1 /* i386/ngen.c - machine code generator for i386
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 Institut f. Computersprachen, TU Wien
5 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6 S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
9 This file is part of CACAO.
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License as
13 published by the Free Software Foundation; either version 2, or (at
14 your option) any later version.
16 This program is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
31 $Id: ngen.c 551 2003-11-01 20:35:28Z twisti $
36 #include "jitdef.h" /* phil */
37 #include "methodtable.c"
39 /* additional functions and macros to generate code ***************************/
41 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
45 #define COUNT_SPILLS count_spills++
51 #define CALCOFFSETBYTES(var, val) \
52 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
53 else if ((s4) (val) != 0) (var) += 1;
56 #define CALCREGOFFBYTES(var, val) \
57 if ((val) > 15) (var) += 4; \
58 else if ((val) != 0) (var) += 1;
61 #define CALCIMMEDIATEBYTES(var, val) \
62 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
66 /* gen_nullptr_check(objreg) */
68 #define gen_nullptr_check(objreg) \
70 i386_test_reg_reg((objreg), (objreg)); \
71 i386_jcc(I386_CC_E, 0); \
72 mcode_addxnullrefs(mcodeptr); \
76 /* MCODECHECK(icnt) */
78 #define MCODECHECK(icnt) \
79 if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) mcode_increase((u1*) mcodeptr)
82 generates an integer-move from register a to b.
83 if a and b are the same int-register, no code will be generated.
86 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
90 generates a floating-point-move from register a to b.
91 if a and b are the same float-register, no code will be generated
94 #define M_FLTMOVE(reg,dreg) panic("M_FLTMOVE");
96 #define M_LNGMEMMOVE(reg,dreg) \
98 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
99 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP2); \
100 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
101 i386_mov_reg_membase(REG_ITMP2, REG_SP, (dreg) * 8 + 4); \
106 this function generates code to fetch data from a pseudo-register
107 into a real register.
108 If the pseudo-register has actually been assigned to a real
109 register, no code will be emitted, since following operations
110 can use this register directly.
112 v: pseudoregister to be fetched from
113 tempregnum: temporary register to be used if v is actually spilled to ram
115 return: the register number, where the operand can be found after
116 fetching (this wil be either tempregnum or the register
117 number allready given to v)
120 #define var_to_reg_int(regnr,v,tempnr) \
121 if ((v)->flags & INMEMORY) { \
123 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
126 regnr = (v)->regoff; \
131 #define var_to_reg_flt(regnr,v,tempnr) \
132 if ((v)->type == TYPE_FLT) { \
133 if ((v)->flags & INMEMORY) { \
135 i386_flds_membase(REG_SP, (v)->regoff * 8); \
139 i386_fld_reg((v)->regoff + fpu_st_offset); \
141 regnr = (v)->regoff; \
144 if ((v)->flags & INMEMORY) { \
146 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
150 i386_fld_reg((v)->regoff + fpu_st_offset); \
152 regnr = (v)->regoff; \
156 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
157 if ((v)->type == TYPE_FLT) { \
158 if ((v)->flags & INMEMORY) { \
160 i386_flds_membase(REG_SP, (v)->regoff * 8); \
164 regnr = (v)->regoff; \
167 if ((v)->flags & INMEMORY) { \
169 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
173 regnr = (v)->regoff; \
179 This function determines a register, to which the result of an operation
180 should go, when it is ultimatively intended to store the result in
182 If v is assigned to an actual register, this register will be returned.
183 Otherwise (when v is spilled) this function returns tempregnum.
184 If not already done, regoff and flags are set in the stack location.
187 static int reg_of_var(stackptr v, int tempregnum)
191 switch (v->varkind) {
193 if (!(v->flags & INMEMORY))
197 var = &(interfaces[v->varnum][v->type]);
198 v->regoff = var->regoff;
199 if (!(var->flags & INMEMORY))
203 var = &(locals[v->varnum][v->type]);
204 v->regoff = var->regoff;
205 if (!(var->flags & INMEMORY))
209 v->regoff = v->varnum;
210 if (IS_FLT_DBL_TYPE(v->type)) {
211 if (v->varnum < fltreg_argnum) {
212 v->regoff = argfltregs[v->varnum];
213 return(argfltregs[v->varnum]);
217 if (v->varnum < intreg_argnum) {
218 v->regoff = argintregs[v->varnum];
219 return(argintregs[v->varnum]);
221 v->regoff -= intreg_argnum;
224 v->flags |= INMEMORY;
229 /* store_reg_to_var_xxx:
230 This function generates the code to store the result of an operation
231 back into a spilled pseudo-variable.
232 If the pseudo-variable has not been spilled in the first place, this
233 function will generate nothing.
235 v ............ Pseudovariable
236 tempregnum ... Number of the temporary registers as returned by
240 #define store_reg_to_var_int(sptr, tempregnum) \
241 if ((sptr)->flags & INMEMORY) { \
243 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
247 #define store_reg_to_var_flt(sptr, tempregnum) \
248 if ((sptr)->type == TYPE_FLT) { \
249 if ((sptr)->flags & INMEMORY) { \
251 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
254 /* i386_fxch_reg((sptr)->regoff);*/ \
255 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
259 if ((sptr)->flags & INMEMORY) { \
261 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
264 /* i386_fxch_reg((sptr)->regoff);*/ \
265 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
271 /* NullPointerException signal handler for hardware null pointer check */
273 void catch_NullPointerException(int sig)
277 /* long faultaddr; */
279 void **_p = (void **) &sig;
280 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
282 /* Reset signal handler - necessary for SysV, does no harm for BSD */
284 instr = *((int*)(sigctx->eip));
285 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
287 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip); */
289 /* if (faultaddr == 0) { */
290 signal(sig, (void *) catch_NullPointerException); /* reinstall handler */
292 sigaddset(&nsig, sig);
293 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
294 sigctx->eax = (long) proto_java_lang_NullPointerException; /* REG_ITMP1_XPTR */
295 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
296 sigctx->eip = (long) asm_handle_exception;
301 /* faultaddr += (long) ((instr << 16) >> 16); */
302 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
303 /* panic("Stack overflow"); */
307 /* ArithmeticException signal handler for hardware divide by zero check */
309 void catch_ArithmeticException(int sig)
313 void **_p = (void **) &sig;
314 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
317 java_objectheader *p;
320 /* Reset signal handler - necessary for SysV, does no harm for BSD */
322 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
324 sigaddset(&nsig, sig);
325 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
327 c = loader_load(utf_new_char("java/lang/ArithmeticException"));
329 m = class_findmethod(c,
330 utf_new_char("<init>"),
331 utf_new_char("(Ljava/lang/String;)V"));
333 asm_calljavamethod(m, p, javastring_new_char("/ by zero"), NULL, NULL);
335 sigctx->eax = (long) p; /* REG_ITMP1_XPTR */
336 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
337 sigctx->eip = (long) asm_handle_exception;
342 void init_exceptions(void)
344 /* install signal handlers we need to convert to exceptions */
349 signal(SIGSEGV, (void *) catch_NullPointerException);
353 signal(SIGBUS, (void *) catch_NullPointerException);
357 signal(SIGFPE, (void *) catch_ArithmeticException);
361 /* function gen_mcode **********************************************************
363 generates machine code
365 *******************************************************************************/
369 static void gen_mcode()
371 int len, s1, s2, s3, d/*, bbs*/;
379 int fpu_st_offset = 0;
388 /* space to save used callee saved registers */
390 savedregs_num += (savintregcnt - maxsavintreguse);
391 savedregs_num += (savfltregcnt - maxsavfltreguse);
393 parentargs_base = maxmemuse + savedregs_num;
395 #ifdef USE_THREADS /* space to save argument of monitor_enter */
397 if (checksync && (method->flags & ACC_SYNCHRONIZED))
402 /* create method header */
404 (void) dseg_addaddress(method); /* MethodPointer */
405 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
409 /* IsSync contains the offset relative to the stack pointer for the
410 argument of monitor_exit used in the exception handler. Since the
411 offset could be zero and give a wrong meaning of the flag it is
415 if (checksync && (method->flags & ACC_SYNCHRONIZED))
416 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
421 (void) dseg_adds4(0); /* IsSync */
423 (void) dseg_adds4(isleafmethod); /* IsLeaf */
424 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
425 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
426 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
428 /* create exception table */
430 for (ex = extable; ex != NULL; ex = ex->down) {
433 if (ex->start != NULL)
434 printf("adding start - %d - ", ex->start->debug_nr);
436 printf("PANIC - start is NULL");
441 dseg_addtarget(ex->start);
445 printf("adding end - %d - ", ex->end->debug_nr);
447 printf("PANIC - end is NULL");
452 dseg_addtarget(ex->end);
455 if (ex->handler != NULL)
456 printf("adding handler - %d\n", ex->handler->debug_nr);
458 printf("PANIC - handler is NULL");
463 dseg_addtarget(ex->handler);
465 (void) dseg_addaddress(ex->catchtype);
468 /* initialize mcode variables */
470 mcodeptr = (u1*) mcodebase;
471 mcodeend = (s4*) (mcodebase + mcodesize);
472 MCODECHECK(128 + mparamcount);
474 /* create stack frame (if necessary) */
476 if (parentargs_base) {
477 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
480 /* save return address and used callee saved registers */
483 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
484 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
486 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
487 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
490 /* save monitorenter argument */
493 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
494 if (method->flags & ACC_STATIC) {
495 i386_mov_imm_reg((s4) class, REG_ITMP1);
496 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
499 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
500 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
505 /* copy argument registers to stack and call trace function with pointer
506 to arguments on stack.
510 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
512 for (p = 0; p < mparamcount; p++) {
514 if (IS_INT_LNG_TYPE(t)) {
515 if (IS_2_WORD_TYPE(t)) {
516 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
517 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
519 } else if (t == TYPE_ADR) {
520 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
521 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
524 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
527 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
528 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
532 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
533 i386_fstps_membase(REG_SP, p * 8);
534 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
535 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
538 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
539 i386_fstpl_membase(REG_SP, p * 8);
544 /* fill up the remaining arguments */
545 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
546 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
547 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
548 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
551 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
553 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
554 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
555 i386_call_reg(REG_ITMP1);
557 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
560 /* take arguments out of register or stack frame */
562 for (p = 0, l = 0; p < mparamcount; p++) {
564 var = &(locals[l][t]);
566 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
571 if (IS_INT_LNG_TYPE(t)) { /* integer args */
572 if (p < intreg_argnum) { /* register arguments */
573 panic("integer register argument");
574 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
575 /* M_INTMOVE (argintregs[p], r); */
577 } else { /* reg arg -> spilled */
578 /* M_LST (argintregs[p], REG_SP, 8 * r); */
580 } else { /* stack arguments */
581 pa = p - intreg_argnum;
582 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
583 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
584 } else { /* stack arg -> spilled */
585 if (!IS_2_WORD_TYPE(t)) {
586 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
587 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
590 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
591 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
592 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
593 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
598 } else { /* floating args */
599 if (p < fltreg_argnum) { /* register arguments */
600 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
601 panic("There are no float argument registers!");
603 } else { /* reg arg -> spilled */
604 panic("There are no float argument registers!");
607 } else { /* stack arguments */
608 pa = p - fltreg_argnum;
609 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
611 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
613 i386_fstp_reg(r + fpu_st_offset);
617 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
619 i386_fstp_reg(r + fpu_st_offset);
623 } else { /* stack-arg -> spilled */
624 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
625 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
627 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
628 i386_fstps_membase(REG_SP, r * 8);
631 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
632 i386_fstpl_membase(REG_SP, r * 8);
639 /* call monitorenter function */
642 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
643 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
644 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
645 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
646 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP2);
647 i386_call_reg(REG_ITMP2);
648 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
653 /* end of header generation */
655 /* walk through all basic blocks */
656 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
658 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
660 if (bptr->flags >= BBREACHED) {
662 /* branch resolving */
665 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
666 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
667 brefs->branchpos, bptr->mpc);
670 /* copy interface registers to their destination */
675 while (src != NULL) {
677 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
678 if (!IS_2_WORD_TYPE(src->type)) {
679 if (bptr->type == BBTYPE_SBR) {
680 d = reg_of_var(src, REG_ITMP1);
682 store_reg_to_var_int(src, d);
684 } else if (bptr->type == BBTYPE_EXH) {
685 d = reg_of_var(src, REG_ITMP1);
686 M_INTMOVE(REG_ITMP1, d);
687 store_reg_to_var_int(src, d);
691 panic("copy interface registers: longs have to me in memory (begin 1)");
695 d = reg_of_var(src, REG_ITMP1);
696 if ((src->varkind != STACKVAR)) {
698 if (IS_FLT_DBL_TYPE(s2)) {
699 s1 = interfaces[len][s2].regoff;
700 if (!(interfaces[len][s2].flags & INMEMORY)) {
704 if (s2 == TYPE_FLT) {
705 i386_flds_membase(REG_SP, s1 * 8);
708 i386_fldl_membase(REG_SP, s1 * 8);
711 store_reg_to_var_flt(src, d);
714 s1 = interfaces[len][s2].regoff;
715 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
716 if (!(interfaces[len][s2].flags & INMEMORY)) {
720 i386_mov_membase_reg(REG_SP, s1 * 8, d);
722 store_reg_to_var_int(src, d);
725 if (interfaces[len][s2].flags & INMEMORY) {
726 M_LNGMEMMOVE(s1, src->regoff);
729 panic("copy interface registers: longs have to be in memory (begin 2)");
738 /* walk through all instructions */
742 for (iptr = bptr->iinstr;
744 src = iptr->dst, len--, iptr++) {
746 MCODECHECK(64); /* an instruction usually needs < 64 words */
749 case ICMD_NOP: /* ... ==> ... */
752 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
753 if (src->flags & INMEMORY) {
754 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
757 i386_test_reg_reg(src->regoff, src->regoff);
759 i386_jcc(I386_CC_E, 0);
760 mcode_addxnullrefs(mcodeptr);
763 /* constant operations ************************************************/
765 case ICMD_ICONST: /* ... ==> ..., constant */
766 /* op1 = 0, val.i = constant */
768 d = reg_of_var(iptr->dst, REG_ITMP1);
769 if (iptr->dst->flags & INMEMORY) {
770 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
773 if (iptr->val.i == 0) {
774 i386_alu_reg_reg(I386_XOR, d, d);
777 i386_mov_imm_reg(iptr->val.i, d);
782 case ICMD_LCONST: /* ... ==> ..., constant */
783 /* op1 = 0, val.l = constant */
785 d = reg_of_var(iptr->dst, REG_ITMP1);
786 if (iptr->dst->flags & INMEMORY) {
787 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
788 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
791 panic("LCONST: longs have to be in memory");
795 case ICMD_FCONST: /* ... ==> ..., constant */
796 /* op1 = 0, val.f = constant */
798 d = reg_of_var(iptr->dst, REG_FTMP1);
799 if (iptr->val.f == 0.0) {
804 if (iptr->val.i == 0x80000000) {
808 } else if (iptr->val.f == 1.0) {
812 } else if (iptr->val.f == 2.0) {
819 a = dseg_addfloat(iptr->val.f);
820 i386_mov_imm_reg(0, REG_ITMP1);
821 dseg_adddata(mcodeptr);
822 i386_flds_membase(REG_ITMP1, a);
825 store_reg_to_var_flt(iptr->dst, d);
828 case ICMD_DCONST: /* ... ==> ..., constant */
829 /* op1 = 0, val.d = constant */
831 d = reg_of_var(iptr->dst, REG_FTMP1);
832 if (iptr->val.d == 0.0) {
837 if (iptr->val.l == 0x8000000000000000LL) {
841 } else if (iptr->val.d == 1.0) {
845 } else if (iptr->val.d == 2.0) {
852 a = dseg_adddouble(iptr->val.d);
853 i386_mov_imm_reg(0, REG_ITMP1);
854 dseg_adddata(mcodeptr);
855 i386_fldl_membase(REG_ITMP1, a);
858 store_reg_to_var_flt(iptr->dst, d);
861 case ICMD_ACONST: /* ... ==> ..., constant */
862 /* op1 = 0, val.a = constant */
864 d = reg_of_var(iptr->dst, REG_ITMP1);
865 if (iptr->dst->flags & INMEMORY) {
866 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
869 if ((s4) iptr->val.a == 0) {
870 i386_alu_reg_reg(I386_XOR, d, d);
873 i386_mov_imm_reg((s4) iptr->val.a, d);
879 /* load/store operations **********************************************/
881 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
882 case ICMD_ALOAD: /* op1 = local variable */
884 d = reg_of_var(iptr->dst, REG_ITMP1);
885 if ((iptr->dst->varkind == LOCALVAR) &&
886 (iptr->dst->varnum == iptr->op1)) {
889 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
890 if (iptr->dst->flags & INMEMORY) {
891 if (var->flags & INMEMORY) {
892 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
893 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
896 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
900 if (var->flags & INMEMORY) {
901 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
904 M_INTMOVE(var->regoff, iptr->dst->regoff);
909 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
910 /* op1 = local variable */
912 d = reg_of_var(iptr->dst, REG_ITMP1);
913 if ((iptr->dst->varkind == LOCALVAR) &&
914 (iptr->dst->varnum == iptr->op1)) {
917 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
918 if (iptr->dst->flags & INMEMORY) {
919 if (var->flags & INMEMORY) {
920 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
923 panic("LLOAD: longs have to be in memory");
927 panic("LLOAD: longs have to be in memory");
931 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
932 /* op1 = local variable */
934 d = reg_of_var(iptr->dst, REG_FTMP1);
935 if ((iptr->dst->varkind == LOCALVAR) &&
936 (iptr->dst->varnum == iptr->op1)) {
939 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
940 if (var->flags & INMEMORY) {
941 i386_flds_membase(REG_SP, var->regoff * 8);
944 i386_fld_reg(var->regoff + fpu_st_offset);
947 store_reg_to_var_flt(iptr->dst, d);
950 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
951 /* op1 = local variable */
953 d = reg_of_var(iptr->dst, REG_FTMP1);
954 if ((iptr->dst->varkind == LOCALVAR) &&
955 (iptr->dst->varnum == iptr->op1)) {
958 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
959 if (var->flags & INMEMORY) {
960 i386_fldl_membase(REG_SP, var->regoff * 8);
963 i386_fld_reg(var->regoff + fpu_st_offset);
966 store_reg_to_var_flt(iptr->dst, d);
969 case ICMD_ISTORE: /* ..., value ==> ... */
970 case ICMD_ASTORE: /* op1 = local variable */
972 if ((src->varkind == LOCALVAR) &&
973 (src->varnum == iptr->op1)) {
976 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
977 if (var->flags & INMEMORY) {
978 if (src->flags & INMEMORY) {
979 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
980 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
983 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
987 var_to_reg_int(s1, src, var->regoff);
988 M_INTMOVE(s1, var->regoff);
992 case ICMD_LSTORE: /* ..., value ==> ... */
993 /* op1 = local variable */
995 if ((src->varkind == LOCALVAR) &&
996 (src->varnum == iptr->op1)) {
999 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1000 if (var->flags & INMEMORY) {
1001 if (src->flags & INMEMORY) {
1002 M_LNGMEMMOVE(src->regoff, var->regoff);
1005 panic("LSTORE: longs have to be in memory");
1009 panic("LSTORE: longs have to be in memory");
1013 case ICMD_FSTORE: /* ..., value ==> ... */
1014 /* op1 = local variable */
1016 if ((src->varkind == LOCALVAR) &&
1017 (src->varnum == iptr->op1)) {
1020 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1021 if (var->flags & INMEMORY) {
1022 var_to_reg_flt(s1, src, REG_FTMP1);
1023 i386_fstps_membase(REG_SP, var->regoff * 8);
1026 var_to_reg_flt(s1, src, var->regoff);
1027 /* M_FLTMOVE(s1, var->regoff); */
1028 i386_fstp_reg(var->regoff + fpu_st_offset);
1033 case ICMD_DSTORE: /* ..., value ==> ... */
1034 /* op1 = local variable */
1036 if ((src->varkind == LOCALVAR) &&
1037 (src->varnum == iptr->op1)) {
1040 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1041 if (var->flags & INMEMORY) {
1042 var_to_reg_flt(s1, src, REG_FTMP1);
1043 i386_fstpl_membase(REG_SP, var->regoff * 8);
1046 var_to_reg_flt(s1, src, var->regoff);
1047 /* M_FLTMOVE(s1, var->regoff); */
1048 i386_fstp_reg(var->regoff + fpu_st_offset);
1054 /* pop/dup/swap operations ********************************************/
1056 /* attention: double and longs are only one entry in CACAO ICMDs */
1058 case ICMD_POP: /* ..., value ==> ... */
1059 case ICMD_POP2: /* ..., value, value ==> ... */
1062 #define M_COPY(from,to) \
1063 d = reg_of_var(to, REG_ITMP1); \
1064 if ((from->regoff != to->regoff) || \
1065 ((from->flags ^ to->flags) & INMEMORY)) { \
1066 if (IS_FLT_DBL_TYPE(from->type)) { \
1067 var_to_reg_flt(s1, from, d); \
1068 /* M_FLTMOVE(s1, d);*/ \
1069 store_reg_to_var_flt(to, d); \
1071 if (!IS_2_WORD_TYPE(from->type)) { \
1072 if (to->flags & INMEMORY) { \
1073 if (from->flags & INMEMORY) { \
1074 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1075 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1077 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1080 if (from->flags & INMEMORY) { \
1081 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1083 i386_mov_reg_reg(from->regoff, to->regoff); \
1087 M_LNGMEMMOVE(from->regoff, to->regoff); \
1092 case ICMD_DUP: /* ..., a ==> ..., a, a */
1093 M_COPY(src, iptr->dst);
1096 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1098 M_COPY(src, iptr->dst->prev->prev);
1100 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1102 M_COPY(src, iptr->dst);
1103 M_COPY(src->prev, iptr->dst->prev);
1106 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1108 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1110 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1112 M_COPY(src, iptr->dst);
1113 M_COPY(src->prev, iptr->dst->prev);
1114 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1115 M_COPY(src, iptr->dst->prev->prev->prev);
1118 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1120 M_COPY(src, iptr->dst);
1121 M_COPY(src->prev, iptr->dst->prev);
1122 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1123 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1124 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1125 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1128 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1130 M_COPY(src, iptr->dst->prev);
1131 M_COPY(src->prev, iptr->dst);
1135 /* integer operations *************************************************/
1137 case ICMD_INEG: /* ..., value ==> ..., - value */
1139 d = reg_of_var(iptr->dst, REG_NULL);
1140 if (iptr->dst->flags & INMEMORY) {
1141 if (src->flags & INMEMORY) {
1142 if (src->regoff == iptr->dst->regoff) {
1143 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1146 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1147 i386_neg_reg(REG_ITMP1);
1148 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1152 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1153 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1157 if (src->flags & INMEMORY) {
1158 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1159 i386_neg_reg(iptr->dst->regoff);
1162 M_INTMOVE(src->regoff, iptr->dst->regoff);
1163 i386_neg_reg(iptr->dst->regoff);
1168 case ICMD_LNEG: /* ..., value ==> ..., - value */
1170 d = reg_of_var(iptr->dst, REG_NULL);
1171 if (iptr->dst->flags & INMEMORY) {
1172 if (src->flags & INMEMORY) {
1173 if (src->regoff == iptr->dst->regoff) {
1174 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1175 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1176 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1179 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1180 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1181 i386_neg_reg(REG_ITMP1);
1182 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1183 i386_neg_reg(REG_ITMP2);
1184 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1185 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1191 case ICMD_I2L: /* ..., value ==> ..., value */
1193 d = reg_of_var(iptr->dst, REG_NULL);
1194 if (iptr->dst->flags & INMEMORY) {
1195 if (src->flags & INMEMORY) {
1196 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX);
1198 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1199 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1202 M_INTMOVE(src->regoff, I386_EAX);
1204 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1205 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1210 case ICMD_L2I: /* ..., value ==> ..., value */
1212 d = reg_of_var(iptr->dst, REG_NULL);
1213 if (iptr->dst->flags & INMEMORY) {
1214 if (src->flags & INMEMORY) {
1215 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1216 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1220 if (src->flags & INMEMORY) {
1221 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1226 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1228 d = reg_of_var(iptr->dst, REG_NULL);
1229 if (iptr->dst->flags & INMEMORY) {
1230 if (src->flags & INMEMORY) {
1231 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1232 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1233 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1234 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1237 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1238 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1239 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1243 if (src->flags & INMEMORY) {
1244 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1245 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1246 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1249 M_INTMOVE(src->regoff, iptr->dst->regoff);
1250 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1251 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1256 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1258 d = reg_of_var(iptr->dst, REG_NULL);
1259 if (iptr->dst->flags & INMEMORY) {
1260 if (src->flags & INMEMORY) {
1261 if (src->regoff == iptr->dst->regoff) {
1262 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1265 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1266 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1267 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1271 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1272 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1276 if (src->flags & INMEMORY) {
1277 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1278 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1281 M_INTMOVE(src->regoff, iptr->dst->regoff);
1282 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1287 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1289 d = reg_of_var(iptr->dst, REG_NULL);
1290 if (iptr->dst->flags & INMEMORY) {
1291 if (src->flags & INMEMORY) {
1292 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1293 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1294 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1295 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1298 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1299 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1300 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1304 if (src->flags & INMEMORY) {
1305 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1306 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1307 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1310 M_INTMOVE(src->regoff, iptr->dst->regoff);
1311 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1312 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1318 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1320 d = reg_of_var(iptr->dst, REG_NULL);
1321 i386_emit_ialu(I386_ADD, src, iptr);
1324 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1325 /* val.i = constant */
1327 d = reg_of_var(iptr->dst, REG_NULL);
1328 /* should we use a inc optimization for smaller code size? */
1329 i386_emit_ialuconst(I386_ADD, src, iptr);
1332 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1334 d = reg_of_var(iptr->dst, REG_NULL);
1335 if (iptr->dst->flags & INMEMORY) {
1336 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1337 if (src->regoff == iptr->dst->regoff) {
1338 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1339 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1340 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1341 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1343 } else if (src->prev->regoff == iptr->dst->regoff) {
1344 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1345 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1346 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1347 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1350 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1351 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1352 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1353 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1354 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1355 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1362 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1363 /* val.l = constant */
1365 d = reg_of_var(iptr->dst, REG_NULL);
1366 if (iptr->dst->flags & INMEMORY) {
1367 if (src->flags & INMEMORY) {
1368 if (src->regoff == iptr->dst->regoff) {
1369 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1370 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1373 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1374 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1375 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1376 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP2);
1377 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1378 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1384 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1386 d = reg_of_var(iptr->dst, REG_NULL);
1387 if (iptr->dst->flags & INMEMORY) {
1388 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1389 if (src->prev->regoff == iptr->dst->regoff) {
1390 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1391 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1394 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1395 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1396 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1399 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1400 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1401 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1402 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1404 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1405 if (src->prev->regoff == iptr->dst->regoff) {
1406 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1409 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1410 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1411 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1415 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1416 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1420 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1421 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1422 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1424 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1425 M_INTMOVE(src->prev->regoff, d);
1426 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1428 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1429 /* workaround for reg alloc */
1430 if (src->regoff == iptr->dst->regoff) {
1431 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1432 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1433 M_INTMOVE(REG_ITMP1, d);
1436 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1437 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1441 /* workaround for reg alloc */
1442 if (src->regoff == iptr->dst->regoff) {
1443 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1444 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1445 M_INTMOVE(REG_ITMP1, d);
1448 M_INTMOVE(src->prev->regoff, d);
1449 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1455 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1456 /* val.i = constant */
1458 d = reg_of_var(iptr->dst, REG_NULL);
1459 i386_emit_ialuconst(I386_SUB, src, iptr);
1462 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1464 d = reg_of_var(iptr->dst, REG_NULL);
1465 if (iptr->dst->flags & INMEMORY) {
1466 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1467 if (src->prev->regoff == iptr->dst->regoff) {
1468 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1469 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1470 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1471 i386_alu_reg_membase(I386_SBB, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1474 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1475 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1476 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1477 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1478 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1479 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1485 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1486 /* val.l = constant */
1488 d = reg_of_var(iptr->dst, REG_NULL);
1489 if (iptr->dst->flags & INMEMORY) {
1490 if (src->flags & INMEMORY) {
1491 if (src->regoff == iptr->dst->regoff) {
1492 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1493 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1496 /* TODO: could be size optimized with lea -- see gcc output */
1497 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1498 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1499 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1500 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP2);
1501 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1502 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1508 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1510 d = reg_of_var(iptr->dst, REG_NULL);
1511 if (iptr->dst->flags & INMEMORY) {
1512 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1513 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1514 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1515 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1517 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1518 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1519 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1520 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1522 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1523 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1524 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1525 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1528 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1529 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1530 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1534 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1535 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1536 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1538 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1539 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1540 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1542 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1543 M_INTMOVE(src->regoff, iptr->dst->regoff);
1544 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1547 if (src->regoff == iptr->dst->regoff) {
1548 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1551 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1552 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1558 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1559 /* val.i = constant */
1561 d = reg_of_var(iptr->dst, REG_NULL);
1562 if (iptr->dst->flags & INMEMORY) {
1563 if (src->flags & INMEMORY) {
1564 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1565 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1568 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1569 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1573 if (src->flags & INMEMORY) {
1574 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1577 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1582 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1584 d = reg_of_var(iptr->dst, REG_NULL);
1585 if (iptr->dst->flags & INMEMORY) {
1586 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1587 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX); /* mem -> EAX */
1588 /* optimize move EAX -> REG_ITMP3 is slower??? */
1589 /* i386_mov_reg_reg(I386_EAX, REG_ITMP3); */
1590 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1592 /* TODO: optimize move EAX -> REG_ITMP3 */
1593 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem -> ITMP3 */
1594 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1595 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1597 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1598 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1600 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1601 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1602 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1607 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1608 /* val.l = constant */
1610 d = reg_of_var(iptr->dst, REG_NULL);
1611 if (iptr->dst->flags & INMEMORY) {
1612 if (src->flags & INMEMORY) {
1613 i386_mov_imm_reg(iptr->val.l, I386_EAX); /* imm -> EAX */
1614 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1615 /* TODO: optimize move EAX -> REG_ITMP3 */
1616 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP3); /* imm -> ITMP3 */
1617 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1619 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1620 i386_mov_imm_reg(iptr->val.l, REG_ITMP3); /* imm -> ITMP3 */
1621 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1623 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1624 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1625 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1630 #define gen_div_check(v) \
1632 if ((v)->flags & INMEMORY) { \
1633 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1635 i386_test_reg_reg(src->regoff, src->regoff); \
1637 i386_jcc(I386_CC_E, 0); \
1638 mcode_addxdivrefs(mcodeptr); \
1641 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1643 d = reg_of_var(iptr->dst, REG_NULL);
1644 var_to_reg_int(s1, src, REG_ITMP3);
1646 if (src->prev->flags & INMEMORY) {
1647 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1650 M_INTMOVE(src->prev->regoff, I386_EAX);
1653 i386_alu_imm_reg(I386_CMP, 0x80000000, I386_EAX); /* check as described in jvm spec */
1654 i386_jcc(I386_CC_NE, 3 + 6);
1655 i386_alu_imm_reg(I386_CMP, -1, s1);
1656 i386_jcc(I386_CC_E, 1 + 2);
1661 if (iptr->dst->flags & INMEMORY) {
1662 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1665 M_INTMOVE(I386_EAX, iptr->dst->regoff);
1669 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1671 d = reg_of_var(iptr->dst, REG_NULL);
1672 var_to_reg_int(s1, src, REG_ITMP3);
1674 if (src->prev->flags & INMEMORY) {
1675 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1678 M_INTMOVE(src->prev->regoff, I386_EAX);
1681 i386_alu_imm_reg(I386_CMP, 0x80000000, I386_EAX); /* check as described in jvm spec */
1682 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1683 i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EDX);
1684 i386_alu_imm_reg(I386_CMP, -1, s1);
1685 i386_jcc(I386_CC_E, 1 + 2);
1690 if (iptr->dst->flags & INMEMORY) {
1691 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8);
1694 M_INTMOVE(I386_EDX, iptr->dst->regoff);
1698 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1699 /* val.i = constant */
1701 /* TODO: optimize for `/ 2' */
1702 var_to_reg_int(s1, src, REG_ITMP1);
1703 d = reg_of_var(iptr->dst, REG_ITMP1);
1706 i386_test_reg_reg(d, d);
1708 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1709 i386_jcc(I386_CC_NS, a);
1710 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1712 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1713 store_reg_to_var_int(iptr->dst, d);
1716 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1717 /* val.i = constant */
1719 d = reg_of_var(iptr->dst, REG_NULL);
1720 if (iptr->dst->flags & INMEMORY) {
1721 if (src->flags & INMEMORY) {
1723 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1725 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1726 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1728 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1729 i386_jcc(I386_CC_NS, a);
1730 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1731 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1732 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1733 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1735 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1736 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1741 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1742 /* val.i = constant */
1744 var_to_reg_int(s1, src, REG_ITMP1);
1745 d = reg_of_var(iptr->dst, REG_ITMP2);
1747 M_INTMOVE(s1, REG_ITMP1);
1754 CALCIMMEDIATEBYTES(a, iptr->val.i);
1757 /* TODO: optimize */
1759 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1760 i386_test_reg_reg(s1, s1);
1761 i386_jcc(I386_CC_GE, a);
1762 i386_mov_reg_reg(s1, d);
1764 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1767 /* M_INTMOVE(s1, I386_EAX); */
1769 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
1770 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
1771 /* i386_alu_reg_reg(I386_AND, iptr->val.i, I386_EAX); */
1772 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
1773 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
1774 /* M_INTMOVE(I386_EAX, d); */
1776 /* i386_alu_reg_reg(I386_XOR, d, d); */
1777 /* i386_mov_imm_reg(iptr->val.i, I386_ECX); */
1778 /* i386_shrd_reg_reg(s1, d); */
1779 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1781 store_reg_to_var_int(iptr->dst, d);
1784 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1785 /* val.l = constant */
1787 d = reg_of_var(iptr->dst, REG_NULL);
1788 if (iptr->dst->flags & INMEMORY) {
1789 if (src->flags & INMEMORY) {
1790 /* Intel algorithm -- does not work, because constant is wrong */
1791 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1792 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1794 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1795 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1796 /* i386_jcc(I386_CC_NS, offset); */
1797 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1798 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1800 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1801 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1802 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1804 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1806 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1807 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1808 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1810 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1811 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1813 /* Alpha algorithm */
1815 CALCOFFSETBYTES(a, src->regoff * 8);
1817 CALCOFFSETBYTES(a, src->regoff * 8 + 4);
1823 /* TODO: hmm, don't know if this is always correct */
1825 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1827 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1833 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1834 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1836 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1837 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1838 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1839 i386_jcc(I386_CC_GE, a);
1841 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1842 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1844 i386_neg_reg(REG_ITMP1);
1845 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1846 i386_neg_reg(REG_ITMP2);
1848 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1849 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1851 i386_neg_reg(REG_ITMP1);
1852 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1853 i386_neg_reg(REG_ITMP2);
1855 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1856 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1861 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1863 d = reg_of_var(iptr->dst, REG_NULL);
1864 i386_emit_ishift(I386_SHL, src, iptr);
1867 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1868 /* val.i = constant */
1870 d = reg_of_var(iptr->dst, REG_NULL);
1871 i386_emit_ishiftconst(I386_SHL, src, iptr);
1874 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1876 d = reg_of_var(iptr->dst, REG_NULL);
1877 i386_emit_ishift(I386_SAR, src, iptr);
1880 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1881 /* val.i = constant */
1883 d = reg_of_var(iptr->dst, REG_NULL);
1884 i386_emit_ishiftconst(I386_SAR, src, iptr);
1887 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1889 d = reg_of_var(iptr->dst, REG_NULL);
1890 i386_emit_ishift(I386_SHR, src, iptr);
1893 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1894 /* val.i = constant */
1896 d = reg_of_var(iptr->dst, REG_NULL);
1897 i386_emit_ishiftconst(I386_SHR, src, iptr);
1900 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1902 d = reg_of_var(iptr->dst, REG_NULL);
1903 if (iptr->dst->flags & INMEMORY ){
1904 if (src->prev->flags & INMEMORY) {
1905 /* if (src->prev->regoff == iptr->dst->regoff) { */
1906 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1908 /* if (src->flags & INMEMORY) { */
1909 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
1911 /* M_INTMOVE(src->regoff, I386_ECX); */
1914 /* i386_test_imm_reg(32, I386_ECX); */
1915 /* i386_jcc(I386_CC_E, 2 + 2); */
1916 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1917 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1919 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1920 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1923 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1924 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1926 if (src->flags & INMEMORY) {
1927 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1929 M_INTMOVE(src->regoff, I386_ECX);
1932 i386_test_imm_reg(32, I386_ECX);
1933 i386_jcc(I386_CC_E, 2 + 2);
1934 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
1935 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1937 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
1938 i386_shift_reg(I386_SHL, REG_ITMP1);
1939 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1940 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1946 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1947 /* val.i = constant */
1949 d = reg_of_var(iptr->dst, REG_NULL);
1950 if (iptr->dst->flags & INMEMORY ) {
1951 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1952 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1954 if (iptr->val.i & 0x20) {
1955 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
1956 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1957 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1960 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1961 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
1964 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1965 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1969 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1971 d = reg_of_var(iptr->dst, REG_NULL);
1972 if (iptr->dst->flags & INMEMORY ){
1973 if (src->prev->flags & INMEMORY) {
1974 /* if (src->prev->regoff == iptr->dst->regoff) { */
1975 /* TODO: optimize */
1976 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1977 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1979 /* if (src->flags & INMEMORY) { */
1980 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
1982 /* M_INTMOVE(src->regoff, I386_ECX); */
1985 /* i386_test_imm_reg(32, I386_ECX); */
1986 /* i386_jcc(I386_CC_E, 2 + 3); */
1987 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
1988 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
1990 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
1991 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
1992 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1993 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1996 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1997 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1999 if (src->flags & INMEMORY) {
2000 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2002 M_INTMOVE(src->regoff, I386_ECX);
2005 i386_test_imm_reg(32, I386_ECX);
2006 i386_jcc(I386_CC_E, 2 + 3);
2007 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2008 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2010 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2011 i386_shift_reg(I386_SAR, REG_ITMP2);
2012 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2013 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2019 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2020 /* val.i = constant */
2022 d = reg_of_var(iptr->dst, REG_NULL);
2023 if (iptr->dst->flags & INMEMORY ) {
2024 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2025 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2027 if (iptr->val.i & 0x20) {
2028 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2029 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2030 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2033 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2034 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2037 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2038 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2042 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2044 d = reg_of_var(iptr->dst, REG_NULL);
2045 if (iptr->dst->flags & INMEMORY ){
2046 if (src->prev->flags & INMEMORY) {
2047 /* if (src->prev->regoff == iptr->dst->regoff) { */
2048 /* TODO: optimize */
2049 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2050 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2052 /* if (src->flags & INMEMORY) { */
2053 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2055 /* M_INTMOVE(src->regoff, I386_ECX); */
2058 /* i386_test_imm_reg(32, I386_ECX); */
2059 /* i386_jcc(I386_CC_E, 2 + 2); */
2060 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2061 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2063 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2064 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2065 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2066 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2069 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2070 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2072 if (src->flags & INMEMORY) {
2073 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2075 M_INTMOVE(src->regoff, I386_ECX);
2078 i386_test_imm_reg(32, I386_ECX);
2079 i386_jcc(I386_CC_E, 2 + 2);
2080 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2081 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2083 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2084 i386_shift_reg(I386_SHR, REG_ITMP2);
2085 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2086 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2092 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2093 /* val.l = constant */
2095 d = reg_of_var(iptr->dst, REG_NULL);
2096 if (iptr->dst->flags & INMEMORY ) {
2097 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2098 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2100 if (iptr->val.i & 0x20) {
2101 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2102 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2103 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2106 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2107 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2110 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2111 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2115 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2117 d = reg_of_var(iptr->dst, REG_NULL);
2118 i386_emit_ialu(I386_AND, src, iptr);
2121 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2122 /* val.i = constant */
2124 d = reg_of_var(iptr->dst, REG_NULL);
2125 i386_emit_ialuconst(I386_AND, src, iptr);
2128 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2130 d = reg_of_var(iptr->dst, REG_NULL);
2131 i386_emit_lalu(I386_AND, src, iptr);
2134 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2135 /* val.l = constant */
2137 d = reg_of_var(iptr->dst, REG_NULL);
2138 i386_emit_laluconst(I386_AND, src, iptr);
2141 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2143 d = reg_of_var(iptr->dst, REG_NULL);
2144 i386_emit_ialu(I386_OR, src, iptr);
2147 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2148 /* val.i = constant */
2150 d = reg_of_var(iptr->dst, REG_NULL);
2151 i386_emit_ialuconst(I386_OR, src, iptr);
2154 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2156 d = reg_of_var(iptr->dst, REG_NULL);
2157 i386_emit_lalu(I386_OR, src, iptr);
2160 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2161 /* val.l = constant */
2163 d = reg_of_var(iptr->dst, REG_NULL);
2164 i386_emit_laluconst(I386_OR, src, iptr);
2167 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2169 d = reg_of_var(iptr->dst, REG_NULL);
2170 i386_emit_ialu(I386_XOR, src, iptr);
2173 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2174 /* val.i = constant */
2176 d = reg_of_var(iptr->dst, REG_NULL);
2177 i386_emit_ialuconst(I386_XOR, src, iptr);
2180 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2182 d = reg_of_var(iptr->dst, REG_NULL);
2183 i386_emit_lalu(I386_XOR, src, iptr);
2186 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2187 /* val.l = constant */
2189 d = reg_of_var(iptr->dst, REG_NULL);
2190 i386_emit_laluconst(I386_XOR, src, iptr);
2193 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2194 /* op1 = variable, val.i = constant */
2196 var = &(locals[iptr->op1][TYPE_INT]);
2197 if (var->flags & INMEMORY) {
2198 if (iptr->val.i == 1) {
2199 i386_inc_membase(REG_SP, var->regoff * 8);
2201 } else if (iptr->val.i == -1) {
2202 i386_dec_membase(REG_SP, var->regoff * 8);
2205 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2209 if (iptr->val.i == 1) {
2210 i386_inc_reg(var->regoff);
2212 } else if (iptr->val.i == -1) {
2213 i386_dec_reg(var->regoff);
2216 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2222 /* floating operations ************************************************/
2224 #define ROUND_TO_SINGLE \
2225 i386_fstps_membase(REG_SP, -8); \
2226 i386_flds_membase(REG_SP, -8);
2228 #define ROUND_TO_DOUBLE \
2229 i386_fstpl_membase(REG_SP, -8); \
2230 i386_fldl_membase(REG_SP, -8);
2232 #define FPU_SET_24BIT_MODE \
2233 if (!fpu_in_24bit_mode) { \
2234 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2235 fpu_in_24bit_mode = 1; \
2238 #define FPU_SET_53BIT_MODE \
2239 if (fpu_in_24bit_mode) { \
2240 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2241 fpu_in_24bit_mode = 0; \
2244 #define ROUND_TO_SINGLE
2245 #define ROUND_TO_DOUBLE
2246 #define FPU_SET_24BIT_MODE
2247 #define FPU_SET_53BIT_MODE
2249 case ICMD_FNEG: /* ..., value ==> ..., - value */
2252 var_to_reg_flt(s1, src, REG_FTMP1);
2253 d = reg_of_var(iptr->dst, REG_FTMP3);
2255 store_reg_to_var_flt(iptr->dst, d);
2258 case ICMD_DNEG: /* ..., value ==> ..., - value */
2261 var_to_reg_flt(s1, src, REG_FTMP1);
2262 d = reg_of_var(iptr->dst, REG_FTMP3);
2264 store_reg_to_var_flt(iptr->dst, d);
2267 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2270 d = reg_of_var(iptr->dst, REG_FTMP3);
2271 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2272 var_to_reg_flt(s2, src, REG_FTMP2);
2275 store_reg_to_var_flt(iptr->dst, d);
2278 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2281 d = reg_of_var(iptr->dst, REG_FTMP3);
2282 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2283 var_to_reg_flt(s2, src, REG_FTMP2);
2286 store_reg_to_var_flt(iptr->dst, d);
2289 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2292 d = reg_of_var(iptr->dst, REG_FTMP3);
2293 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2294 var_to_reg_flt(s2, src, REG_FTMP2);
2297 store_reg_to_var_flt(iptr->dst, d);
2300 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2303 d = reg_of_var(iptr->dst, REG_FTMP3);
2304 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2305 var_to_reg_flt(s2, src, REG_FTMP2);
2308 store_reg_to_var_flt(iptr->dst, d);
2311 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2314 d = reg_of_var(iptr->dst, REG_FTMP3);
2315 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2316 var_to_reg_flt(s2, src, REG_FTMP2);
2320 store_reg_to_var_flt(iptr->dst, d);
2323 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2326 d = reg_of_var(iptr->dst, REG_FTMP3);
2327 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2329 /* i386_fldt_mem(subnormal_bias1); */
2332 var_to_reg_flt(s2, src, REG_FTMP2);
2337 /* i386_fldt_mem(subnormal_bias2); */
2340 store_reg_to_var_flt(iptr->dst, d);
2343 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2346 d = reg_of_var(iptr->dst, REG_FTMP3);
2347 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2348 var_to_reg_flt(s2, src, REG_FTMP2);
2352 store_reg_to_var_flt(iptr->dst, d);
2355 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2358 d = reg_of_var(iptr->dst, REG_FTMP3);
2359 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2361 /* i386_fldt_mem(subnormal_bias1); */
2364 var_to_reg_flt(s2, src, REG_FTMP2);
2369 /* i386_fldt_mem(subnormal_bias2); */
2372 store_reg_to_var_flt(iptr->dst, d);
2375 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2378 /* exchanged to skip fxch */
2379 var_to_reg_flt(s2, src, REG_FTMP2);
2380 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2381 d = reg_of_var(iptr->dst, REG_FTMP3);
2387 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2388 store_reg_to_var_flt(iptr->dst, d);
2394 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2397 /* exchanged to skip fxch */
2398 var_to_reg_flt(s2, src, REG_FTMP2);
2399 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2400 d = reg_of_var(iptr->dst, REG_FTMP3);
2406 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2407 store_reg_to_var_flt(iptr->dst, d);
2413 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2414 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2416 d = reg_of_var(iptr->dst, REG_FTMP1);
2417 if (src->flags & INMEMORY) {
2418 i386_fildl_membase(REG_SP, src->regoff * 8);
2423 i386_mov_imm_reg(0, REG_ITMP1);
2424 dseg_adddata(mcodeptr);
2425 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2426 i386_fildl_membase(REG_ITMP1, a);
2429 store_reg_to_var_flt(iptr->dst, d);
2432 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2433 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2435 d = reg_of_var(iptr->dst, REG_FTMP1);
2436 if (src->flags & INMEMORY) {
2437 i386_fildll_membase(REG_SP, src->regoff * 8);
2441 panic("L2F: longs have to be in memory");
2443 store_reg_to_var_flt(iptr->dst, d);
2446 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2448 var_to_reg_flt(s1, src, REG_FTMP1);
2449 d = reg_of_var(iptr->dst, REG_ITMP1);
2451 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2452 i386_mov_imm_reg(0, REG_ITMP1);
2453 dseg_adddata(mcodeptr);
2454 i386_fldcw_membase(REG_ITMP1, a);
2456 if (iptr->dst->flags & INMEMORY) {
2457 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2460 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2461 i386_fldcw_membase(REG_ITMP1, a);
2463 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2466 CALCOFFSETBYTES(a, src->regoff * 8);
2468 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2472 i386_fistpl_membase(REG_ITMP1, a);
2474 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2476 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2477 i386_fldcw_membase(REG_ITMP1, a);
2479 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2482 CALCOFFSETBYTES(a, src->regoff * 8);
2483 a += 5 + 2 + ((REG_RESULT == d) ? 0 : 2);
2486 i386_jcc(I386_CC_NE, a);
2488 /* XXX: change this when we use registers */
2489 i386_flds_membase(REG_SP, src->regoff * 8);
2490 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP2);
2491 i386_call_reg(REG_ITMP2);
2493 if (iptr->dst->flags & INMEMORY) {
2494 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2497 M_INTMOVE(REG_RESULT, d);
2501 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2503 var_to_reg_flt(s1, src, REG_FTMP1);
2504 d = reg_of_var(iptr->dst, REG_ITMP1);
2506 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2507 i386_mov_imm_reg(0, REG_ITMP1);
2508 dseg_adddata(mcodeptr);
2509 i386_fldcw_membase(REG_ITMP1, a);
2511 if (iptr->dst->flags & INMEMORY) {
2512 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2515 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2516 i386_fldcw_membase(REG_ITMP1, a);
2518 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2521 CALCOFFSETBYTES(a, src->regoff * 8);
2523 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2527 i386_fistpl_membase(REG_ITMP1, a);
2529 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2531 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2532 i386_fldcw_membase(REG_ITMP1, a);
2534 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2537 CALCOFFSETBYTES(a, src->regoff * 8);
2538 a += 5 + 2 + ((REG_RESULT == d) ? 0 : 2);
2541 i386_jcc(I386_CC_NE, a);
2543 /* XXX: change this when we use registers */
2544 i386_fldl_membase(REG_SP, src->regoff * 8);
2545 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP2);
2546 i386_call_reg(REG_ITMP2);
2548 if (iptr->dst->flags & INMEMORY) {
2549 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2551 M_INTMOVE(REG_RESULT, d);
2555 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2557 var_to_reg_flt(s1, src, REG_FTMP1);
2558 d = reg_of_var(iptr->dst, REG_ITMP1);
2560 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2561 i386_mov_imm_reg(0, REG_ITMP1);
2562 dseg_adddata(mcodeptr);
2563 i386_fldcw_membase(REG_ITMP1, a);
2565 if (iptr->dst->flags & INMEMORY) {
2566 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2569 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2570 i386_fldcw_membase(REG_ITMP1, a);
2572 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2575 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2577 CALCOFFSETBYTES(a, src->regoff * 8);
2580 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2582 CALCOFFSETBYTES(a, iptr->dst->regoff * 8 + 4);
2584 i386_jcc(I386_CC_NE, a);
2586 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2589 CALCOFFSETBYTES(a, src->regoff * 8);
2591 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2593 i386_jcc(I386_CC_NE, a);
2595 /* XXX: change this when we use registers */
2596 i386_flds_membase(REG_SP, src->regoff * 8);
2597 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP2);
2598 i386_call_reg(REG_ITMP2);
2599 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2600 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2603 panic("F2L: longs have to be in memory");
2607 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2609 var_to_reg_flt(s1, src, REG_FTMP1);
2610 d = reg_of_var(iptr->dst, REG_ITMP1);
2612 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2613 i386_mov_imm_reg(0, REG_ITMP1);
2614 dseg_adddata(mcodeptr);
2615 i386_fldcw_membase(REG_ITMP1, a);
2617 if (iptr->dst->flags & INMEMORY) {
2618 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2621 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2622 i386_fldcw_membase(REG_ITMP1, a);
2624 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2627 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2629 CALCOFFSETBYTES(a, src->regoff * 8);
2632 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2634 CALCOFFSETBYTES(a, iptr->dst->regoff * 8 + 4);
2636 i386_jcc(I386_CC_NE, a);
2638 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2641 CALCOFFSETBYTES(a, src->regoff * 8);
2643 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2645 i386_jcc(I386_CC_NE, a);
2647 /* XXX: change this when we use registers */
2648 i386_fldl_membase(REG_SP, src->regoff * 8);
2649 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP2);
2650 i386_call_reg(REG_ITMP2);
2651 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2652 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2655 panic("D2L: longs have to be in memory");
2659 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2661 var_to_reg_flt(s1, src, REG_FTMP1);
2662 d = reg_of_var(iptr->dst, REG_FTMP3);
2664 store_reg_to_var_flt(iptr->dst, d);
2667 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2669 var_to_reg_flt(s1, src, REG_FTMP1);
2670 d = reg_of_var(iptr->dst, REG_FTMP3);
2672 store_reg_to_var_flt(iptr->dst, d);
2675 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2678 /* exchanged to skip fxch */
2679 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2680 var_to_reg_flt(s1, src, REG_FTMP2);
2681 d = reg_of_var(iptr->dst, REG_ITMP2);
2682 i386_alu_reg_reg(I386_XOR, d, d);
2687 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as GT */
2688 i386_jcc(I386_CC_E, 6);
2689 i386_alu_imm_reg(I386_AND, 0x000000ff, I386_EAX);
2691 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2692 i386_jcc(I386_CC_B, 1 + 5);
2696 store_reg_to_var_int(iptr->dst, d);
2699 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2702 /* exchanged to skip fxch */
2703 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2704 var_to_reg_flt(s1, src, REG_FTMP2);
2705 d = reg_of_var(iptr->dst, REG_ITMP2);
2706 i386_alu_reg_reg(I386_XOR, d, d);
2711 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as LT */
2712 i386_jcc(I386_CC_E, 3);
2713 i386_movb_imm_reg(1, I386_AH);
2715 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2716 i386_jcc(I386_CC_B, 1 + 5);
2720 store_reg_to_var_int(iptr->dst, d);
2724 /* memory operations **************************************************/
2726 #define gen_bound_check \
2727 if (checkbounds) { \
2728 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2729 i386_jcc(I386_CC_AE, 0); \
2730 mcode_addxboundrefs(mcodeptr); \
2733 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2735 var_to_reg_int(s1, src, REG_ITMP1);
2736 d = reg_of_var(iptr->dst, REG_ITMP2);
2737 gen_nullptr_check(s1);
2738 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2739 store_reg_to_var_int(iptr->dst, d);
2742 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2744 var_to_reg_int(s1, src->prev, REG_ITMP1);
2745 var_to_reg_int(s2, src, REG_ITMP2);
2746 d = reg_of_var(iptr->dst, REG_ITMP1);
2747 if (iptr->op1 == 0) {
2748 gen_nullptr_check(s1);
2751 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2752 store_reg_to_var_int(iptr->dst, d);
2755 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2757 var_to_reg_int(s1, src->prev, REG_ITMP1);
2758 var_to_reg_int(s2, src, REG_ITMP2);
2759 d = reg_of_var(iptr->dst, REG_ITMP3);
2760 if (iptr->op1 == 0) {
2761 gen_nullptr_check(s1);
2765 if (iptr->dst->flags & INMEMORY) {
2766 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2767 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2768 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2769 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2773 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2775 var_to_reg_int(s1, src->prev, REG_ITMP1);
2776 var_to_reg_int(s2, src, REG_ITMP2);
2777 d = reg_of_var(iptr->dst, REG_ITMP1);
2778 if (iptr->op1 == 0) {
2779 gen_nullptr_check(s1);
2782 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2783 store_reg_to_var_int(iptr->dst, d);
2786 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2788 var_to_reg_int(s1, src->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src, REG_ITMP2);
2790 d = reg_of_var(iptr->dst, REG_FTMP1);
2791 if (iptr->op1 == 0) {
2792 gen_nullptr_check(s1);
2795 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2797 store_reg_to_var_flt(iptr->dst, d);
2800 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2802 var_to_reg_int(s1, src->prev, REG_ITMP1);
2803 var_to_reg_int(s2, src, REG_ITMP2);
2804 d = reg_of_var(iptr->dst, REG_FTMP3);
2805 if (iptr->op1 == 0) {
2806 gen_nullptr_check(s1);
2809 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2811 store_reg_to_var_flt(iptr->dst, d);
2814 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2816 var_to_reg_int(s1, src->prev, REG_ITMP1);
2817 var_to_reg_int(s2, src, REG_ITMP2);
2818 d = reg_of_var(iptr->dst, REG_ITMP1);
2819 if (iptr->op1 == 0) {
2820 gen_nullptr_check(s1);
2823 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2824 store_reg_to_var_int(iptr->dst, d);
2827 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2829 var_to_reg_int(s1, src->prev, REG_ITMP1);
2830 var_to_reg_int(s2, src, REG_ITMP2);
2831 d = reg_of_var(iptr->dst, REG_ITMP1);
2832 if (iptr->op1 == 0) {
2833 gen_nullptr_check(s1);
2836 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2837 store_reg_to_var_int(iptr->dst, d);
2840 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2842 var_to_reg_int(s1, src->prev, REG_ITMP1);
2843 var_to_reg_int(s2, src, REG_ITMP2);
2844 d = reg_of_var(iptr->dst, REG_ITMP1);
2845 if (iptr->op1 == 0) {
2846 gen_nullptr_check(s1);
2849 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2850 store_reg_to_var_int(iptr->dst, d);
2854 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2856 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2857 var_to_reg_int(s2, src->prev, REG_ITMP2);
2858 if (iptr->op1 == 0) {
2859 gen_nullptr_check(s1);
2862 var_to_reg_int(s3, src, REG_ITMP3);
2863 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2866 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2868 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2869 var_to_reg_int(s2, src->prev, REG_ITMP2);
2870 if (iptr->op1 == 0) {
2871 gen_nullptr_check(s1);
2875 if (src->flags & INMEMORY) {
2876 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2877 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2878 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2879 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2883 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2885 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2886 var_to_reg_int(s2, src->prev, REG_ITMP2);
2887 if (iptr->op1 == 0) {
2888 gen_nullptr_check(s1);
2891 var_to_reg_int(s3, src, REG_ITMP3);
2892 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2895 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2897 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2898 var_to_reg_int(s2, src->prev, REG_ITMP2);
2899 if (iptr->op1 == 0) {
2900 gen_nullptr_check(s1);
2903 var_to_reg_flt(s3, src, REG_FTMP1);
2904 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2908 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2910 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2911 var_to_reg_int(s2, src->prev, REG_ITMP2);
2912 if (iptr->op1 == 0) {
2913 gen_nullptr_check(s1);
2916 var_to_reg_flt(s3, src, REG_FTMP1);
2917 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2921 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2923 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2924 var_to_reg_int(s2, src->prev, REG_ITMP2);
2925 if (iptr->op1 == 0) {
2926 gen_nullptr_check(s1);
2929 var_to_reg_int(s3, src, REG_ITMP3);
2930 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2933 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2935 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2936 var_to_reg_int(s2, src->prev, REG_ITMP2);
2937 if (iptr->op1 == 0) {
2938 gen_nullptr_check(s1);
2941 var_to_reg_int(s3, src, REG_ITMP3);
2942 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2945 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2947 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2948 var_to_reg_int(s2, src->prev, REG_ITMP2);
2949 if (iptr->op1 == 0) {
2950 gen_nullptr_check(s1);
2953 var_to_reg_int(s3, src, REG_ITMP3);
2954 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
2955 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2959 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2960 /* op1 = type, val.a = field address */
2962 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2963 /* here it's slightly slower */
2964 i386_mov_imm_reg(0, REG_ITMP2);
2965 dseg_adddata(mcodeptr);
2966 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
2967 switch (iptr->op1) {
2970 var_to_reg_int(s2, src, REG_ITMP1);
2971 i386_mov_reg_membase(s2, REG_ITMP2, 0);
2974 if (src->flags & INMEMORY) {
2975 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2976 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
2977 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
2978 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
2980 panic("PUTSTATIC: longs have to be in memory");
2984 var_to_reg_flt(s2, src, REG_FTMP1);
2985 i386_fstps_membase(REG_ITMP2, 0);
2989 var_to_reg_flt(s2, src, REG_FTMP1);
2990 i386_fstpl_membase(REG_ITMP2, 0);
2993 default: panic ("internal error");
2997 case ICMD_GETSTATIC: /* ... ==> ..., value */
2998 /* op1 = type, val.a = field address */
3000 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3001 i386_mov_imm_reg(0, REG_ITMP2);
3002 dseg_adddata(mcodeptr);
3003 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3004 switch (iptr->op1) {
3007 d = reg_of_var(iptr->dst, REG_ITMP1);
3008 i386_mov_membase_reg(REG_ITMP2, 0, d);
3009 store_reg_to_var_int(iptr->dst, d);
3012 d = reg_of_var(iptr->dst, REG_NULL);
3013 if (iptr->dst->flags & INMEMORY) {
3014 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3015 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3016 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3017 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3019 panic("GETSTATIC: longs have to be in memory");
3023 d = reg_of_var(iptr->dst, REG_FTMP1);
3024 i386_flds_membase(REG_ITMP2, 0);
3026 store_reg_to_var_flt(iptr->dst, d);
3029 d = reg_of_var(iptr->dst, REG_FTMP1);
3030 i386_fldl_membase(REG_ITMP2, 0);
3032 store_reg_to_var_flt(iptr->dst, d);
3034 default: panic ("internal error");
3038 case ICMD_PUTFIELD: /* ..., value ==> ... */
3039 /* op1 = type, val.i = field offset */
3041 a = ((fieldinfo *)(iptr->val.a))->offset;
3042 switch (iptr->op1) {
3045 var_to_reg_int(s1, src->prev, REG_ITMP1);
3046 var_to_reg_int(s2, src, REG_ITMP2);
3047 gen_nullptr_check(s1);
3048 i386_mov_reg_membase(s2, s1, a);
3051 var_to_reg_int(s1, src->prev, REG_ITMP1);
3052 gen_nullptr_check(s1);
3053 if (src->flags & INMEMORY) {
3054 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3055 i386_mov_reg_membase(REG_ITMP2, s1, a);
3056 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3057 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3059 panic("PUTFIELD: longs have to be in memory");
3063 var_to_reg_int(s1, src->prev, REG_ITMP1);
3064 var_to_reg_flt(s2, src, REG_FTMP1);
3065 gen_nullptr_check(s1);
3066 i386_fstps_membase(s1, a);
3070 var_to_reg_int(s1, src->prev, REG_ITMP1);
3071 var_to_reg_flt(s2, src, REG_FTMP1);
3072 gen_nullptr_check(s1);
3073 i386_fstpl_membase(s1, a);
3076 default: panic ("internal error");
3080 case ICMD_GETFIELD: /* ... ==> ..., value */
3081 /* op1 = type, val.i = field offset */
3083 a = ((fieldinfo *)(iptr->val.a))->offset;
3084 switch (iptr->op1) {
3087 var_to_reg_int(s1, src, REG_ITMP1);
3088 d = reg_of_var(iptr->dst, REG_ITMP2);
3089 gen_nullptr_check(s1);
3090 i386_mov_membase_reg(s1, a, d);
3091 store_reg_to_var_int(iptr->dst, d);
3094 var_to_reg_int(s1, src, REG_ITMP1);
3095 d = reg_of_var(iptr->dst, REG_NULL);
3096 gen_nullptr_check(s1);
3097 i386_mov_membase_reg(s1, a, REG_ITMP2);
3098 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3099 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3100 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3103 var_to_reg_int(s1, src, REG_ITMP1);
3104 d = reg_of_var(iptr->dst, REG_FTMP1);
3105 gen_nullptr_check(s1);
3106 i386_flds_membase(s1, a);
3108 store_reg_to_var_flt(iptr->dst, d);
3111 var_to_reg_int(s1, src, REG_ITMP1);
3112 d = reg_of_var(iptr->dst, REG_FTMP1);
3113 gen_nullptr_check(s1);
3114 i386_fldl_membase(s1, a);
3116 store_reg_to_var_flt(iptr->dst, d);
3118 default: panic ("internal error");
3123 /* branch operations **************************************************/
3126 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3127 #define ALIGNCODENOP do {} while (0)
3129 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3131 var_to_reg_int(s1, src, REG_ITMP1);
3132 M_INTMOVE(s1, REG_ITMP1_XPTR);
3134 i386_call_imm(0); /* passing exception pointer */
3135 i386_pop_reg(REG_ITMP2_XPC);
3137 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
3138 i386_jmp_reg(I386_EDI);
3142 case ICMD_GOTO: /* ... ==> ... */
3143 /* op1 = target JavaVM pc */
3146 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3150 case ICMD_JSR: /* ... ==> ... */
3151 /* op1 = target JavaVM pc */
3154 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3157 case ICMD_RET: /* ... ==> ... */
3158 /* op1 = local variable */
3160 var = &(locals[iptr->op1][TYPE_ADR]);
3161 var_to_reg_int(s1, var, REG_ITMP1);
3165 case ICMD_IFNULL: /* ..., value ==> ... */
3166 /* op1 = target JavaVM pc */
3168 if (src->flags & INMEMORY) {
3169 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3172 i386_test_reg_reg(src->regoff, src->regoff);
3174 i386_jcc(I386_CC_E, 0);
3175 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3178 case ICMD_IFNONNULL: /* ..., value ==> ... */
3179 /* op1 = target JavaVM pc */
3181 if (src->flags & INMEMORY) {
3182 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3185 i386_test_reg_reg(src->regoff, src->regoff);
3187 i386_jcc(I386_CC_NE, 0);
3188 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3191 case ICMD_IFEQ: /* ..., value ==> ... */
3192 /* op1 = target JavaVM pc, val.i = constant */
3194 if (src->flags & INMEMORY) {
3195 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3198 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3200 i386_jcc(I386_CC_E, 0);
3201 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3204 case ICMD_IFLT: /* ..., value ==> ... */
3205 /* op1 = target JavaVM pc, val.i = constant */
3207 if (src->flags & INMEMORY) {
3208 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3211 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3213 i386_jcc(I386_CC_L, 0);
3214 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3217 case ICMD_IFLE: /* ..., value ==> ... */
3218 /* op1 = target JavaVM pc, val.i = constant */
3220 if (src->flags & INMEMORY) {
3221 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3224 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3226 i386_jcc(I386_CC_LE, 0);
3227 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3230 case ICMD_IFNE: /* ..., value ==> ... */
3231 /* op1 = target JavaVM pc, val.i = constant */
3233 if (src->flags & INMEMORY) {
3234 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3237 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3239 i386_jcc(I386_CC_NE, 0);
3240 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3243 case ICMD_IFGT: /* ..., value ==> ... */
3244 /* op1 = target JavaVM pc, val.i = constant */
3246 if (src->flags & INMEMORY) {
3247 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3250 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3252 i386_jcc(I386_CC_G, 0);
3253 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3256 case ICMD_IFGE: /* ..., value ==> ... */
3257 /* op1 = target JavaVM pc, val.i = constant */
3259 if (src->flags & INMEMORY) {
3260 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3263 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3265 i386_jcc(I386_CC_GE, 0);
3266 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3269 case ICMD_IF_LEQ: /* ..., value ==> ... */
3270 /* op1 = target JavaVM pc, val.l = constant */
3272 if (src->flags & INMEMORY) {
3273 if (iptr->val.l == 0) {
3274 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3275 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3277 } else if (iptr->val.l > 0 && iptr->val.l <= 0x00000000ffffffff) {
3278 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3279 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3280 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3283 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3284 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3285 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3286 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3287 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3290 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3291 i386_jcc(I386_CC_E, 0);
3292 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3295 case ICMD_IF_LLT: /* ..., value ==> ... */
3296 /* op1 = target JavaVM pc, val.l = constant */
3298 /* TODO: optimize as in IF_LEQ */
3299 if (src->flags & INMEMORY) {
3300 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3301 i386_jcc(I386_CC_L, 0);
3302 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3305 CALCREGOFFBYTES(a, src->regoff);
3306 CALCIMMEDIATEBYTES(a, iptr->val.l);
3308 i386_jcc(I386_CC_G, a);
3310 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3311 i386_jcc(I386_CC_B, 0);
3312 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3316 case ICMD_IF_LLE: /* ..., value ==> ... */
3317 /* op1 = target JavaVM pc, val.l = constant */
3319 /* TODO: optimize as in IF_LEQ */
3320 if (src->flags & INMEMORY) {
3321 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3322 i386_jcc(I386_CC_L, 0);
3323 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3326 CALCREGOFFBYTES(a, src->regoff);
3327 CALCIMMEDIATEBYTES(a, iptr->val.l);
3329 i386_jcc(I386_CC_G, a);
3331 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3332 i386_jcc(I386_CC_BE, 0);
3333 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3337 case ICMD_IF_LNE: /* ..., value ==> ... */
3338 /* op1 = target JavaVM pc, val.l = constant */
3340 /* TODO: optimize for val.l == 0 */
3341 if (src->flags & INMEMORY) {
3342 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3343 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3344 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3345 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3346 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3347 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3349 i386_jcc(I386_CC_NE, 0);
3350 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3353 case ICMD_IF_LGT: /* ..., value ==> ... */
3354 /* op1 = target JavaVM pc, val.l = constant */
3356 /* TODO: optimize as in IF_LEQ */
3357 if (src->flags & INMEMORY) {
3358 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3359 i386_jcc(I386_CC_G, 0);
3360 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3363 CALCREGOFFBYTES(a, src->regoff);
3364 CALCIMMEDIATEBYTES(a, iptr->val.l);
3366 i386_jcc(I386_CC_L, a);
3368 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3369 i386_jcc(I386_CC_A, 0);
3370 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3374 case ICMD_IF_LGE: /* ..., value ==> ... */
3375 /* op1 = target JavaVM pc, val.l = constant */
3377 /* TODO: optimize as in IF_LEQ */
3378 if (src->flags & INMEMORY) {
3379 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3380 i386_jcc(I386_CC_G, 0);
3381 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3384 CALCREGOFFBYTES(a, src->regoff);
3385 CALCIMMEDIATEBYTES(a, iptr->val.l);
3387 i386_jcc(I386_CC_L, a);
3389 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3390 i386_jcc(I386_CC_AE, 0);
3391 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3395 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3396 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3398 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3399 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3400 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3402 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3403 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3405 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3406 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3409 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3411 i386_jcc(I386_CC_E, 0);
3412 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3415 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3416 /* op1 = target JavaVM pc */
3418 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3419 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3420 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3421 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3422 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3423 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3424 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3426 i386_jcc(I386_CC_E, 0);
3427 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3430 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3431 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3433 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3434 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3435 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3437 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3438 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3440 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3441 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3444 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3446 i386_jcc(I386_CC_NE, 0);
3447 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3450 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3451 /* op1 = target JavaVM pc */
3453 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3454 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3455 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3456 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3457 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3458 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3459 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3461 i386_jcc(I386_CC_NE, 0);
3462 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3465 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3466 /* op1 = target JavaVM pc */
3468 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3469 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3470 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3472 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3473 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3475 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3476 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3479 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3481 i386_jcc(I386_CC_L, 0);
3482 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3485 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3486 /* op1 = target JavaVM pc */
3488 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3489 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3490 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3491 i386_jcc(I386_CC_L, 0);
3492 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3495 CALCREGOFFBYTES(a, src->prev->regoff);
3496 CALCREGOFFBYTES(a, src->regoff);
3498 i386_jcc(I386_CC_G, a);
3500 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3501 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3502 i386_jcc(I386_CC_B, 0);
3503 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3507 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3508 /* op1 = target JavaVM pc */
3510 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3511 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3512 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3514 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3515 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3517 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3518 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3521 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3523 i386_jcc(I386_CC_G, 0);
3524 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3527 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3528 /* op1 = target JavaVM pc */
3530 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3531 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3532 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3533 i386_jcc(I386_CC_G, 0);
3534 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3537 CALCREGOFFBYTES(a, src->prev->regoff);
3538 CALCREGOFFBYTES(a, src->regoff);
3540 i386_jcc(I386_CC_L, a);
3542 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3543 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3544 i386_jcc(I386_CC_A, 0);
3545 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3549 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3550 /* op1 = target JavaVM pc */
3552 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3553 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3554 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3556 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3557 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3559 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3560 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3563 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3565 i386_jcc(I386_CC_LE, 0);
3566 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3569 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3570 /* op1 = target JavaVM pc */
3572 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3573 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3574 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3575 i386_jcc(I386_CC_L, 0);
3576 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3579 CALCREGOFFBYTES(a, src->prev->regoff);
3580 CALCREGOFFBYTES(a, src->regoff);
3582 i386_jcc(I386_CC_G, a);
3584 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3585 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3586 i386_jcc(I386_CC_BE, 0);
3587 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3591 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3592 /* op1 = target JavaVM pc */
3594 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3595 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3596 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3598 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3599 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3601 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3602 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3605 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3607 i386_jcc(I386_CC_GE, 0);
3608 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3611 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3612 /* op1 = target JavaVM pc */
3614 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3615 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3616 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3617 i386_jcc(I386_CC_G, 0);
3618 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3621 CALCREGOFFBYTES(a, src->prev->regoff);
3622 CALCREGOFFBYTES(a, src->regoff);
3624 i386_jcc(I386_CC_L, a);
3626 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3627 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3628 i386_jcc(I386_CC_AE, 0);
3629 mcode_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3633 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3635 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3638 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3639 /* val.i = constant */
3641 d = reg_of_var(iptr->dst, REG_NULL);
3642 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3645 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3646 /* val.i = constant */
3648 d = reg_of_var(iptr->dst, REG_NULL);
3649 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3652 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3653 /* val.i = constant */
3655 d = reg_of_var(iptr->dst, REG_NULL);
3656 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3659 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3660 /* val.i = constant */
3662 d = reg_of_var(iptr->dst, REG_NULL);
3663 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3666 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3667 /* val.i = constant */
3669 d = reg_of_var(iptr->dst, REG_NULL);
3670 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3673 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3674 /* val.i = constant */
3676 d = reg_of_var(iptr->dst, REG_NULL);
3677 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3681 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3685 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3686 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3687 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3688 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3689 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3690 i386_call_reg(REG_ITMP1);
3691 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3694 var_to_reg_int(s1, src, REG_RESULT);
3695 M_INTMOVE(s1, REG_RESULT);
3696 goto nowperformreturn;
3698 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3701 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3702 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3703 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3704 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3705 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3706 i386_call_reg(REG_ITMP1);
3707 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3710 if (src->flags & INMEMORY) {
3711 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3712 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3715 panic("LRETURN: longs have to be in memory");
3717 goto nowperformreturn;
3719 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3722 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3723 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3724 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3725 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3726 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3727 i386_call_reg(REG_ITMP1);
3728 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3731 var_to_reg_flt(s1, src, REG_FRESULT);
3732 /* this may be an early return -- keep the offset correct for the remaining code */
3734 goto nowperformreturn;
3736 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3739 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3740 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3741 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3742 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3743 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3744 i386_call_reg(REG_ITMP1);
3745 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3748 var_to_reg_flt(s1, src, REG_FRESULT);
3749 /* this may be an early return -- keep the offset correct for the remaining code */
3751 goto nowperformreturn;
3753 case ICMD_RETURN: /* ... ==> ... */
3756 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3757 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3758 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3759 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3760 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3761 i386_call_reg(REG_ITMP1);
3762 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3770 p = parentargs_base;
3772 /* restore saved registers */
3773 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3775 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3777 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3779 i386_fldl_membase(REG_SP, p * 8);
3781 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3782 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3784 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3789 /* deallocate stack */
3790 if (parentargs_base) {
3791 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3794 /* call trace function */
3796 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3798 i386_mov_imm_membase((s4) method, REG_SP, 0);
3800 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3801 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3803 i386_fstl_membase(REG_SP, 4 + 8);
3804 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3806 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3807 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3808 i386_call_reg(REG_ITMP1);
3810 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3811 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3813 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3822 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3827 tptr = (void **) iptr->target;
3829 s4ptr = iptr->val.a;
3830 l = s4ptr[1]; /* low */
3831 i = s4ptr[2]; /* high */
3833 var_to_reg_int(s1, src, REG_ITMP1);
3834 M_INTMOVE(s1, REG_ITMP1);
3836 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3842 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3843 i386_jcc(I386_CC_A, 0);
3845 /* mcode_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3846 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3848 /* build jump table top down and use address of lowest entry */
3850 /* s4ptr += 3 + i; */
3854 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3855 dseg_addtarget((basicblock *) tptr[0]);
3859 /* length of dataseg after last dseg_addtarget is used by load */
3861 i386_mov_imm_reg(0, REG_ITMP2);
3862 dseg_adddata(mcodeptr);
3863 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3864 i386_jmp_reg(REG_ITMP1);
3870 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3872 s4 i, l, val, *s4ptr;
3875 tptr = (void **) iptr->target;
3877 s4ptr = iptr->val.a;
3878 l = s4ptr[0]; /* default */
3879 i = s4ptr[1]; /* count */
3881 MCODECHECK((i<<2)+8);
3882 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3888 i386_alu_imm_reg(I386_CMP, val, s1);
3889 i386_jcc(I386_CC_E, 0);
3890 /* mcode_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3891 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3895 /* mcode_addreference(BlockPtrOfPC(l), mcodeptr); */
3897 tptr = (void **) iptr->target;
3898 mcode_addreference((basicblock *) tptr[0], mcodeptr);
3905 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3906 /* op1 = return type, val.a = function pointer*/
3910 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3911 /* op1 = return type, val.a = function pointer*/
3915 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3916 /* op1 = return type, val.a = function pointer*/
3920 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3921 /* op1 = arg count, val.a = method pointer */
3923 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3924 /* op1 = arg count, val.a = method pointer */
3926 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3927 /* op1 = arg count, val.a = method pointer */
3929 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3930 /* op1 = arg count, val.a = method pointer */
3938 MCODECHECK((s3 << 1) + 64);
3940 /* copy arguments to registers or stack location */
3942 for (; --s3 >= 0; src = src->prev) {
3943 if (src->varkind == ARGVAR) {
3947 if (IS_INT_LNG_TYPE(src->type)) {
3948 if (s3 < intreg_argnum) {
3949 panic("No integer argument registers available!");
3952 if (!IS_2_WORD_TYPE(src->type)) {
3953 if (src->flags & INMEMORY) {
3954 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3955 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
3958 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
3962 if (src->flags & INMEMORY) {
3963 M_LNGMEMMOVE(src->regoff, s3);
3966 panic("copy arguments: longs have to be in memory");
3972 if (s3 < fltreg_argnum) {
3973 panic("No float argument registers available!");
3976 var_to_reg_flt(d, src, REG_FTMP1);
3977 if (src->type == TYPE_FLT) {
3978 i386_fstps_membase(REG_SP, s3 * 8);
3981 i386_fstpl_membase(REG_SP, s3 * 8);
3988 switch (iptr->opc) {
3996 i386_mov_imm_reg(a, REG_ITMP1);
3997 i386_call_reg(REG_ITMP1);
4000 case ICMD_INVOKESTATIC:
4002 a = (s4) m->stubroutine;
4005 i386_mov_imm_reg(a, REG_ITMP2);
4006 i386_call_reg(REG_ITMP2);
4009 case ICMD_INVOKESPECIAL:
4011 a = (s4) m->stubroutine;
4014 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4015 gen_nullptr_check(REG_ITMP1);
4016 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4018 i386_mov_imm_reg(a, REG_ITMP2);
4019 i386_call_reg(REG_ITMP2);
4022 case ICMD_INVOKEVIRTUAL:
4026 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4027 gen_nullptr_check(REG_ITMP1);
4028 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4029 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4031 i386_call_reg(REG_ITMP1);
4034 case ICMD_INVOKEINTERFACE:
4039 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4040 gen_nullptr_check(REG_ITMP1);
4041 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4042 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4043 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4045 i386_call_reg(REG_ITMP1);
4050 sprintf(logtext, "Unkown ICMD-Command: %d", iptr->opc);
4054 /* d contains return type */
4056 if (d != TYPE_VOID) {
4057 d = reg_of_var(iptr->dst, REG_NULL);
4059 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4060 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4061 if (iptr->dst->flags & INMEMORY) {
4062 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4063 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4066 panic("RETURN: longs have to be in memory");
4070 if (iptr->dst->flags & INMEMORY) {
4071 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4074 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4079 /* fld from called function -- has other fpu_st_offset counter */
4081 store_reg_to_var_flt(iptr->dst, d);
4088 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4090 /* op1: 0 == array, 1 == class */
4091 /* val.a: (classinfo*) superclass */
4093 /* superclass is an interface:
4095 * return (sub != NULL) &&
4096 * (sub->vftbl->interfacetablelength > super->index) &&
4097 * (sub->vftbl->interfacetable[-super->index] != NULL);
4099 * superclass is a class:
4101 * return ((sub != NULL) && (0
4102 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4103 * super->vftbl->diffvall));
4107 classinfo *super = (classinfo*) iptr->val.a;
4109 var_to_reg_int(s1, src, REG_ITMP1);
4110 d = reg_of_var(iptr->dst, REG_ITMP3);
4112 M_INTMOVE(s1, REG_ITMP1);
4115 i386_alu_reg_reg(I386_XOR, d, d);
4116 if (iptr->op1) { /* class/interface */
4117 if (super->flags & ACC_INTERFACE) { /* interface */
4118 i386_test_reg_reg(s1, s1);
4120 /* TODO: clean up this calculation */
4122 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4125 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4128 CALCOFFSETBYTES(a, super->index);
4134 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4141 i386_jcc(I386_CC_E, a);
4143 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4144 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4145 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4147 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4149 /* TODO: clean up this calculation */
4152 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4159 i386_jcc(I386_CC_LE, a);
4160 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4162 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4163 /* i386_setcc_reg(I386_CC_A, d); */
4164 /* i386_jcc(I386_CC_BE, 5); */
4165 i386_jcc(I386_CC_E, 5);
4166 i386_mov_imm_reg(1, d);
4169 } else { /* class */
4170 i386_test_reg_reg(s1, s1);
4172 /* TODO: clean up this calculation */
4174 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4177 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4179 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4182 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4192 i386_jcc(I386_CC_E, a);
4194 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4195 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4196 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4197 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4198 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4199 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4200 i386_alu_reg_reg(I386_XOR, d, d);
4201 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4202 i386_jcc(I386_CC_A, 5);
4203 i386_mov_imm_reg(1, d);
4207 panic ("internal error: no inlined array instanceof");
4209 store_reg_to_var_int(iptr->dst, d);
4212 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4214 /* op1: 0 == array, 1 == class */
4215 /* val.a: (classinfo*) superclass */
4217 /* superclass is an interface:
4219 * OK if ((sub == NULL) ||
4220 * (sub->vftbl->interfacetablelength > super->index) &&
4221 * (sub->vftbl->interfacetable[-super->index] != NULL));
4223 * superclass is a class:
4225 * OK if ((sub == NULL) || (0
4226 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4227 * super->vftbl->diffvall));
4231 classinfo *super = (classinfo*) iptr->val.a;
4233 d = reg_of_var(iptr->dst, REG_ITMP3);
4234 var_to_reg_int(s1, src, d);
4235 if (iptr->op1) { /* class/interface */
4236 if (super->flags & ACC_INTERFACE) { /* interface */
4237 i386_test_reg_reg(s1, s1);
4239 /* TODO: clean up this calculation */
4241 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4244 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4247 CALCOFFSETBYTES(a, super->index);
4253 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4258 i386_jcc(I386_CC_E, a);
4260 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4261 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4262 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4264 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4265 i386_jcc(I386_CC_LE, 0);
4266 mcode_addxcastrefs(mcodeptr);
4267 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4269 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4270 i386_jcc(I386_CC_E, 0);
4271 mcode_addxcastrefs(mcodeptr);
4273 } else { /* class */
4274 i386_test_reg_reg(s1, s1);
4276 /* TODO: clean up this calculation */
4278 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4283 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4285 if (d != REG_ITMP3) {
4287 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4290 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4296 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4303 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4310 i386_jcc(I386_CC_E, a);
4312 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4313 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4314 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4315 if (d != REG_ITMP3) {
4316 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4317 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4318 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4321 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4322 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4323 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4324 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4326 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4327 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4328 mcode_addxcastrefs(mcodeptr);
4332 panic ("internal error: no inlined array checkcast");
4335 store_reg_to_var_int(iptr->dst, d);
4338 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4340 if (src->flags & INMEMORY) {
4341 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4344 i386_test_reg_reg(src->regoff, src->regoff);
4346 i386_jcc(I386_CC_L, 0);
4347 mcode_addxcheckarefs(mcodeptr);
4350 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4351 /* op1 = dimension, val.a = array descriptor */
4353 /* check for negative sizes and copy sizes to stack if necessary */
4355 MCODECHECK((iptr->op1 << 1) + 64);
4357 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4358 if (src->flags & INMEMORY) {
4359 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4362 i386_test_reg_reg(src->regoff, src->regoff);
4364 i386_jcc(I386_CC_L, 0);
4365 mcode_addxcheckarefs(mcodeptr);
4368 * copy sizes to new stack location, be cause native function
4369 * builtin_nmultianewarray access them as (int *)
4371 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4372 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4374 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4376 if (src->varkind != ARGVAR) {
4377 if (src->flags & INMEMORY) {
4378 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4379 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4382 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4386 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4388 /* a0 = dimension count */
4390 /* save stack pointer */
4391 M_INTMOVE(REG_SP, REG_ITMP1);
4393 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4394 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4396 /* a1 = arraydescriptor */
4398 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4400 /* a2 = pointer to dimensions = stack pointer */
4402 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4404 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4405 i386_call_reg(REG_ITMP1);
4406 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4408 s1 = reg_of_var(iptr->dst, REG_RESULT);
4409 M_INTMOVE(REG_RESULT, s1);
4410 store_reg_to_var_int(iptr->dst, s1);
4414 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
4421 } /* for instruction */
4423 /* copy values to interface registers */
4425 src = bptr->outstack;
4426 len = bptr->outdepth;
4430 if ((src->varkind != STACKVAR)) {
4432 if (IS_FLT_DBL_TYPE(s2)) {
4433 var_to_reg_flt(s1, src, REG_FTMP1);
4434 if (!(interfaces[len][s2].flags & INMEMORY)) {
4435 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4438 panic("double store");
4439 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4443 var_to_reg_int(s1, src, REG_ITMP1);
4444 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4445 if (!(interfaces[len][s2].flags & INMEMORY)) {
4446 M_INTMOVE(s1, interfaces[len][s2].regoff);
4449 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4453 if (interfaces[len][s2].flags & INMEMORY) {
4454 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4457 panic("copy interface registers: longs have to be in memory (end)");
4464 } /* if (bptr -> flags >= BBREACHED) */
4465 } /* for basic block */
4467 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4471 /* generate bound check stubs */
4472 u1 *xcodeptr = NULL;
4474 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4475 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4476 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4477 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4482 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4483 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4487 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4488 dseg_adddata(mcodeptr);
4489 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4490 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4492 if (xcodeptr != NULL) {
4493 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4496 xcodeptr = mcodeptr;
4498 i386_mov_imm_reg((s4) proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
4499 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4500 i386_jmp_reg(I386_EDI);
4504 /* generate negative array size check stubs */
4507 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4508 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4509 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4510 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4514 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4515 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4519 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4520 dseg_adddata(mcodeptr);
4521 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4522 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4524 if (xcodeptr != NULL) {
4525 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4528 xcodeptr = mcodeptr;
4530 i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
4531 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4532 i386_jmp_reg(I386_EDI);
4536 /* generate cast check stubs */
4539 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4540 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4541 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4542 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4546 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4547 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4551 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4552 dseg_adddata(mcodeptr);
4553 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4554 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4556 if (xcodeptr != NULL) {
4557 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4560 xcodeptr = mcodeptr;
4562 i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
4563 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4564 i386_jmp_reg(I386_EDI);
4568 /* generate divide by zero check stubs */
4571 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4572 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4573 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4574 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4578 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4579 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4583 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4584 dseg_adddata(mcodeptr);
4585 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4586 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4588 if (xcodeptr != NULL) {
4589 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4592 xcodeptr = mcodeptr;
4594 i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
4595 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4596 i386_jmp_reg(I386_EDI);
4600 /* generate null pointer check stubs */
4603 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4604 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4605 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4606 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4610 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4611 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4615 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4616 dseg_adddata(mcodeptr);
4617 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4618 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4620 if (xcodeptr != NULL) {
4621 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4624 xcodeptr = mcodeptr;
4626 i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
4627 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4628 i386_jmp_reg(I386_EDI);
4633 mcode_finish((int)((u1*) mcodeptr - mcodebase));
4637 /* function createcompilerstub *************************************************
4639 creates a stub routine which calls the compiler
4641 *******************************************************************************/
4643 #define COMPSTUBSIZE 12
4645 u1 *createcompilerstub(methodinfo *m)
4647 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4648 mcodeptr = s; /* code generation pointer */
4650 /* code for the stub */
4651 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4653 /* we use EDI cause EDX (REG_ITMP2) is used for patching */
4654 i386_mov_imm_reg((s4) asm_call_jit_compiler, I386_EDI); /* load address */
4655 i386_jmp_reg(I386_EDI); /* jump to compiler */
4658 count_cstub_len += COMPSTUBSIZE;
4665 /* function removecompilerstub *************************************************
4667 deletes a compilerstub from memory (simply by freeing it)
4669 *******************************************************************************/
4671 void removecompilerstub(u1 *stub)
4673 CFREE(stub, COMPSTUBSIZE);
4676 /* function: createnativestub **************************************************
4678 creates a stub routine which calls a native method
4680 *******************************************************************************/
4682 #define NATIVESTUBSIZE 320
4684 u1 *createnativestub(functionptr f, methodinfo *m)
4686 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4690 int stackframesize = 4; /* initial 4 bytes is space for jni env */
4691 int stackframeoffset = 4;
4695 mcodeptr = s; /* make macros work */
4699 descriptor2types(m); /* set paramcount and paramtypes */
4702 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4704 for (p = 0; p < m->paramcount; p++) {
4705 t = m->paramtypes[p];
4706 if (IS_INT_LNG_TYPE(t)) {
4707 if (IS_2_WORD_TYPE(t)) {
4708 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4709 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4711 } else if (t == TYPE_ADR) {
4712 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4713 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4716 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4719 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4720 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4723 if (t == TYPE_FLT) {
4724 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4725 i386_fstps_membase(REG_SP, p * 8);
4726 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4727 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4730 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4731 i386_fstpl_membase(REG_SP, p * 8);
4737 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4738 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4739 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4740 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4743 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4745 i386_mov_imm_reg((s4) asm_builtin_trace, REG_ITMP1);
4746 i386_call_reg(REG_ITMP1);
4748 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4752 * mark the whole fpu stack as free for native functions
4753 * (only for saved register count == 0)
4765 * calculate stackframe size for native function
4767 tptr = m->paramtypes;
4768 for (i = 0; i < m->paramcount; i++) {
4773 stackframesize += 4;
4778 stackframesize += 8;
4782 panic("unknown parameter type in native function");
4786 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4788 tptr = m->paramtypes;
4789 for (i = 0; i < m->paramcount; i++) {
4794 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4795 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4796 stackframeoffset += 4;
4801 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4802 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
4803 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4804 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
4805 stackframeoffset += 8;
4809 panic("unknown parameter type in native function");
4813 i386_mov_imm_membase((s4) &env, REG_SP, 0);
4814 i386_mov_imm_reg((s4) f, REG_ITMP1);
4815 i386_call_reg(REG_ITMP1);
4816 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
4819 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4821 i386_mov_imm_membase((s4) m, REG_SP, 0);
4823 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4824 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4826 i386_fstl_membase(REG_SP, 4 + 8);
4827 i386_fsts_membase(REG_SP, 4 + 8 + 8);
4829 i386_mov_imm_reg((s4) asm_builtin_exittrace, REG_ITMP1);
4830 i386_call_reg(REG_ITMP1);
4832 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4833 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4835 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4838 /* we can use EDI cause it's not preserved across function calls */
4839 i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4840 i386_mov_membase_reg(I386_EDI, 0, I386_EDI);
4841 i386_test_reg_reg(I386_EDI, I386_EDI);
4842 i386_jcc(I386_CC_NE, 1);
4846 i386_mov_reg_reg(I386_EDI, REG_ITMP1_XPTR);
4847 i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4848 i386_mov_imm_membase(0, I386_EDI, 0);
4849 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
4850 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
4852 i386_mov_imm_reg((s4) asm_handle_nat_exception, I386_EDI);
4853 i386_jmp_reg(I386_EDI);
4856 count_nstub_len += NATIVESTUBSIZE;
4862 /* function: removenativestub **************************************************
4864 removes a previously created native-stub from memory
4866 *******************************************************************************/
4868 void removenativestub(u1 *stub)
4870 CFREE(stub, NATIVESTUBSIZE);
4875 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
4877 if (iptr->dst->flags & INMEMORY) {
4878 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4879 if (src->regoff == iptr->dst->regoff) {
4880 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4881 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4883 } else if (src->prev->regoff == iptr->dst->regoff) {
4884 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4885 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4888 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4889 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
4890 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4893 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4894 if (src->regoff == iptr->dst->regoff) {
4895 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4898 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4899 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
4900 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4903 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4904 if (src->prev->regoff == iptr->dst->regoff) {
4905 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4908 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4909 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
4910 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4914 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4915 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4919 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4920 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4921 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4923 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4924 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4925 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4927 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4928 M_INTMOVE(src->regoff, iptr->dst->regoff);
4929 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4932 if (src->regoff == iptr->dst->regoff) {
4933 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
4936 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4937 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
4945 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
4947 if (iptr->dst->flags & INMEMORY) {
4948 if (src->flags & INMEMORY) {
4949 if (src->regoff == iptr->dst->regoff) {
4950 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4953 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4954 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
4955 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4959 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
4960 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4964 if (src->flags & INMEMORY) {
4965 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
4966 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
4969 M_INTMOVE(src->regoff, iptr->dst->regoff);
4970 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
4977 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
4979 if (iptr->dst->flags & INMEMORY) {
4980 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4981 if (src->regoff == iptr->dst->regoff) {
4982 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4983 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
4984 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4985 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
4987 } else if (src->prev->regoff == iptr->dst->regoff) {
4988 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4989 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
4990 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4991 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
4994 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4995 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
4996 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
4997 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
4998 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4999 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5007 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5009 if (iptr->dst->flags & INMEMORY) {
5010 if (src->flags & INMEMORY) {
5011 if (src->regoff == iptr->dst->regoff) {
5012 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5013 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5016 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5017 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5018 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5019 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP2);
5020 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5021 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5029 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5031 if (iptr->dst->flags & INMEMORY) {
5032 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5033 if (src->prev->regoff == iptr->dst->regoff) {
5034 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5035 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5038 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5039 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5040 i386_shift_reg(shift_op, REG_ITMP1);
5041 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5044 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5045 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5046 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5047 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5049 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5050 if (src->prev->regoff == iptr->dst->regoff) {
5051 M_INTMOVE(src->regoff, I386_ECX);
5052 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5055 M_INTMOVE(src->regoff, I386_ECX);
5056 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5057 i386_shift_reg(shift_op, REG_ITMP1);
5058 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5062 M_INTMOVE(src->regoff, I386_ECX);
5063 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5064 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5068 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5069 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5070 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5071 i386_shift_reg(shift_op, iptr->dst->regoff);
5073 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5074 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5075 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5076 i386_shift_reg(shift_op, iptr->dst->regoff);
5078 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5079 M_INTMOVE(src->regoff, I386_ECX);
5080 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5081 i386_shift_reg(shift_op, iptr->dst->regoff);
5084 M_INTMOVE(src->regoff, I386_ECX);
5085 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5086 i386_shift_reg(shift_op, iptr->dst->regoff);
5093 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5095 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5096 if (src->regoff == iptr->dst->regoff) {
5097 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5100 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5101 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5102 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5105 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5106 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5107 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5109 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5110 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5111 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5114 M_INTMOVE(src->regoff, iptr->dst->regoff);
5115 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5121 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5123 if (iptr->dst->flags & INMEMORY) {
5126 if (src->flags & INMEMORY) {
5127 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5130 i386_test_reg_reg(src->regoff, src->regoff);
5134 CALCOFFSETBYTES(offset, iptr->dst->regoff * 8);
5136 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5137 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5139 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5140 i386_jmp_imm(offset);
5141 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5145 if (src->flags & INMEMORY) {
5146 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5149 i386_test_reg_reg(src->regoff, src->regoff);
5152 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5153 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5155 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5157 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5169 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5170 *(mcodeptr++) = (u1) 0x89;
5171 i386_emit_reg((reg),(dreg));
5175 void i386_mov_imm_reg(s4 imm, s4 reg) {
5176 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5177 i386_emit_imm32((imm));
5181 void i386_movb_imm_reg(s4 imm, s4 reg) {
5182 *(mcodeptr++) = (u1) 0xc6;
5183 i386_emit_reg(0,(reg));
5184 i386_emit_imm8((imm));
5188 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5189 *(mcodeptr++) = (u1) 0x8b;
5190 i386_emit_membase((basereg),(disp),(reg));
5195 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5196 * constant membase immediate length of 32bit
5198 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5199 *(mcodeptr++) = (u1) 0x8b;
5200 i386_address_byte(2, (reg), (basereg));
5201 i386_emit_imm32((disp));
5205 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5206 *(mcodeptr++) = (u1) 0x89;
5207 i386_emit_membase((basereg),(disp),(reg));
5211 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5212 *(mcodeptr++) = (u1) 0x8b;
5213 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5217 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5218 *(mcodeptr++) = (u1) 0x89;
5219 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5223 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5224 *(mcodeptr++) = (u1) 0x66;
5225 *(mcodeptr++) = (u1) 0x89;
5226 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5230 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5231 *(mcodeptr++) = (u1) 0x88;
5232 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5236 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5237 *(mcodeptr++) = (u1) 0xc7;
5238 i386_emit_membase((basereg),(disp),0);
5239 i386_emit_imm32((imm));
5243 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5244 *(mcodeptr++) = (u1) 0x0f;
5245 *(mcodeptr++) = (u1) 0xbe;
5246 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5250 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5251 *(mcodeptr++) = (u1) 0x0f;
5252 *(mcodeptr++) = (u1) 0xbf;
5253 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5257 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5258 *(mcodeptr++) = (u1) 0x0f;
5259 *(mcodeptr++) = (u1) 0xb7;
5260 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5268 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5269 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5270 i386_emit_reg((reg),(dreg));
5274 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5275 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5276 i386_emit_membase((basereg),(disp),(reg));
5280 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5281 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5282 i386_emit_membase((basereg),(disp),(reg));
5286 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5287 if (i386_is_imm8(imm)) {
5288 *(mcodeptr++) = (u1) 0x83;
5289 i386_emit_reg((opc),(dreg));
5290 i386_emit_imm8((imm));
5292 *(mcodeptr++) = (u1) 0x81;
5293 i386_emit_reg((opc),(dreg));
5294 i386_emit_imm32((imm));
5299 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5300 if (i386_is_imm8(imm)) {
5301 *(mcodeptr++) = (u1) 0x83;
5302 i386_emit_membase((basereg),(disp),(opc));
5303 i386_emit_imm8((imm));
5305 *(mcodeptr++) = (u1) 0x81;
5306 i386_emit_membase((basereg),(disp),(opc));
5307 i386_emit_imm32((imm));
5312 void i386_test_reg_reg(s4 reg, s4 dreg) {
5313 *(mcodeptr++) = (u1) 0x85;
5314 i386_emit_reg((reg),(dreg));
5318 void i386_test_imm_reg(s4 imm, s4 reg) {
5319 *(mcodeptr++) = (u1) 0xf7;
5320 i386_emit_reg(0,(reg));
5321 i386_emit_imm32((imm));
5327 * inc, dec operations
5329 void i386_inc_reg(s4 reg) {
5330 *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
5334 void i386_inc_membase(s4 basereg, s4 disp) {
5335 *(mcodeptr++) = (u1) 0xff;
5336 i386_emit_membase((basereg),(disp),0);
5340 void i386_dec_reg(s4 reg) {
5341 *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
5345 void i386_dec_membase(s4 basereg, s4 disp) {
5346 *(mcodeptr++) = (u1) 0xff;
5347 i386_emit_membase((basereg),(disp),1);
5353 *(mcodeptr++) = (u1) 0x99;
5358 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5359 *(mcodeptr++) = (u1) 0x0f;
5360 *(mcodeptr++) = (u1) 0xaf;
5361 i386_emit_reg((dreg),(reg));
5365 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5366 *(mcodeptr++) = (u1) 0x0f;
5367 *(mcodeptr++) = (u1) 0xaf;
5368 i386_emit_membase((basereg),(disp),(dreg));
5372 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5373 if (i386_is_imm8((imm))) {
5374 *(mcodeptr++) = (u1) 0x6b;
5375 i386_emit_reg(0,(dreg));
5376 i386_emit_imm8((imm));
5378 *(mcodeptr++) = (u1) 0x69;
5379 i386_emit_reg(0,(dreg));
5380 i386_emit_imm32((imm));
5385 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5386 if (i386_is_imm8((imm))) {
5387 *(mcodeptr++) = (u1) 0x6b;
5388 i386_emit_reg((dreg),(reg));
5389 i386_emit_imm8((imm));
5391 *(mcodeptr++) = (u1) 0x69;
5392 i386_emit_reg((dreg),(reg));
5393 i386_emit_imm32((imm));
5398 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5399 if (i386_is_imm8((imm))) {
5400 *(mcodeptr++) = (u1) 0x6b;
5401 i386_emit_membase((basereg),(disp),(dreg));
5402 i386_emit_imm8((imm));
5404 *(mcodeptr++) = (u1) 0x69;
5405 i386_emit_membase((basereg),(disp),(dreg));
5406 i386_emit_imm32((imm));
5411 void i386_mul_membase(s4 basereg, s4 disp) {
5412 *(mcodeptr++) = (u1) 0xf7;
5413 i386_emit_membase((basereg),(disp),4);
5417 void i386_idiv_reg(s4 reg) {
5418 *(mcodeptr++) = (u1) 0xf7;
5419 i386_emit_reg(7,(reg));
5425 *(mcodeptr++) = (u1) 0xc3;
5433 void i386_shift_reg(s4 opc, s4 reg) {
5434 *(mcodeptr++) = (u1) 0xd3;
5435 i386_emit_reg((opc),(reg));
5439 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5440 *(mcodeptr++) = (u1) 0xd3;
5441 i386_emit_membase((basereg),(disp),(opc));
5445 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5447 *(mcodeptr++) = (u1) 0xd1;
5448 i386_emit_reg((opc),(dreg));
5450 *(mcodeptr++) = (u1) 0xc1;
5451 i386_emit_reg((opc),(dreg));
5452 i386_emit_imm8((imm));
5457 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5459 *(mcodeptr++) = (u1) 0xd1;
5460 i386_emit_membase((basereg),(disp),(opc));
5462 *(mcodeptr++) = (u1) 0xc1;
5463 i386_emit_membase((basereg),(disp),(opc));
5464 i386_emit_imm8((imm));
5469 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5470 *(mcodeptr++) = (u1) 0x0f;
5471 *(mcodeptr++) = (u1) 0xa5;
5472 i386_emit_reg((reg),(dreg));
5476 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5477 *(mcodeptr++) = (u1) 0x0f;
5478 *(mcodeptr++) = (u1) 0xa4;
5479 i386_emit_reg((reg),(dreg));
5480 i386_emit_imm8((imm));
5484 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5485 *(mcodeptr++) = (u1) 0x0f;
5486 *(mcodeptr++) = (u1) 0xa5;
5487 i386_emit_membase((basereg),(disp),(reg));
5491 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5492 *(mcodeptr++) = (u1) 0x0f;
5493 *(mcodeptr++) = (u1) 0xad;
5494 i386_emit_reg((reg),(dreg));
5498 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5499 *(mcodeptr++) = (u1) 0x0f;
5500 *(mcodeptr++) = (u1) 0xac;
5501 i386_emit_reg((reg),(dreg));
5502 i386_emit_imm8((imm));
5506 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5507 *(mcodeptr++) = (u1) 0x0f;
5508 *(mcodeptr++) = (u1) 0xad;
5509 i386_emit_membase((basereg),(disp),(reg));
5517 void i386_jmp_imm(s4 imm) {
5518 *(mcodeptr++) = (u1) 0xe9;
5519 i386_emit_imm32((imm));
5523 void i386_jmp_reg(s4 reg) {
5524 *(mcodeptr++) = (u1) 0xff;
5525 i386_emit_reg(4,(reg));
5529 void i386_jcc(s4 opc, s4 imm) {
5530 *(mcodeptr++) = (u1) 0x0f;
5531 *(mcodeptr++) = (u1) (0x80 + i386_jcc_map[(opc)]);
5532 i386_emit_imm32((imm));
5538 * conditional set operations
5540 void i386_setcc_reg(s4 opc, s4 reg) {
5541 *(mcodeptr++) = (u1) 0x0f;
5542 *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]);
5543 i386_emit_reg(0,(reg));
5547 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5548 *(mcodeptr++) = (u1) 0x0f;
5549 *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]);
5550 i386_emit_membase((basereg),(disp),0);
5555 void i386_neg_reg(s4 reg) {
5556 *(mcodeptr++) = (u1) 0xf7;
5557 i386_emit_reg(3,(reg));
5561 void i386_neg_membase(s4 basereg, s4 disp) {
5562 *(mcodeptr++) = (u1) 0xf7;
5563 i386_emit_membase((basereg),(disp),3);
5568 void i386_push_imm(s4 imm) {
5569 *(mcodeptr++) = (u1) 0x68;
5570 i386_emit_imm32((imm));
5574 void i386_pop_reg(s4 reg) {
5575 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5580 *(mcodeptr++) = (u1) 0x90;
5587 void i386_call_reg(s4 reg) {
5588 *(mcodeptr++) = (u1) 0xff;
5589 i386_emit_reg(2,(reg));
5593 void i386_call_imm(s4 imm) {
5594 *(mcodeptr++) = (u1) 0xe8;
5595 i386_emit_imm32((imm));
5601 * floating point instructions
5604 *(mcodeptr++) = (u1) 0xd9;
5605 *(mcodeptr++) = (u1) 0xe8;
5610 *(mcodeptr++) = (u1) 0xd9;
5611 *(mcodeptr++) = (u1) 0xee;
5615 void i386_fld_reg(s4 reg) {
5616 *(mcodeptr++) = (u1) 0xd9;
5617 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5621 void i386_flds_membase(s4 basereg, s4 disp) {
5622 *(mcodeptr++) = (u1) 0xd9;
5623 i386_emit_membase((basereg),(disp),0);
5627 void i386_fldl_membase(s4 basereg, s4 disp) {
5628 *(mcodeptr++) = (u1) 0xdd;
5629 i386_emit_membase((basereg),(disp),0);
5633 void i386_fldt_membase(s4 basereg, s4 disp) {
5634 *(mcodeptr++) = (u1) 0xdb;
5635 i386_emit_membase((basereg),(disp),5);
5639 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5640 *(mcodeptr++) = (u1) 0xd9;
5641 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5645 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5646 *(mcodeptr++) = (u1) 0xdd;
5647 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5653 void i386_fildl_membase(s4 basereg, s4 disp) {
5654 *(mcodeptr++) = (u1) 0xdb;
5655 i386_emit_membase((basereg),(disp),0);
5659 void i386_fildll_membase(s4 basereg, s4 disp) {
5660 *(mcodeptr++) = (u1) 0xdf;
5661 i386_emit_membase((basereg),(disp),5);
5667 void i386_fst_reg(s4 reg) {
5668 *(mcodeptr++) = (u1) 0xdd;
5669 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5673 void i386_fsts_membase(s4 basereg, s4 disp) {
5674 *(mcodeptr++) = (u1) 0xd9;
5675 i386_emit_membase((basereg),(disp),2);
5679 void i386_fstl_membase(s4 basereg, s4 disp) {
5680 *(mcodeptr++) = (u1) 0xdd;
5681 i386_emit_membase((basereg),(disp),2);
5685 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5686 *(mcodeptr++) = (u1) 0xd9;
5687 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5691 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5692 *(mcodeptr++) = (u1) 0xdd;
5693 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5697 void i386_fstp_reg(s4 reg) {
5698 *(mcodeptr++) = (u1) 0xdd;
5699 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5703 void i386_fstps_membase(s4 basereg, s4 disp) {
5704 *(mcodeptr++) = (u1) 0xd9;
5705 i386_emit_membase((basereg),(disp),3);
5709 void i386_fstpl_membase(s4 basereg, s4 disp) {
5710 *(mcodeptr++) = (u1) 0xdd;
5711 i386_emit_membase((basereg),(disp),3);
5715 void i386_fstpt_membase(s4 basereg, s4 disp) {
5716 *(mcodeptr++) = (u1) 0xdb;
5717 i386_emit_membase((basereg),(disp),7);
5721 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5722 *(mcodeptr++) = (u1) 0xd9;
5723 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5727 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5728 *(mcodeptr++) = (u1) 0xdd;
5729 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5733 void i386_fistl_membase(s4 basereg, s4 disp) {
5734 *(mcodeptr++) = (u1) 0xdb;
5735 i386_emit_membase((basereg),(disp),2);
5739 void i386_fistpl_membase(s4 basereg, s4 disp) {
5740 *(mcodeptr++) = (u1) 0xdb;
5741 i386_emit_membase((basereg),(disp),3);
5745 void i386_fistpll_membase(s4 basereg, s4 disp) {
5746 *(mcodeptr++) = (u1) 0xdf;
5747 i386_emit_membase((basereg),(disp),7);
5752 *(mcodeptr++) = (u1) 0xd9;
5753 *(mcodeptr++) = (u1) 0xe0;
5758 *(mcodeptr++) = (u1) 0xde;
5759 *(mcodeptr++) = (u1) 0xc1;
5763 void i386_fadd_reg_st(s4 reg) {
5764 *(mcodeptr++) = (u1) 0xd8;
5765 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5769 void i386_fadd_st_reg(s4 reg) {
5770 *(mcodeptr++) = (u1) 0xdc;
5771 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5775 void i386_faddp_st_reg(s4 reg) {
5776 *(mcodeptr++) = (u1) 0xde;
5777 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5781 void i386_fadds_membase(s4 basereg, s4 disp) {
5782 *(mcodeptr++) = (u1) 0xd8;
5783 i386_emit_membase((basereg),(disp),0);
5787 void i386_faddl_membase(s4 basereg, s4 disp) {
5788 *(mcodeptr++) = (u1) 0xdc;
5789 i386_emit_membase((basereg),(disp),0);
5793 void i386_fsub_reg_st(s4 reg) {
5794 *(mcodeptr++) = (u1) 0xd8;
5795 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5799 void i386_fsub_st_reg(s4 reg) {
5800 *(mcodeptr++) = (u1) 0xdc;
5801 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5805 void i386_fsubp_st_reg(s4 reg) {
5806 *(mcodeptr++) = (u1) 0xde;
5807 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5812 *(mcodeptr++) = (u1) 0xde;
5813 *(mcodeptr++) = (u1) 0xe9;
5817 void i386_fsubs_membase(s4 basereg, s4 disp) {
5818 *(mcodeptr++) = (u1) 0xd8;
5819 i386_emit_membase((basereg),(disp),4);
5823 void i386_fsubl_membase(s4 basereg, s4 disp) {
5824 *(mcodeptr++) = (u1) 0xdc;
5825 i386_emit_membase((basereg),(disp),4);
5829 void i386_fmul_reg_st(s4 reg) {
5830 *(mcodeptr++) = (u1) 0xd8;
5831 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5835 void i386_fmul_st_reg(s4 reg) {
5836 *(mcodeptr++) = (u1) 0xdc;
5837 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5842 *(mcodeptr++) = (u1) 0xde;
5843 *(mcodeptr++) = (u1) 0xc9;
5847 void i386_fmulp_st_reg(s4 reg) {
5848 *(mcodeptr++) = (u1) 0xde;
5849 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5853 void i386_fmuls_membase(s4 basereg, s4 disp) {
5854 *(mcodeptr++) = (u1) 0xd8;
5855 i386_emit_membase((basereg),(disp),1);
5859 void i386_fmull_membase(s4 basereg, s4 disp) {
5860 *(mcodeptr++) = (u1) 0xdc;
5861 i386_emit_membase((basereg),(disp),1);
5865 void i386_fdiv_reg_st(s4 reg) {
5866 *(mcodeptr++) = (u1) 0xd8;
5867 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
5871 void i386_fdiv_st_reg(s4 reg) {
5872 *(mcodeptr++) = (u1) 0xdc;
5873 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5878 *(mcodeptr++) = (u1) 0xde;
5879 *(mcodeptr++) = (u1) 0xf9;
5883 void i386_fdivp_st_reg(s4 reg) {
5884 *(mcodeptr++) = (u1) 0xde;
5885 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5890 *(mcodeptr++) = (u1) 0xd9;
5891 *(mcodeptr++) = (u1) 0xc9;
5895 void i386_fxch_reg(s4 reg) {
5896 *(mcodeptr++) = (u1) 0xd9;
5897 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5902 *(mcodeptr++) = (u1) 0xd9;
5903 *(mcodeptr++) = (u1) 0xf8;
5907 void i386_fprem1() {
5908 *(mcodeptr++) = (u1) 0xd9;
5909 *(mcodeptr++) = (u1) 0xf5;
5914 *(mcodeptr++) = (u1) 0xdd;
5915 *(mcodeptr++) = (u1) 0xe1;
5919 void i386_fucom_reg(s4 reg) {
5920 *(mcodeptr++) = (u1) 0xdd;
5921 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5925 void i386_fucomp_reg(s4 reg) {
5926 *(mcodeptr++) = (u1) 0xdd;
5927 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5931 void i386_fucompp() {
5932 *(mcodeptr++) = (u1) 0xda;
5933 *(mcodeptr++) = (u1) 0xe9;
5937 void i386_fnstsw() {
5938 *(mcodeptr++) = (u1) 0xdf;
5939 *(mcodeptr++) = (u1) 0xe0;
5944 *(mcodeptr++) = (u1) 0x9e;
5949 *(mcodeptr++) = (u1) 0x9b;
5950 *(mcodeptr++) = (u1) 0xdb;
5951 *(mcodeptr++) = (u1) 0xe3;
5955 void i386_fldcw_mem(s4 mem) {
5956 *(mcodeptr++) = (u1) 0xd9;
5957 i386_emit_mem(5,(mem));
5961 void i386_fldcw_membase(s4 basereg, s4 disp) {
5962 *(mcodeptr++) = (u1) 0xd9;
5963 i386_emit_membase((basereg),(disp),5);
5968 *(mcodeptr++) = (u1) 0x9b;
5972 void i386_ffree_reg(s4 reg) {
5973 *(mcodeptr++) = (u1) 0xdd;
5974 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5978 void i386_fdecstp() {
5979 *(mcodeptr++) = (u1) 0xd9;
5980 *(mcodeptr++) = (u1) 0xf6;
5984 void i386_fincstp() {
5985 *(mcodeptr++) = (u1) 0xd9;
5986 *(mcodeptr++) = (u1) 0xf7;
5992 * These are local overrides for various environment variables in Emacs.
5993 * Please do not remove this and leave it at the end of the file, where
5994 * Emacs will automagically detect them.
5995 * ---------------------------------------------------------------------
5998 * indent-tabs-mode: t