1 /* jit/i386/codegen.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: codegen.c 557 2003-11-02 22:51:59Z twisti $
48 #include "methodtable.h"
50 /* include independent code generation stuff */
51 #include "codegen.inc"
55 /* additional functions and macros to generate code ***************************/
57 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
61 #define COUNT_SPILLS count_spills++
67 #define CALCOFFSETBYTES(var, val) \
68 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
69 else if ((s4) (val) != 0) (var) += 1;
72 #define CALCREGOFFBYTES(var, val) \
73 if ((val) > 15) (var) += 4; \
74 else if ((val) != 0) (var) += 1;
77 #define CALCIMMEDIATEBYTES(var, val) \
78 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
82 /* gen_nullptr_check(objreg) */
84 #define gen_nullptr_check(objreg) \
86 i386_test_reg_reg((objreg), (objreg)); \
87 i386_jcc(I386_CC_E, 0); \
88 codegen_addxnullrefs(mcodeptr); \
92 /* MCODECHECK(icnt) */
94 #define MCODECHECK(icnt) \
95 if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
98 generates an integer-move from register a to b.
99 if a and b are the same int-register, no code will be generated.
102 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
106 generates a floating-point-move from register a to b.
107 if a and b are the same float-register, no code will be generated
110 #define M_FLTMOVE(reg,dreg) panic("M_FLTMOVE");
112 #define M_LNGMEMMOVE(reg,dreg) \
114 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
115 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP2); \
116 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
117 i386_mov_reg_membase(REG_ITMP2, REG_SP, (dreg) * 8 + 4); \
122 this function generates code to fetch data from a pseudo-register
123 into a real register.
124 If the pseudo-register has actually been assigned to a real
125 register, no code will be emitted, since following operations
126 can use this register directly.
128 v: pseudoregister to be fetched from
129 tempregnum: temporary register to be used if v is actually spilled to ram
131 return: the register number, where the operand can be found after
132 fetching (this wil be either tempregnum or the register
133 number allready given to v)
136 #define var_to_reg_int(regnr,v,tempnr) \
137 if ((v)->flags & INMEMORY) { \
139 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
142 regnr = (v)->regoff; \
147 #define var_to_reg_flt(regnr,v,tempnr) \
148 if ((v)->type == TYPE_FLT) { \
149 if ((v)->flags & INMEMORY) { \
151 i386_flds_membase(REG_SP, (v)->regoff * 8); \
155 i386_fld_reg((v)->regoff + fpu_st_offset); \
157 regnr = (v)->regoff; \
160 if ((v)->flags & INMEMORY) { \
162 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
166 i386_fld_reg((v)->regoff + fpu_st_offset); \
168 regnr = (v)->regoff; \
172 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
173 if ((v)->type == TYPE_FLT) { \
174 if ((v)->flags & INMEMORY) { \
176 i386_flds_membase(REG_SP, (v)->regoff * 8); \
180 regnr = (v)->regoff; \
183 if ((v)->flags & INMEMORY) { \
185 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
189 regnr = (v)->regoff; \
195 This function determines a register, to which the result of an operation
196 should go, when it is ultimatively intended to store the result in
198 If v is assigned to an actual register, this register will be returned.
199 Otherwise (when v is spilled) this function returns tempregnum.
200 If not already done, regoff and flags are set in the stack location.
203 static int reg_of_var(stackptr v, int tempregnum)
207 switch (v->varkind) {
209 if (!(v->flags & INMEMORY))
213 var = &(interfaces[v->varnum][v->type]);
214 v->regoff = var->regoff;
215 if (!(var->flags & INMEMORY))
219 var = &(locals[v->varnum][v->type]);
220 v->regoff = var->regoff;
221 if (!(var->flags & INMEMORY))
225 v->regoff = v->varnum;
226 if (IS_FLT_DBL_TYPE(v->type)) {
227 if (v->varnum < fltreg_argnum) {
228 v->regoff = argfltregs[v->varnum];
229 return(argfltregs[v->varnum]);
233 if (v->varnum < intreg_argnum) {
234 v->regoff = argintregs[v->varnum];
235 return(argintregs[v->varnum]);
237 v->regoff -= intreg_argnum;
240 v->flags |= INMEMORY;
245 /* store_reg_to_var_xxx:
246 This function generates the code to store the result of an operation
247 back into a spilled pseudo-variable.
248 If the pseudo-variable has not been spilled in the first place, this
249 function will generate nothing.
251 v ............ Pseudovariable
252 tempregnum ... Number of the temporary registers as returned by
256 #define store_reg_to_var_int(sptr, tempregnum) \
257 if ((sptr)->flags & INMEMORY) { \
259 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
263 #define store_reg_to_var_flt(sptr, tempregnum) \
264 if ((sptr)->type == TYPE_FLT) { \
265 if ((sptr)->flags & INMEMORY) { \
267 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
270 /* i386_fxch_reg((sptr)->regoff);*/ \
271 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
275 if ((sptr)->flags & INMEMORY) { \
277 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
280 /* i386_fxch_reg((sptr)->regoff);*/ \
281 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
287 /* NullPointerException signal handler for hardware null pointer check */
289 void catch_NullPointerException(int sig)
293 /* long faultaddr; */
295 void **_p = (void **) &sig;
296 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
298 /* Reset signal handler - necessary for SysV, does no harm for BSD */
300 instr = *((int*)(sigctx->eip));
301 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
303 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip); */
305 /* if (faultaddr == 0) { */
306 signal(sig, (void *) catch_NullPointerException); /* reinstall handler */
308 sigaddset(&nsig, sig);
309 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
310 sigctx->eax = (long) proto_java_lang_NullPointerException; /* REG_ITMP1_XPTR */
311 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
312 sigctx->eip = (long) asm_handle_exception;
317 /* faultaddr += (long) ((instr << 16) >> 16); */
318 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
319 /* panic("Stack overflow"); */
323 /* ArithmeticException signal handler for hardware divide by zero check */
325 void catch_ArithmeticException(int sig)
329 void **_p = (void **) &sig;
330 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
333 java_objectheader *p;
336 /* Reset signal handler - necessary for SysV, does no harm for BSD */
338 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
340 sigaddset(&nsig, sig);
341 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
343 c = loader_load(utf_new_char("java/lang/ArithmeticException"));
345 m = class_findmethod(c,
346 utf_new_char("<init>"),
347 utf_new_char("(Ljava/lang/String;)V"));
349 asm_calljavamethod(m, p, javastring_new_char("/ by zero"), NULL, NULL);
351 sigctx->eax = (long) p; /* REG_ITMP1_XPTR */
352 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
353 sigctx->eip = (long) asm_handle_exception;
358 void init_exceptions(void)
360 /* install signal handlers we need to convert to exceptions */
365 signal(SIGSEGV, (void *) catch_NullPointerException);
369 signal(SIGBUS, (void *) catch_NullPointerException);
373 signal(SIGFPE, (void *) catch_ArithmeticException);
377 /* function gen_mcode **********************************************************
379 generates machine code
381 *******************************************************************************/
387 int len, s1, s2, s3, d/*, bbs*/;
395 int fpu_st_offset = 0;
404 /* space to save used callee saved registers */
406 savedregs_num += (savintregcnt - maxsavintreguse);
407 savedregs_num += (savfltregcnt - maxsavfltreguse);
409 parentargs_base = maxmemuse + savedregs_num;
411 #ifdef USE_THREADS /* space to save argument of monitor_enter */
413 if (checksync && (method->flags & ACC_SYNCHRONIZED))
418 /* create method header */
420 (void) dseg_addaddress(method); /* MethodPointer */
421 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
425 /* IsSync contains the offset relative to the stack pointer for the
426 argument of monitor_exit used in the exception handler. Since the
427 offset could be zero and give a wrong meaning of the flag it is
431 if (checksync && (method->flags & ACC_SYNCHRONIZED))
432 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
437 (void) dseg_adds4(0); /* IsSync */
439 (void) dseg_adds4(isleafmethod); /* IsLeaf */
440 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
441 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
442 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
444 /* create exception table */
446 for (ex = extable; ex != NULL; ex = ex->down) {
449 if (ex->start != NULL)
450 printf("adding start - %d - ", ex->start->debug_nr);
452 printf("PANIC - start is NULL");
457 dseg_addtarget(ex->start);
461 printf("adding end - %d - ", ex->end->debug_nr);
463 printf("PANIC - end is NULL");
468 dseg_addtarget(ex->end);
471 if (ex->handler != NULL)
472 printf("adding handler - %d\n", ex->handler->debug_nr);
474 printf("PANIC - handler is NULL");
479 dseg_addtarget(ex->handler);
481 (void) dseg_addaddress(ex->catchtype);
484 /* initialize mcode variables */
486 mcodeptr = (u1*) mcodebase;
487 mcodeend = (s4*) (mcodebase + mcodesize);
488 MCODECHECK(128 + mparamcount);
490 /* create stack frame (if necessary) */
492 if (parentargs_base) {
493 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
496 /* save return address and used callee saved registers */
499 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
500 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
502 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
503 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
506 /* save monitorenter argument */
509 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
510 if (method->flags & ACC_STATIC) {
511 i386_mov_imm_reg((s4) class, REG_ITMP1);
512 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
515 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
516 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
521 /* copy argument registers to stack and call trace function with pointer
522 to arguments on stack.
526 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
528 for (p = 0; p < mparamcount; p++) {
530 if (IS_INT_LNG_TYPE(t)) {
531 if (IS_2_WORD_TYPE(t)) {
532 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
533 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
535 } else if (t == TYPE_ADR) {
536 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
537 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
540 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
543 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
544 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
548 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
549 i386_fstps_membase(REG_SP, p * 8);
550 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
551 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
554 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
555 i386_fstpl_membase(REG_SP, p * 8);
560 /* fill up the remaining arguments */
561 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
562 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
563 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
564 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
567 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
569 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
570 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
571 i386_call_reg(REG_ITMP1);
573 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
576 /* take arguments out of register or stack frame */
578 for (p = 0, l = 0; p < mparamcount; p++) {
580 var = &(locals[l][t]);
582 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
587 if (IS_INT_LNG_TYPE(t)) { /* integer args */
588 if (p < intreg_argnum) { /* register arguments */
589 panic("integer register argument");
590 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
591 /* M_INTMOVE (argintregs[p], r); */
593 } else { /* reg arg -> spilled */
594 /* M_LST (argintregs[p], REG_SP, 8 * r); */
596 } else { /* stack arguments */
597 pa = p - intreg_argnum;
598 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
599 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
600 } else { /* stack arg -> spilled */
601 if (!IS_2_WORD_TYPE(t)) {
602 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
603 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
606 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
607 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
608 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
609 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
614 } else { /* floating args */
615 if (p < fltreg_argnum) { /* register arguments */
616 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
617 panic("There are no float argument registers!");
619 } else { /* reg arg -> spilled */
620 panic("There are no float argument registers!");
623 } else { /* stack arguments */
624 pa = p - fltreg_argnum;
625 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
627 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
629 i386_fstp_reg(r + fpu_st_offset);
633 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
635 i386_fstp_reg(r + fpu_st_offset);
639 } else { /* stack-arg -> spilled */
640 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
641 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
643 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
644 i386_fstps_membase(REG_SP, r * 8);
647 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
648 i386_fstpl_membase(REG_SP, r * 8);
655 /* call monitorenter function */
658 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
659 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
660 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
661 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
662 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP2);
663 i386_call_reg(REG_ITMP2);
664 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
669 /* end of header generation */
671 /* walk through all basic blocks */
672 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
674 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
676 if (bptr->flags >= BBREACHED) {
678 /* branch resolving */
681 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
682 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
683 brefs->branchpos, bptr->mpc);
686 /* copy interface registers to their destination */
691 while (src != NULL) {
693 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
694 if (!IS_2_WORD_TYPE(src->type)) {
695 if (bptr->type == BBTYPE_SBR) {
696 d = reg_of_var(src, REG_ITMP1);
698 store_reg_to_var_int(src, d);
700 } else if (bptr->type == BBTYPE_EXH) {
701 d = reg_of_var(src, REG_ITMP1);
702 M_INTMOVE(REG_ITMP1, d);
703 store_reg_to_var_int(src, d);
707 panic("copy interface registers: longs have to me in memory (begin 1)");
711 d = reg_of_var(src, REG_ITMP1);
712 if ((src->varkind != STACKVAR)) {
714 if (IS_FLT_DBL_TYPE(s2)) {
715 s1 = interfaces[len][s2].regoff;
716 if (!(interfaces[len][s2].flags & INMEMORY)) {
720 if (s2 == TYPE_FLT) {
721 i386_flds_membase(REG_SP, s1 * 8);
724 i386_fldl_membase(REG_SP, s1 * 8);
727 store_reg_to_var_flt(src, d);
730 s1 = interfaces[len][s2].regoff;
731 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
732 if (!(interfaces[len][s2].flags & INMEMORY)) {
736 i386_mov_membase_reg(REG_SP, s1 * 8, d);
738 store_reg_to_var_int(src, d);
741 if (interfaces[len][s2].flags & INMEMORY) {
742 M_LNGMEMMOVE(s1, src->regoff);
745 panic("copy interface registers: longs have to be in memory (begin 2)");
754 /* walk through all instructions */
758 for (iptr = bptr->iinstr;
760 src = iptr->dst, len--, iptr++) {
762 MCODECHECK(64); /* an instruction usually needs < 64 words */
765 case ICMD_NOP: /* ... ==> ... */
768 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
769 if (src->flags & INMEMORY) {
770 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
773 i386_test_reg_reg(src->regoff, src->regoff);
775 i386_jcc(I386_CC_E, 0);
776 codegen_addxnullrefs(mcodeptr);
779 /* constant operations ************************************************/
781 case ICMD_ICONST: /* ... ==> ..., constant */
782 /* op1 = 0, val.i = constant */
784 d = reg_of_var(iptr->dst, REG_ITMP1);
785 if (iptr->dst->flags & INMEMORY) {
786 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
789 if (iptr->val.i == 0) {
790 i386_alu_reg_reg(I386_XOR, d, d);
793 i386_mov_imm_reg(iptr->val.i, d);
798 case ICMD_LCONST: /* ... ==> ..., constant */
799 /* op1 = 0, val.l = constant */
801 d = reg_of_var(iptr->dst, REG_ITMP1);
802 if (iptr->dst->flags & INMEMORY) {
803 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
804 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
807 panic("LCONST: longs have to be in memory");
811 case ICMD_FCONST: /* ... ==> ..., constant */
812 /* op1 = 0, val.f = constant */
814 d = reg_of_var(iptr->dst, REG_FTMP1);
815 if (iptr->val.f == 0.0) {
820 if (iptr->val.i == 0x80000000) {
824 } else if (iptr->val.f == 1.0) {
828 } else if (iptr->val.f == 2.0) {
835 a = dseg_addfloat(iptr->val.f);
836 i386_mov_imm_reg(0, REG_ITMP1);
837 dseg_adddata(mcodeptr);
838 i386_flds_membase(REG_ITMP1, a);
841 store_reg_to_var_flt(iptr->dst, d);
844 case ICMD_DCONST: /* ... ==> ..., constant */
845 /* op1 = 0, val.d = constant */
847 d = reg_of_var(iptr->dst, REG_FTMP1);
848 if (iptr->val.d == 0.0) {
853 if (iptr->val.l == 0x8000000000000000LL) {
857 } else if (iptr->val.d == 1.0) {
861 } else if (iptr->val.d == 2.0) {
868 a = dseg_adddouble(iptr->val.d);
869 i386_mov_imm_reg(0, REG_ITMP1);
870 dseg_adddata(mcodeptr);
871 i386_fldl_membase(REG_ITMP1, a);
874 store_reg_to_var_flt(iptr->dst, d);
877 case ICMD_ACONST: /* ... ==> ..., constant */
878 /* op1 = 0, val.a = constant */
880 d = reg_of_var(iptr->dst, REG_ITMP1);
881 if (iptr->dst->flags & INMEMORY) {
882 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
885 if ((s4) iptr->val.a == 0) {
886 i386_alu_reg_reg(I386_XOR, d, d);
889 i386_mov_imm_reg((s4) iptr->val.a, d);
895 /* load/store operations **********************************************/
897 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
898 case ICMD_ALOAD: /* op1 = local variable */
900 d = reg_of_var(iptr->dst, REG_ITMP1);
901 if ((iptr->dst->varkind == LOCALVAR) &&
902 (iptr->dst->varnum == iptr->op1)) {
905 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
906 if (iptr->dst->flags & INMEMORY) {
907 if (var->flags & INMEMORY) {
908 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
909 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
912 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
916 if (var->flags & INMEMORY) {
917 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
920 M_INTMOVE(var->regoff, iptr->dst->regoff);
925 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
926 /* op1 = local variable */
928 d = reg_of_var(iptr->dst, REG_ITMP1);
929 if ((iptr->dst->varkind == LOCALVAR) &&
930 (iptr->dst->varnum == iptr->op1)) {
933 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
934 if (iptr->dst->flags & INMEMORY) {
935 if (var->flags & INMEMORY) {
936 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
939 panic("LLOAD: longs have to be in memory");
943 panic("LLOAD: longs have to be in memory");
947 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
948 /* op1 = local variable */
950 d = reg_of_var(iptr->dst, REG_FTMP1);
951 if ((iptr->dst->varkind == LOCALVAR) &&
952 (iptr->dst->varnum == iptr->op1)) {
955 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
956 if (var->flags & INMEMORY) {
957 i386_flds_membase(REG_SP, var->regoff * 8);
960 i386_fld_reg(var->regoff + fpu_st_offset);
963 store_reg_to_var_flt(iptr->dst, d);
966 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
967 /* op1 = local variable */
969 d = reg_of_var(iptr->dst, REG_FTMP1);
970 if ((iptr->dst->varkind == LOCALVAR) &&
971 (iptr->dst->varnum == iptr->op1)) {
974 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
975 if (var->flags & INMEMORY) {
976 i386_fldl_membase(REG_SP, var->regoff * 8);
979 i386_fld_reg(var->regoff + fpu_st_offset);
982 store_reg_to_var_flt(iptr->dst, d);
985 case ICMD_ISTORE: /* ..., value ==> ... */
986 case ICMD_ASTORE: /* op1 = local variable */
988 if ((src->varkind == LOCALVAR) &&
989 (src->varnum == iptr->op1)) {
992 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
993 if (var->flags & INMEMORY) {
994 if (src->flags & INMEMORY) {
995 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
996 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
999 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
1003 var_to_reg_int(s1, src, var->regoff);
1004 M_INTMOVE(s1, var->regoff);
1008 case ICMD_LSTORE: /* ..., value ==> ... */
1009 /* op1 = local variable */
1011 if ((src->varkind == LOCALVAR) &&
1012 (src->varnum == iptr->op1)) {
1015 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1016 if (var->flags & INMEMORY) {
1017 if (src->flags & INMEMORY) {
1018 M_LNGMEMMOVE(src->regoff, var->regoff);
1021 panic("LSTORE: longs have to be in memory");
1025 panic("LSTORE: longs have to be in memory");
1029 case ICMD_FSTORE: /* ..., value ==> ... */
1030 /* op1 = local variable */
1032 if ((src->varkind == LOCALVAR) &&
1033 (src->varnum == iptr->op1)) {
1036 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1037 if (var->flags & INMEMORY) {
1038 var_to_reg_flt(s1, src, REG_FTMP1);
1039 i386_fstps_membase(REG_SP, var->regoff * 8);
1042 var_to_reg_flt(s1, src, var->regoff);
1043 /* M_FLTMOVE(s1, var->regoff); */
1044 i386_fstp_reg(var->regoff + fpu_st_offset);
1049 case ICMD_DSTORE: /* ..., value ==> ... */
1050 /* op1 = local variable */
1052 if ((src->varkind == LOCALVAR) &&
1053 (src->varnum == iptr->op1)) {
1056 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1057 if (var->flags & INMEMORY) {
1058 var_to_reg_flt(s1, src, REG_FTMP1);
1059 i386_fstpl_membase(REG_SP, var->regoff * 8);
1062 var_to_reg_flt(s1, src, var->regoff);
1063 /* M_FLTMOVE(s1, var->regoff); */
1064 i386_fstp_reg(var->regoff + fpu_st_offset);
1070 /* pop/dup/swap operations ********************************************/
1072 /* attention: double and longs are only one entry in CACAO ICMDs */
1074 case ICMD_POP: /* ..., value ==> ... */
1075 case ICMD_POP2: /* ..., value, value ==> ... */
1078 #define M_COPY(from,to) \
1079 d = reg_of_var(to, REG_ITMP1); \
1080 if ((from->regoff != to->regoff) || \
1081 ((from->flags ^ to->flags) & INMEMORY)) { \
1082 if (IS_FLT_DBL_TYPE(from->type)) { \
1083 var_to_reg_flt(s1, from, d); \
1084 /* M_FLTMOVE(s1, d);*/ \
1085 store_reg_to_var_flt(to, d); \
1087 if (!IS_2_WORD_TYPE(from->type)) { \
1088 if (to->flags & INMEMORY) { \
1089 if (from->flags & INMEMORY) { \
1090 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1091 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1093 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1096 if (from->flags & INMEMORY) { \
1097 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1099 i386_mov_reg_reg(from->regoff, to->regoff); \
1103 M_LNGMEMMOVE(from->regoff, to->regoff); \
1108 case ICMD_DUP: /* ..., a ==> ..., a, a */
1109 M_COPY(src, iptr->dst);
1112 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1114 M_COPY(src, iptr->dst->prev->prev);
1116 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1118 M_COPY(src, iptr->dst);
1119 M_COPY(src->prev, iptr->dst->prev);
1122 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1124 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1126 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1128 M_COPY(src, iptr->dst);
1129 M_COPY(src->prev, iptr->dst->prev);
1130 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1131 M_COPY(src, iptr->dst->prev->prev->prev);
1134 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1136 M_COPY(src, iptr->dst);
1137 M_COPY(src->prev, iptr->dst->prev);
1138 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1139 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1140 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1141 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1144 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1146 M_COPY(src, iptr->dst->prev);
1147 M_COPY(src->prev, iptr->dst);
1151 /* integer operations *************************************************/
1153 case ICMD_INEG: /* ..., value ==> ..., - value */
1155 d = reg_of_var(iptr->dst, REG_NULL);
1156 if (iptr->dst->flags & INMEMORY) {
1157 if (src->flags & INMEMORY) {
1158 if (src->regoff == iptr->dst->regoff) {
1159 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1162 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1163 i386_neg_reg(REG_ITMP1);
1164 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1168 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1169 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1173 if (src->flags & INMEMORY) {
1174 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1175 i386_neg_reg(iptr->dst->regoff);
1178 M_INTMOVE(src->regoff, iptr->dst->regoff);
1179 i386_neg_reg(iptr->dst->regoff);
1184 case ICMD_LNEG: /* ..., value ==> ..., - value */
1186 d = reg_of_var(iptr->dst, REG_NULL);
1187 if (iptr->dst->flags & INMEMORY) {
1188 if (src->flags & INMEMORY) {
1189 if (src->regoff == iptr->dst->regoff) {
1190 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1191 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1192 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1195 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1196 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1197 i386_neg_reg(REG_ITMP1);
1198 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1199 i386_neg_reg(REG_ITMP2);
1200 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1201 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1207 case ICMD_I2L: /* ..., value ==> ..., value */
1209 d = reg_of_var(iptr->dst, REG_NULL);
1210 if (iptr->dst->flags & INMEMORY) {
1211 if (src->flags & INMEMORY) {
1212 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX);
1214 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1215 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1218 M_INTMOVE(src->regoff, I386_EAX);
1220 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1221 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1226 case ICMD_L2I: /* ..., 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_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1236 if (src->flags & INMEMORY) {
1237 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1242 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1244 d = reg_of_var(iptr->dst, REG_NULL);
1245 if (iptr->dst->flags & INMEMORY) {
1246 if (src->flags & INMEMORY) {
1247 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1248 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1249 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1250 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1253 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1254 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1255 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1259 if (src->flags & INMEMORY) {
1260 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1261 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1262 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1265 M_INTMOVE(src->regoff, iptr->dst->regoff);
1266 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1267 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1272 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1274 d = reg_of_var(iptr->dst, REG_NULL);
1275 if (iptr->dst->flags & INMEMORY) {
1276 if (src->flags & INMEMORY) {
1277 if (src->regoff == iptr->dst->regoff) {
1278 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1281 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1282 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1283 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1287 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1288 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1292 if (src->flags & INMEMORY) {
1293 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1294 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1297 M_INTMOVE(src->regoff, iptr->dst->regoff);
1298 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1303 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1305 d = reg_of_var(iptr->dst, REG_NULL);
1306 if (iptr->dst->flags & INMEMORY) {
1307 if (src->flags & INMEMORY) {
1308 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1309 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1310 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1311 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1314 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1315 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1316 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1320 if (src->flags & INMEMORY) {
1321 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1322 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1323 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1326 M_INTMOVE(src->regoff, iptr->dst->regoff);
1327 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1328 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1334 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1336 d = reg_of_var(iptr->dst, REG_NULL);
1337 i386_emit_ialu(I386_ADD, src, iptr);
1340 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1341 /* val.i = constant */
1343 d = reg_of_var(iptr->dst, REG_NULL);
1344 /* should we use a inc optimization for smaller code size? */
1345 i386_emit_ialuconst(I386_ADD, src, iptr);
1348 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1350 d = reg_of_var(iptr->dst, REG_NULL);
1351 if (iptr->dst->flags & INMEMORY) {
1352 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1353 if (src->regoff == iptr->dst->regoff) {
1354 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1355 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1356 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1357 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1359 } else if (src->prev->regoff == iptr->dst->regoff) {
1360 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1361 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1362 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1363 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1366 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1367 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1368 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1369 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1370 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1371 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1378 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1379 /* val.l = constant */
1381 d = reg_of_var(iptr->dst, REG_NULL);
1382 if (iptr->dst->flags & INMEMORY) {
1383 if (src->flags & INMEMORY) {
1384 if (src->regoff == iptr->dst->regoff) {
1385 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1386 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1389 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1390 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1391 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1392 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP2);
1393 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1394 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1400 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1402 d = reg_of_var(iptr->dst, REG_NULL);
1403 if (iptr->dst->flags & INMEMORY) {
1404 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1405 if (src->prev->regoff == iptr->dst->regoff) {
1406 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1407 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1410 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1411 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1412 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1415 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1416 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1417 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1418 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1420 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1421 if (src->prev->regoff == iptr->dst->regoff) {
1422 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1425 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1426 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1427 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1431 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1432 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1436 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1437 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1438 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1440 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1441 M_INTMOVE(src->prev->regoff, d);
1442 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1444 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1445 /* workaround for reg alloc */
1446 if (src->regoff == iptr->dst->regoff) {
1447 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1448 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1449 M_INTMOVE(REG_ITMP1, d);
1452 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1453 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1457 /* workaround for reg alloc */
1458 if (src->regoff == iptr->dst->regoff) {
1459 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1460 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1461 M_INTMOVE(REG_ITMP1, d);
1464 M_INTMOVE(src->prev->regoff, d);
1465 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1471 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1472 /* val.i = constant */
1474 d = reg_of_var(iptr->dst, REG_NULL);
1475 i386_emit_ialuconst(I386_SUB, src, iptr);
1478 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1480 d = reg_of_var(iptr->dst, REG_NULL);
1481 if (iptr->dst->flags & INMEMORY) {
1482 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1483 if (src->prev->regoff == iptr->dst->regoff) {
1484 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1485 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1486 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1487 i386_alu_reg_membase(I386_SBB, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1490 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1491 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1492 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1493 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1494 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1495 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1501 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1502 /* val.l = constant */
1504 d = reg_of_var(iptr->dst, REG_NULL);
1505 if (iptr->dst->flags & INMEMORY) {
1506 if (src->flags & INMEMORY) {
1507 if (src->regoff == iptr->dst->regoff) {
1508 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1509 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1512 /* TODO: could be size optimized with lea -- see gcc output */
1513 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1514 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1515 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1516 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP2);
1517 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1518 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1524 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1526 d = reg_of_var(iptr->dst, REG_NULL);
1527 if (iptr->dst->flags & INMEMORY) {
1528 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1529 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1530 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1531 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1533 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1534 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1535 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1536 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1538 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1539 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1540 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1541 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1544 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1545 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1546 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1550 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1551 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1552 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1554 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1555 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1556 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1558 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1559 M_INTMOVE(src->regoff, iptr->dst->regoff);
1560 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1563 if (src->regoff == iptr->dst->regoff) {
1564 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1567 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1568 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1574 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1575 /* val.i = constant */
1577 d = reg_of_var(iptr->dst, REG_NULL);
1578 if (iptr->dst->flags & INMEMORY) {
1579 if (src->flags & INMEMORY) {
1580 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1581 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1584 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1585 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1589 if (src->flags & INMEMORY) {
1590 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1593 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1598 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1600 d = reg_of_var(iptr->dst, REG_NULL);
1601 if (iptr->dst->flags & INMEMORY) {
1602 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1603 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX); /* mem -> EAX */
1604 /* optimize move EAX -> REG_ITMP3 is slower??? */
1605 /* i386_mov_reg_reg(I386_EAX, REG_ITMP3); */
1606 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1608 /* TODO: optimize move EAX -> REG_ITMP3 */
1609 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem -> ITMP3 */
1610 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1611 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1613 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1614 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1616 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1617 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1618 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1623 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1624 /* val.l = constant */
1626 d = reg_of_var(iptr->dst, REG_NULL);
1627 if (iptr->dst->flags & INMEMORY) {
1628 if (src->flags & INMEMORY) {
1629 i386_mov_imm_reg(iptr->val.l, I386_EAX); /* imm -> EAX */
1630 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1631 /* TODO: optimize move EAX -> REG_ITMP3 */
1632 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP3); /* imm -> ITMP3 */
1633 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1635 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1636 i386_mov_imm_reg(iptr->val.l, REG_ITMP3); /* imm -> ITMP3 */
1637 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1639 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1640 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1641 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1646 #define gen_div_check(v) \
1648 if ((v)->flags & INMEMORY) { \
1649 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1651 i386_test_reg_reg(src->regoff, src->regoff); \
1653 i386_jcc(I386_CC_E, 0); \
1654 codegen_addxdivrefs(mcodeptr); \
1657 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1659 d = reg_of_var(iptr->dst, REG_NULL);
1660 var_to_reg_int(s1, src, REG_ITMP3);
1662 if (src->prev->flags & INMEMORY) {
1663 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1666 M_INTMOVE(src->prev->regoff, I386_EAX);
1669 i386_alu_imm_reg(I386_CMP, 0x80000000, I386_EAX); /* check as described in jvm spec */
1670 i386_jcc(I386_CC_NE, 3 + 6);
1671 i386_alu_imm_reg(I386_CMP, -1, s1);
1672 i386_jcc(I386_CC_E, 1 + 2);
1677 if (iptr->dst->flags & INMEMORY) {
1678 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1681 M_INTMOVE(I386_EAX, iptr->dst->regoff);
1685 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1687 d = reg_of_var(iptr->dst, REG_NULL);
1688 var_to_reg_int(s1, src, REG_ITMP3);
1690 if (src->prev->flags & INMEMORY) {
1691 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1694 M_INTMOVE(src->prev->regoff, I386_EAX);
1697 i386_alu_imm_reg(I386_CMP, 0x80000000, I386_EAX); /* check as described in jvm spec */
1698 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1699 i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EDX);
1700 i386_alu_imm_reg(I386_CMP, -1, s1);
1701 i386_jcc(I386_CC_E, 1 + 2);
1706 if (iptr->dst->flags & INMEMORY) {
1707 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8);
1710 M_INTMOVE(I386_EDX, iptr->dst->regoff);
1714 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1715 /* val.i = constant */
1717 /* TODO: optimize for `/ 2' */
1718 var_to_reg_int(s1, src, REG_ITMP1);
1719 d = reg_of_var(iptr->dst, REG_ITMP1);
1722 i386_test_reg_reg(d, d);
1724 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1725 i386_jcc(I386_CC_NS, a);
1726 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1728 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1729 store_reg_to_var_int(iptr->dst, d);
1732 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1733 /* val.i = constant */
1735 d = reg_of_var(iptr->dst, REG_NULL);
1736 if (iptr->dst->flags & INMEMORY) {
1737 if (src->flags & INMEMORY) {
1739 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1741 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1742 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1744 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1745 i386_jcc(I386_CC_NS, a);
1746 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1747 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1748 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1749 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1751 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1752 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1757 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1758 /* val.i = constant */
1760 var_to_reg_int(s1, src, REG_ITMP1);
1761 d = reg_of_var(iptr->dst, REG_ITMP2);
1763 M_INTMOVE(s1, REG_ITMP1);
1770 CALCIMMEDIATEBYTES(a, iptr->val.i);
1773 /* TODO: optimize */
1775 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1776 i386_test_reg_reg(s1, s1);
1777 i386_jcc(I386_CC_GE, a);
1778 i386_mov_reg_reg(s1, d);
1780 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1783 /* M_INTMOVE(s1, I386_EAX); */
1785 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
1786 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
1787 /* i386_alu_reg_reg(I386_AND, iptr->val.i, I386_EAX); */
1788 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
1789 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
1790 /* M_INTMOVE(I386_EAX, d); */
1792 /* i386_alu_reg_reg(I386_XOR, d, d); */
1793 /* i386_mov_imm_reg(iptr->val.i, I386_ECX); */
1794 /* i386_shrd_reg_reg(s1, d); */
1795 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1797 store_reg_to_var_int(iptr->dst, d);
1800 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1801 /* val.l = constant */
1803 d = reg_of_var(iptr->dst, REG_NULL);
1804 if (iptr->dst->flags & INMEMORY) {
1805 if (src->flags & INMEMORY) {
1806 /* Intel algorithm -- does not work, because constant is wrong */
1807 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1808 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1810 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1811 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1812 /* i386_jcc(I386_CC_NS, offset); */
1813 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1814 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1816 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1817 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1818 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1820 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1822 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1823 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1824 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1826 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1827 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1829 /* Alpha algorithm */
1831 CALCOFFSETBYTES(a, src->regoff * 8);
1833 CALCOFFSETBYTES(a, src->regoff * 8 + 4);
1839 /* TODO: hmm, don't know if this is always correct */
1841 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1843 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1849 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1850 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1852 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1853 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1854 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1855 i386_jcc(I386_CC_GE, a);
1857 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1858 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1860 i386_neg_reg(REG_ITMP1);
1861 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1862 i386_neg_reg(REG_ITMP2);
1864 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1865 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1867 i386_neg_reg(REG_ITMP1);
1868 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1869 i386_neg_reg(REG_ITMP2);
1871 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1872 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1877 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1879 d = reg_of_var(iptr->dst, REG_NULL);
1880 i386_emit_ishift(I386_SHL, src, iptr);
1883 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1884 /* val.i = constant */
1886 d = reg_of_var(iptr->dst, REG_NULL);
1887 i386_emit_ishiftconst(I386_SHL, src, iptr);
1890 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1892 d = reg_of_var(iptr->dst, REG_NULL);
1893 i386_emit_ishift(I386_SAR, src, iptr);
1896 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1897 /* val.i = constant */
1899 d = reg_of_var(iptr->dst, REG_NULL);
1900 i386_emit_ishiftconst(I386_SAR, src, iptr);
1903 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1905 d = reg_of_var(iptr->dst, REG_NULL);
1906 i386_emit_ishift(I386_SHR, src, iptr);
1909 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1910 /* val.i = constant */
1912 d = reg_of_var(iptr->dst, REG_NULL);
1913 i386_emit_ishiftconst(I386_SHR, src, iptr);
1916 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1918 d = reg_of_var(iptr->dst, REG_NULL);
1919 if (iptr->dst->flags & INMEMORY ){
1920 if (src->prev->flags & INMEMORY) {
1921 /* if (src->prev->regoff == iptr->dst->regoff) { */
1922 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1924 /* if (src->flags & INMEMORY) { */
1925 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
1927 /* M_INTMOVE(src->regoff, I386_ECX); */
1930 /* i386_test_imm_reg(32, I386_ECX); */
1931 /* i386_jcc(I386_CC_E, 2 + 2); */
1932 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1933 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1935 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1936 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1939 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1940 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1942 if (src->flags & INMEMORY) {
1943 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1945 M_INTMOVE(src->regoff, I386_ECX);
1948 i386_test_imm_reg(32, I386_ECX);
1949 i386_jcc(I386_CC_E, 2 + 2);
1950 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
1951 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1953 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
1954 i386_shift_reg(I386_SHL, REG_ITMP1);
1955 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1956 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1962 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1963 /* val.i = constant */
1965 d = reg_of_var(iptr->dst, REG_NULL);
1966 if (iptr->dst->flags & INMEMORY ) {
1967 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1968 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1970 if (iptr->val.i & 0x20) {
1971 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
1972 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1973 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1976 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1977 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
1980 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1981 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1985 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1987 d = reg_of_var(iptr->dst, REG_NULL);
1988 if (iptr->dst->flags & INMEMORY ){
1989 if (src->prev->flags & INMEMORY) {
1990 /* if (src->prev->regoff == iptr->dst->regoff) { */
1991 /* TODO: optimize */
1992 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1993 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1995 /* if (src->flags & INMEMORY) { */
1996 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
1998 /* M_INTMOVE(src->regoff, I386_ECX); */
2001 /* i386_test_imm_reg(32, I386_ECX); */
2002 /* i386_jcc(I386_CC_E, 2 + 3); */
2003 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2004 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2006 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2007 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2008 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2009 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2012 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2013 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2015 if (src->flags & INMEMORY) {
2016 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2018 M_INTMOVE(src->regoff, I386_ECX);
2021 i386_test_imm_reg(32, I386_ECX);
2022 i386_jcc(I386_CC_E, 2 + 3);
2023 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2024 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2026 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2027 i386_shift_reg(I386_SAR, REG_ITMP2);
2028 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2029 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2035 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2036 /* val.i = constant */
2038 d = reg_of_var(iptr->dst, REG_NULL);
2039 if (iptr->dst->flags & INMEMORY ) {
2040 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2041 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2043 if (iptr->val.i & 0x20) {
2044 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2045 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2046 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2049 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2050 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2053 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2054 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2058 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2060 d = reg_of_var(iptr->dst, REG_NULL);
2061 if (iptr->dst->flags & INMEMORY ){
2062 if (src->prev->flags & INMEMORY) {
2063 /* if (src->prev->regoff == iptr->dst->regoff) { */
2064 /* TODO: optimize */
2065 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2066 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2068 /* if (src->flags & INMEMORY) { */
2069 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2071 /* M_INTMOVE(src->regoff, I386_ECX); */
2074 /* i386_test_imm_reg(32, I386_ECX); */
2075 /* i386_jcc(I386_CC_E, 2 + 2); */
2076 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2077 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2079 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2080 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2081 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2082 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2085 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2086 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2088 if (src->flags & INMEMORY) {
2089 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2091 M_INTMOVE(src->regoff, I386_ECX);
2094 i386_test_imm_reg(32, I386_ECX);
2095 i386_jcc(I386_CC_E, 2 + 2);
2096 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2097 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2099 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2100 i386_shift_reg(I386_SHR, REG_ITMP2);
2101 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2102 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2108 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2109 /* val.l = constant */
2111 d = reg_of_var(iptr->dst, REG_NULL);
2112 if (iptr->dst->flags & INMEMORY ) {
2113 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2114 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2116 if (iptr->val.i & 0x20) {
2117 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2118 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2119 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2122 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2123 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2126 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2127 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2131 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2133 d = reg_of_var(iptr->dst, REG_NULL);
2134 i386_emit_ialu(I386_AND, src, iptr);
2137 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2138 /* val.i = constant */
2140 d = reg_of_var(iptr->dst, REG_NULL);
2141 i386_emit_ialuconst(I386_AND, src, iptr);
2144 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2146 d = reg_of_var(iptr->dst, REG_NULL);
2147 i386_emit_lalu(I386_AND, src, iptr);
2150 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2151 /* val.l = constant */
2153 d = reg_of_var(iptr->dst, REG_NULL);
2154 i386_emit_laluconst(I386_AND, src, iptr);
2157 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2159 d = reg_of_var(iptr->dst, REG_NULL);
2160 i386_emit_ialu(I386_OR, src, iptr);
2163 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2164 /* val.i = constant */
2166 d = reg_of_var(iptr->dst, REG_NULL);
2167 i386_emit_ialuconst(I386_OR, src, iptr);
2170 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2172 d = reg_of_var(iptr->dst, REG_NULL);
2173 i386_emit_lalu(I386_OR, src, iptr);
2176 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2177 /* val.l = constant */
2179 d = reg_of_var(iptr->dst, REG_NULL);
2180 i386_emit_laluconst(I386_OR, src, iptr);
2183 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2185 d = reg_of_var(iptr->dst, REG_NULL);
2186 i386_emit_ialu(I386_XOR, src, iptr);
2189 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2190 /* val.i = constant */
2192 d = reg_of_var(iptr->dst, REG_NULL);
2193 i386_emit_ialuconst(I386_XOR, src, iptr);
2196 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2198 d = reg_of_var(iptr->dst, REG_NULL);
2199 i386_emit_lalu(I386_XOR, src, iptr);
2202 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2203 /* val.l = constant */
2205 d = reg_of_var(iptr->dst, REG_NULL);
2206 i386_emit_laluconst(I386_XOR, src, iptr);
2209 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2210 /* op1 = variable, val.i = constant */
2212 var = &(locals[iptr->op1][TYPE_INT]);
2213 if (var->flags & INMEMORY) {
2214 if (iptr->val.i == 1) {
2215 i386_inc_membase(REG_SP, var->regoff * 8);
2217 } else if (iptr->val.i == -1) {
2218 i386_dec_membase(REG_SP, var->regoff * 8);
2221 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2225 if (iptr->val.i == 1) {
2226 i386_inc_reg(var->regoff);
2228 } else if (iptr->val.i == -1) {
2229 i386_dec_reg(var->regoff);
2232 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2238 /* floating operations ************************************************/
2240 #define ROUND_TO_SINGLE \
2241 i386_fstps_membase(REG_SP, -8); \
2242 i386_flds_membase(REG_SP, -8);
2244 #define ROUND_TO_DOUBLE \
2245 i386_fstpl_membase(REG_SP, -8); \
2246 i386_fldl_membase(REG_SP, -8);
2248 #define FPU_SET_24BIT_MODE \
2249 if (!fpu_in_24bit_mode) { \
2250 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2251 fpu_in_24bit_mode = 1; \
2254 #define FPU_SET_53BIT_MODE \
2255 if (fpu_in_24bit_mode) { \
2256 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2257 fpu_in_24bit_mode = 0; \
2260 #define ROUND_TO_SINGLE
2261 #define ROUND_TO_DOUBLE
2262 #define FPU_SET_24BIT_MODE
2263 #define FPU_SET_53BIT_MODE
2265 case ICMD_FNEG: /* ..., value ==> ..., - value */
2268 var_to_reg_flt(s1, src, REG_FTMP1);
2269 d = reg_of_var(iptr->dst, REG_FTMP3);
2271 store_reg_to_var_flt(iptr->dst, d);
2274 case ICMD_DNEG: /* ..., value ==> ..., - value */
2277 var_to_reg_flt(s1, src, REG_FTMP1);
2278 d = reg_of_var(iptr->dst, REG_FTMP3);
2280 store_reg_to_var_flt(iptr->dst, d);
2283 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2286 d = reg_of_var(iptr->dst, REG_FTMP3);
2287 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2288 var_to_reg_flt(s2, src, REG_FTMP2);
2291 store_reg_to_var_flt(iptr->dst, d);
2294 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2297 d = reg_of_var(iptr->dst, REG_FTMP3);
2298 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2299 var_to_reg_flt(s2, src, REG_FTMP2);
2302 store_reg_to_var_flt(iptr->dst, d);
2305 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2308 d = reg_of_var(iptr->dst, REG_FTMP3);
2309 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2310 var_to_reg_flt(s2, src, REG_FTMP2);
2313 store_reg_to_var_flt(iptr->dst, d);
2316 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2319 d = reg_of_var(iptr->dst, REG_FTMP3);
2320 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2321 var_to_reg_flt(s2, src, REG_FTMP2);
2324 store_reg_to_var_flt(iptr->dst, d);
2327 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2330 d = reg_of_var(iptr->dst, REG_FTMP3);
2331 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2332 var_to_reg_flt(s2, src, REG_FTMP2);
2336 store_reg_to_var_flt(iptr->dst, d);
2339 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2342 d = reg_of_var(iptr->dst, REG_FTMP3);
2343 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2345 /* i386_fldt_mem(subnormal_bias1); */
2348 var_to_reg_flt(s2, src, REG_FTMP2);
2353 /* i386_fldt_mem(subnormal_bias2); */
2356 store_reg_to_var_flt(iptr->dst, d);
2359 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2362 d = reg_of_var(iptr->dst, REG_FTMP3);
2363 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2364 var_to_reg_flt(s2, src, REG_FTMP2);
2368 store_reg_to_var_flt(iptr->dst, d);
2371 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2374 d = reg_of_var(iptr->dst, REG_FTMP3);
2375 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2377 /* i386_fldt_mem(subnormal_bias1); */
2380 var_to_reg_flt(s2, src, REG_FTMP2);
2385 /* i386_fldt_mem(subnormal_bias2); */
2388 store_reg_to_var_flt(iptr->dst, d);
2391 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2394 /* exchanged to skip fxch */
2395 var_to_reg_flt(s2, src, REG_FTMP2);
2396 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2397 d = reg_of_var(iptr->dst, REG_FTMP3);
2403 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2404 store_reg_to_var_flt(iptr->dst, d);
2410 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2413 /* exchanged to skip fxch */
2414 var_to_reg_flt(s2, src, REG_FTMP2);
2415 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2416 d = reg_of_var(iptr->dst, REG_FTMP3);
2422 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2423 store_reg_to_var_flt(iptr->dst, d);
2429 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2430 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2432 d = reg_of_var(iptr->dst, REG_FTMP1);
2433 if (src->flags & INMEMORY) {
2434 i386_fildl_membase(REG_SP, src->regoff * 8);
2439 i386_mov_imm_reg(0, REG_ITMP1);
2440 dseg_adddata(mcodeptr);
2441 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2442 i386_fildl_membase(REG_ITMP1, a);
2445 store_reg_to_var_flt(iptr->dst, d);
2448 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2449 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2451 d = reg_of_var(iptr->dst, REG_FTMP1);
2452 if (src->flags & INMEMORY) {
2453 i386_fildll_membase(REG_SP, src->regoff * 8);
2457 panic("L2F: longs have to be in memory");
2459 store_reg_to_var_flt(iptr->dst, d);
2462 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2464 var_to_reg_flt(s1, src, REG_FTMP1);
2465 d = reg_of_var(iptr->dst, REG_ITMP1);
2467 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2468 i386_mov_imm_reg(0, REG_ITMP1);
2469 dseg_adddata(mcodeptr);
2470 i386_fldcw_membase(REG_ITMP1, a);
2472 if (iptr->dst->flags & INMEMORY) {
2473 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2476 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2477 i386_fldcw_membase(REG_ITMP1, a);
2479 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2482 CALCOFFSETBYTES(a, src->regoff * 8);
2484 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2488 i386_fistpl_membase(REG_ITMP1, a);
2490 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2492 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2493 i386_fldcw_membase(REG_ITMP1, a);
2495 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2498 CALCOFFSETBYTES(a, src->regoff * 8);
2499 a += 5 + 2 + ((REG_RESULT == d) ? 0 : 2);
2502 i386_jcc(I386_CC_NE, a);
2504 /* XXX: change this when we use registers */
2505 i386_flds_membase(REG_SP, src->regoff * 8);
2506 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP2);
2507 i386_call_reg(REG_ITMP2);
2509 if (iptr->dst->flags & INMEMORY) {
2510 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2513 M_INTMOVE(REG_RESULT, d);
2517 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2519 var_to_reg_flt(s1, src, REG_FTMP1);
2520 d = reg_of_var(iptr->dst, REG_ITMP1);
2522 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2523 i386_mov_imm_reg(0, REG_ITMP1);
2524 dseg_adddata(mcodeptr);
2525 i386_fldcw_membase(REG_ITMP1, a);
2527 if (iptr->dst->flags & INMEMORY) {
2528 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2531 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2532 i386_fldcw_membase(REG_ITMP1, a);
2534 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2537 CALCOFFSETBYTES(a, src->regoff * 8);
2539 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2543 i386_fistpl_membase(REG_ITMP1, a);
2545 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2547 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2548 i386_fldcw_membase(REG_ITMP1, a);
2550 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2553 CALCOFFSETBYTES(a, src->regoff * 8);
2554 a += 5 + 2 + ((REG_RESULT == d) ? 0 : 2);
2557 i386_jcc(I386_CC_NE, a);
2559 /* XXX: change this when we use registers */
2560 i386_fldl_membase(REG_SP, src->regoff * 8);
2561 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP2);
2562 i386_call_reg(REG_ITMP2);
2564 if (iptr->dst->flags & INMEMORY) {
2565 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2567 M_INTMOVE(REG_RESULT, d);
2571 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2573 var_to_reg_flt(s1, src, REG_FTMP1);
2574 d = reg_of_var(iptr->dst, REG_ITMP1);
2576 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2577 i386_mov_imm_reg(0, REG_ITMP1);
2578 dseg_adddata(mcodeptr);
2579 i386_fldcw_membase(REG_ITMP1, a);
2581 if (iptr->dst->flags & INMEMORY) {
2582 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2585 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2586 i386_fldcw_membase(REG_ITMP1, a);
2588 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2591 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2593 CALCOFFSETBYTES(a, src->regoff * 8);
2596 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2598 CALCOFFSETBYTES(a, iptr->dst->regoff * 8 + 4);
2600 i386_jcc(I386_CC_NE, a);
2602 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2605 CALCOFFSETBYTES(a, src->regoff * 8);
2607 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2609 i386_jcc(I386_CC_NE, a);
2611 /* XXX: change this when we use registers */
2612 i386_flds_membase(REG_SP, src->regoff * 8);
2613 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP2);
2614 i386_call_reg(REG_ITMP2);
2615 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2616 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2619 panic("F2L: longs have to be in memory");
2623 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2625 var_to_reg_flt(s1, src, REG_FTMP1);
2626 d = reg_of_var(iptr->dst, REG_ITMP1);
2628 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2629 i386_mov_imm_reg(0, REG_ITMP1);
2630 dseg_adddata(mcodeptr);
2631 i386_fldcw_membase(REG_ITMP1, a);
2633 if (iptr->dst->flags & INMEMORY) {
2634 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2637 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2638 i386_fldcw_membase(REG_ITMP1, a);
2640 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2643 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2645 CALCOFFSETBYTES(a, src->regoff * 8);
2648 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2650 CALCOFFSETBYTES(a, iptr->dst->regoff * 8 + 4);
2652 i386_jcc(I386_CC_NE, a);
2654 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2657 CALCOFFSETBYTES(a, src->regoff * 8);
2659 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2661 i386_jcc(I386_CC_NE, a);
2663 /* XXX: change this when we use registers */
2664 i386_fldl_membase(REG_SP, src->regoff * 8);
2665 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP2);
2666 i386_call_reg(REG_ITMP2);
2667 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2668 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2671 panic("D2L: longs have to be in memory");
2675 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2677 var_to_reg_flt(s1, src, REG_FTMP1);
2678 d = reg_of_var(iptr->dst, REG_FTMP3);
2680 store_reg_to_var_flt(iptr->dst, d);
2683 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2685 var_to_reg_flt(s1, src, REG_FTMP1);
2686 d = reg_of_var(iptr->dst, REG_FTMP3);
2688 store_reg_to_var_flt(iptr->dst, d);
2691 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2694 /* exchanged to skip fxch */
2695 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2696 var_to_reg_flt(s1, src, REG_FTMP2);
2697 d = reg_of_var(iptr->dst, REG_ITMP2);
2698 i386_alu_reg_reg(I386_XOR, d, d);
2703 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as GT */
2704 i386_jcc(I386_CC_E, 6);
2705 i386_alu_imm_reg(I386_AND, 0x000000ff, I386_EAX);
2707 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2708 i386_jcc(I386_CC_B, 1 + 5);
2712 store_reg_to_var_int(iptr->dst, d);
2715 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2718 /* exchanged to skip fxch */
2719 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2720 var_to_reg_flt(s1, src, REG_FTMP2);
2721 d = reg_of_var(iptr->dst, REG_ITMP2);
2722 i386_alu_reg_reg(I386_XOR, d, d);
2727 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as LT */
2728 i386_jcc(I386_CC_E, 3);
2729 i386_movb_imm_reg(1, I386_AH);
2731 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2732 i386_jcc(I386_CC_B, 1 + 5);
2736 store_reg_to_var_int(iptr->dst, d);
2740 /* memory operations **************************************************/
2742 #define gen_bound_check \
2743 if (checkbounds) { \
2744 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2745 i386_jcc(I386_CC_AE, 0); \
2746 codegen_addxboundrefs(mcodeptr); \
2749 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2751 var_to_reg_int(s1, src, REG_ITMP1);
2752 d = reg_of_var(iptr->dst, REG_ITMP2);
2753 gen_nullptr_check(s1);
2754 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2755 store_reg_to_var_int(iptr->dst, d);
2758 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2760 var_to_reg_int(s1, src->prev, REG_ITMP1);
2761 var_to_reg_int(s2, src, REG_ITMP2);
2762 d = reg_of_var(iptr->dst, REG_ITMP1);
2763 if (iptr->op1 == 0) {
2764 gen_nullptr_check(s1);
2767 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2768 store_reg_to_var_int(iptr->dst, d);
2771 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2773 var_to_reg_int(s1, src->prev, REG_ITMP1);
2774 var_to_reg_int(s2, src, REG_ITMP2);
2775 d = reg_of_var(iptr->dst, REG_ITMP3);
2776 if (iptr->op1 == 0) {
2777 gen_nullptr_check(s1);
2781 if (iptr->dst->flags & INMEMORY) {
2782 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2783 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2784 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2785 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2789 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2791 var_to_reg_int(s1, src->prev, REG_ITMP1);
2792 var_to_reg_int(s2, src, REG_ITMP2);
2793 d = reg_of_var(iptr->dst, REG_ITMP1);
2794 if (iptr->op1 == 0) {
2795 gen_nullptr_check(s1);
2798 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2799 store_reg_to_var_int(iptr->dst, d);
2802 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2804 var_to_reg_int(s1, src->prev, REG_ITMP1);
2805 var_to_reg_int(s2, src, REG_ITMP2);
2806 d = reg_of_var(iptr->dst, REG_FTMP1);
2807 if (iptr->op1 == 0) {
2808 gen_nullptr_check(s1);
2811 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2813 store_reg_to_var_flt(iptr->dst, d);
2816 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2818 var_to_reg_int(s1, src->prev, REG_ITMP1);
2819 var_to_reg_int(s2, src, REG_ITMP2);
2820 d = reg_of_var(iptr->dst, REG_FTMP3);
2821 if (iptr->op1 == 0) {
2822 gen_nullptr_check(s1);
2825 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2827 store_reg_to_var_flt(iptr->dst, d);
2830 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2832 var_to_reg_int(s1, src->prev, REG_ITMP1);
2833 var_to_reg_int(s2, src, REG_ITMP2);
2834 d = reg_of_var(iptr->dst, REG_ITMP1);
2835 if (iptr->op1 == 0) {
2836 gen_nullptr_check(s1);
2839 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2840 store_reg_to_var_int(iptr->dst, d);
2843 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2845 var_to_reg_int(s1, src->prev, REG_ITMP1);
2846 var_to_reg_int(s2, src, REG_ITMP2);
2847 d = reg_of_var(iptr->dst, REG_ITMP1);
2848 if (iptr->op1 == 0) {
2849 gen_nullptr_check(s1);
2852 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2853 store_reg_to_var_int(iptr->dst, d);
2856 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2858 var_to_reg_int(s1, src->prev, REG_ITMP1);
2859 var_to_reg_int(s2, src, REG_ITMP2);
2860 d = reg_of_var(iptr->dst, REG_ITMP1);
2861 if (iptr->op1 == 0) {
2862 gen_nullptr_check(s1);
2865 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2866 store_reg_to_var_int(iptr->dst, d);
2870 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2872 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2873 var_to_reg_int(s2, src->prev, REG_ITMP2);
2874 if (iptr->op1 == 0) {
2875 gen_nullptr_check(s1);
2878 var_to_reg_int(s3, src, REG_ITMP3);
2879 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2882 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2884 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2885 var_to_reg_int(s2, src->prev, REG_ITMP2);
2886 if (iptr->op1 == 0) {
2887 gen_nullptr_check(s1);
2891 if (src->flags & INMEMORY) {
2892 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2893 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2894 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2895 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2899 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2901 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2902 var_to_reg_int(s2, src->prev, REG_ITMP2);
2903 if (iptr->op1 == 0) {
2904 gen_nullptr_check(s1);
2907 var_to_reg_int(s3, src, REG_ITMP3);
2908 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2911 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2913 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2914 var_to_reg_int(s2, src->prev, REG_ITMP2);
2915 if (iptr->op1 == 0) {
2916 gen_nullptr_check(s1);
2919 var_to_reg_flt(s3, src, REG_FTMP1);
2920 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2924 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2926 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2927 var_to_reg_int(s2, src->prev, REG_ITMP2);
2928 if (iptr->op1 == 0) {
2929 gen_nullptr_check(s1);
2932 var_to_reg_flt(s3, src, REG_FTMP1);
2933 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2937 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2939 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2940 var_to_reg_int(s2, src->prev, REG_ITMP2);
2941 if (iptr->op1 == 0) {
2942 gen_nullptr_check(s1);
2945 var_to_reg_int(s3, src, REG_ITMP3);
2946 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2949 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2951 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2952 var_to_reg_int(s2, src->prev, REG_ITMP2);
2953 if (iptr->op1 == 0) {
2954 gen_nullptr_check(s1);
2957 var_to_reg_int(s3, src, REG_ITMP3);
2958 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2961 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2963 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2964 var_to_reg_int(s2, src->prev, REG_ITMP2);
2965 if (iptr->op1 == 0) {
2966 gen_nullptr_check(s1);
2969 var_to_reg_int(s3, src, REG_ITMP3);
2970 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
2971 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2975 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2976 /* op1 = type, val.a = field address */
2978 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
2979 /* here it's slightly slower */
2980 i386_mov_imm_reg(0, REG_ITMP2);
2981 dseg_adddata(mcodeptr);
2982 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
2983 switch (iptr->op1) {
2986 var_to_reg_int(s2, src, REG_ITMP1);
2987 i386_mov_reg_membase(s2, REG_ITMP2, 0);
2990 if (src->flags & INMEMORY) {
2991 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2992 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
2993 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
2994 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
2996 panic("PUTSTATIC: longs have to be in memory");
3000 var_to_reg_flt(s2, src, REG_FTMP1);
3001 i386_fstps_membase(REG_ITMP2, 0);
3005 var_to_reg_flt(s2, src, REG_FTMP1);
3006 i386_fstpl_membase(REG_ITMP2, 0);
3009 default: panic ("internal error");
3013 case ICMD_GETSTATIC: /* ... ==> ..., value */
3014 /* op1 = type, val.a = field address */
3016 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3017 i386_mov_imm_reg(0, REG_ITMP2);
3018 dseg_adddata(mcodeptr);
3019 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3020 switch (iptr->op1) {
3023 d = reg_of_var(iptr->dst, REG_ITMP1);
3024 i386_mov_membase_reg(REG_ITMP2, 0, d);
3025 store_reg_to_var_int(iptr->dst, d);
3028 d = reg_of_var(iptr->dst, REG_NULL);
3029 if (iptr->dst->flags & INMEMORY) {
3030 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3031 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3032 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3033 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3035 panic("GETSTATIC: longs have to be in memory");
3039 d = reg_of_var(iptr->dst, REG_FTMP1);
3040 i386_flds_membase(REG_ITMP2, 0);
3042 store_reg_to_var_flt(iptr->dst, d);
3045 d = reg_of_var(iptr->dst, REG_FTMP1);
3046 i386_fldl_membase(REG_ITMP2, 0);
3048 store_reg_to_var_flt(iptr->dst, d);
3050 default: panic ("internal error");
3054 case ICMD_PUTFIELD: /* ..., value ==> ... */
3055 /* op1 = type, val.i = field offset */
3057 a = ((fieldinfo *)(iptr->val.a))->offset;
3058 switch (iptr->op1) {
3061 var_to_reg_int(s1, src->prev, REG_ITMP1);
3062 var_to_reg_int(s2, src, REG_ITMP2);
3063 gen_nullptr_check(s1);
3064 i386_mov_reg_membase(s2, s1, a);
3067 var_to_reg_int(s1, src->prev, REG_ITMP1);
3068 gen_nullptr_check(s1);
3069 if (src->flags & INMEMORY) {
3070 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3071 i386_mov_reg_membase(REG_ITMP2, s1, a);
3072 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3073 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3075 panic("PUTFIELD: longs have to be in memory");
3079 var_to_reg_int(s1, src->prev, REG_ITMP1);
3080 var_to_reg_flt(s2, src, REG_FTMP1);
3081 gen_nullptr_check(s1);
3082 i386_fstps_membase(s1, a);
3086 var_to_reg_int(s1, src->prev, REG_ITMP1);
3087 var_to_reg_flt(s2, src, REG_FTMP1);
3088 gen_nullptr_check(s1);
3089 i386_fstpl_membase(s1, a);
3092 default: panic ("internal error");
3096 case ICMD_GETFIELD: /* ... ==> ..., value */
3097 /* op1 = type, val.i = field offset */
3099 a = ((fieldinfo *)(iptr->val.a))->offset;
3100 switch (iptr->op1) {
3103 var_to_reg_int(s1, src, REG_ITMP1);
3104 d = reg_of_var(iptr->dst, REG_ITMP2);
3105 gen_nullptr_check(s1);
3106 i386_mov_membase_reg(s1, a, d);
3107 store_reg_to_var_int(iptr->dst, d);
3110 var_to_reg_int(s1, src, REG_ITMP1);
3111 d = reg_of_var(iptr->dst, REG_NULL);
3112 gen_nullptr_check(s1);
3113 i386_mov_membase_reg(s1, a, REG_ITMP2);
3114 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3115 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3116 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3119 var_to_reg_int(s1, src, REG_ITMP1);
3120 d = reg_of_var(iptr->dst, REG_FTMP1);
3121 gen_nullptr_check(s1);
3122 i386_flds_membase(s1, a);
3124 store_reg_to_var_flt(iptr->dst, d);
3127 var_to_reg_int(s1, src, REG_ITMP1);
3128 d = reg_of_var(iptr->dst, REG_FTMP1);
3129 gen_nullptr_check(s1);
3130 i386_fldl_membase(s1, a);
3132 store_reg_to_var_flt(iptr->dst, d);
3134 default: panic ("internal error");
3139 /* branch operations **************************************************/
3142 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3143 #define ALIGNCODENOP do {} while (0)
3145 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3147 var_to_reg_int(s1, src, REG_ITMP1);
3148 M_INTMOVE(s1, REG_ITMP1_XPTR);
3150 i386_call_imm(0); /* passing exception pointer */
3151 i386_pop_reg(REG_ITMP2_XPC);
3153 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
3154 i386_jmp_reg(I386_EDI);
3158 case ICMD_GOTO: /* ... ==> ... */
3159 /* op1 = target JavaVM pc */
3162 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3166 case ICMD_JSR: /* ... ==> ... */
3167 /* op1 = target JavaVM pc */
3170 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3173 case ICMD_RET: /* ... ==> ... */
3174 /* op1 = local variable */
3176 var = &(locals[iptr->op1][TYPE_ADR]);
3177 var_to_reg_int(s1, var, REG_ITMP1);
3181 case ICMD_IFNULL: /* ..., value ==> ... */
3182 /* op1 = target JavaVM pc */
3184 if (src->flags & INMEMORY) {
3185 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3188 i386_test_reg_reg(src->regoff, src->regoff);
3190 i386_jcc(I386_CC_E, 0);
3191 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3194 case ICMD_IFNONNULL: /* ..., value ==> ... */
3195 /* op1 = target JavaVM pc */
3197 if (src->flags & INMEMORY) {
3198 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3201 i386_test_reg_reg(src->regoff, src->regoff);
3203 i386_jcc(I386_CC_NE, 0);
3204 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3207 case ICMD_IFEQ: /* ..., value ==> ... */
3208 /* op1 = target JavaVM pc, val.i = constant */
3210 if (src->flags & INMEMORY) {
3211 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3214 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3216 i386_jcc(I386_CC_E, 0);
3217 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3220 case ICMD_IFLT: /* ..., value ==> ... */
3221 /* op1 = target JavaVM pc, val.i = constant */
3223 if (src->flags & INMEMORY) {
3224 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3227 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3229 i386_jcc(I386_CC_L, 0);
3230 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3233 case ICMD_IFLE: /* ..., value ==> ... */
3234 /* op1 = target JavaVM pc, val.i = constant */
3236 if (src->flags & INMEMORY) {
3237 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3240 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3242 i386_jcc(I386_CC_LE, 0);
3243 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3246 case ICMD_IFNE: /* ..., value ==> ... */
3247 /* op1 = target JavaVM pc, val.i = constant */
3249 if (src->flags & INMEMORY) {
3250 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3253 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3255 i386_jcc(I386_CC_NE, 0);
3256 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3259 case ICMD_IFGT: /* ..., value ==> ... */
3260 /* op1 = target JavaVM pc, val.i = constant */
3262 if (src->flags & INMEMORY) {
3263 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3266 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3268 i386_jcc(I386_CC_G, 0);
3269 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3272 case ICMD_IFGE: /* ..., value ==> ... */
3273 /* op1 = target JavaVM pc, val.i = constant */
3275 if (src->flags & INMEMORY) {
3276 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3279 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3281 i386_jcc(I386_CC_GE, 0);
3282 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3285 case ICMD_IF_LEQ: /* ..., value ==> ... */
3286 /* op1 = target JavaVM pc, val.l = constant */
3288 if (src->flags & INMEMORY) {
3289 if (iptr->val.l == 0) {
3290 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3291 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3293 } else if (iptr->val.l > 0 && iptr->val.l <= 0x00000000ffffffff) {
3294 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3295 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3296 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3299 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3300 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3301 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3302 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3303 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3306 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3307 i386_jcc(I386_CC_E, 0);
3308 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3311 case ICMD_IF_LLT: /* ..., value ==> ... */
3312 /* op1 = target JavaVM pc, val.l = constant */
3314 /* TODO: optimize as in IF_LEQ */
3315 if (src->flags & INMEMORY) {
3316 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3317 i386_jcc(I386_CC_L, 0);
3318 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3321 CALCREGOFFBYTES(a, src->regoff);
3322 CALCIMMEDIATEBYTES(a, iptr->val.l);
3324 i386_jcc(I386_CC_G, a);
3326 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3327 i386_jcc(I386_CC_B, 0);
3328 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3332 case ICMD_IF_LLE: /* ..., value ==> ... */
3333 /* op1 = target JavaVM pc, val.l = constant */
3335 /* TODO: optimize as in IF_LEQ */
3336 if (src->flags & INMEMORY) {
3337 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3338 i386_jcc(I386_CC_L, 0);
3339 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3342 CALCREGOFFBYTES(a, src->regoff);
3343 CALCIMMEDIATEBYTES(a, iptr->val.l);
3345 i386_jcc(I386_CC_G, a);
3347 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3348 i386_jcc(I386_CC_BE, 0);
3349 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3353 case ICMD_IF_LNE: /* ..., value ==> ... */
3354 /* op1 = target JavaVM pc, val.l = constant */
3356 /* TODO: optimize for val.l == 0 */
3357 if (src->flags & INMEMORY) {
3358 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3359 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3360 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3361 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3362 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3363 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3365 i386_jcc(I386_CC_NE, 0);
3366 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3369 case ICMD_IF_LGT: /* ..., value ==> ... */
3370 /* op1 = target JavaVM pc, val.l = constant */
3372 /* TODO: optimize as in IF_LEQ */
3373 if (src->flags & INMEMORY) {
3374 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3375 i386_jcc(I386_CC_G, 0);
3376 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3379 CALCREGOFFBYTES(a, src->regoff);
3380 CALCIMMEDIATEBYTES(a, iptr->val.l);
3382 i386_jcc(I386_CC_L, a);
3384 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3385 i386_jcc(I386_CC_A, 0);
3386 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3390 case ICMD_IF_LGE: /* ..., value ==> ... */
3391 /* op1 = target JavaVM pc, val.l = constant */
3393 /* TODO: optimize as in IF_LEQ */
3394 if (src->flags & INMEMORY) {
3395 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3396 i386_jcc(I386_CC_G, 0);
3397 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3400 CALCREGOFFBYTES(a, src->regoff);
3401 CALCIMMEDIATEBYTES(a, iptr->val.l);
3403 i386_jcc(I386_CC_L, a);
3405 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3406 i386_jcc(I386_CC_AE, 0);
3407 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3411 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3412 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3414 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3415 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3416 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3418 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3419 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3421 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3422 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3425 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3427 i386_jcc(I386_CC_E, 0);
3428 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3431 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3432 /* op1 = target JavaVM pc */
3434 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3435 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3436 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3437 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3438 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3439 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3440 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3442 i386_jcc(I386_CC_E, 0);
3443 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3446 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3447 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3449 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3450 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3451 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3453 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3454 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3456 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3457 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3460 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3462 i386_jcc(I386_CC_NE, 0);
3463 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3466 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3467 /* op1 = target JavaVM pc */
3469 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3470 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3471 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3472 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3473 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3474 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3475 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3477 i386_jcc(I386_CC_NE, 0);
3478 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3481 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3482 /* op1 = target JavaVM pc */
3484 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3485 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3486 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3488 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3489 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3491 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3492 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3495 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3497 i386_jcc(I386_CC_L, 0);
3498 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3501 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3502 /* op1 = target JavaVM pc */
3504 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3505 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3506 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3507 i386_jcc(I386_CC_L, 0);
3508 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3511 CALCREGOFFBYTES(a, src->prev->regoff);
3512 CALCREGOFFBYTES(a, src->regoff);
3514 i386_jcc(I386_CC_G, a);
3516 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3517 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3518 i386_jcc(I386_CC_B, 0);
3519 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3523 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3524 /* op1 = target JavaVM pc */
3526 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3527 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3528 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3530 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3531 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3533 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3534 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3537 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3539 i386_jcc(I386_CC_G, 0);
3540 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3543 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3544 /* op1 = target JavaVM pc */
3546 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3547 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3548 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3549 i386_jcc(I386_CC_G, 0);
3550 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3553 CALCREGOFFBYTES(a, src->prev->regoff);
3554 CALCREGOFFBYTES(a, src->regoff);
3556 i386_jcc(I386_CC_L, a);
3558 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3559 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3560 i386_jcc(I386_CC_A, 0);
3561 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3565 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3566 /* op1 = target JavaVM pc */
3568 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3569 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3570 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3572 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3573 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3575 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3576 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3579 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3581 i386_jcc(I386_CC_LE, 0);
3582 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3585 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3586 /* op1 = target JavaVM pc */
3588 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3589 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3590 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3591 i386_jcc(I386_CC_L, 0);
3592 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3595 CALCREGOFFBYTES(a, src->prev->regoff);
3596 CALCREGOFFBYTES(a, src->regoff);
3598 i386_jcc(I386_CC_G, a);
3600 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3601 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3602 i386_jcc(I386_CC_BE, 0);
3603 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3607 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3608 /* op1 = target JavaVM pc */
3610 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3611 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3612 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3614 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3615 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3617 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3618 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3621 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3623 i386_jcc(I386_CC_GE, 0);
3624 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3627 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3628 /* op1 = target JavaVM pc */
3630 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3631 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3632 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3633 i386_jcc(I386_CC_G, 0);
3634 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3637 CALCREGOFFBYTES(a, src->prev->regoff);
3638 CALCREGOFFBYTES(a, src->regoff);
3640 i386_jcc(I386_CC_L, a);
3642 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3643 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3644 i386_jcc(I386_CC_AE, 0);
3645 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3649 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3651 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3654 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3655 /* val.i = constant */
3657 d = reg_of_var(iptr->dst, REG_NULL);
3658 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3661 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3662 /* val.i = constant */
3664 d = reg_of_var(iptr->dst, REG_NULL);
3665 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3668 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3669 /* val.i = constant */
3671 d = reg_of_var(iptr->dst, REG_NULL);
3672 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3675 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3676 /* val.i = constant */
3678 d = reg_of_var(iptr->dst, REG_NULL);
3679 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3682 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3683 /* val.i = constant */
3685 d = reg_of_var(iptr->dst, REG_NULL);
3686 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3689 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3690 /* val.i = constant */
3692 d = reg_of_var(iptr->dst, REG_NULL);
3693 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3697 case ICMD_IRETURN: /* ..., 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 var_to_reg_int(s1, src, REG_RESULT);
3711 M_INTMOVE(s1, REG_RESULT);
3712 goto nowperformreturn;
3714 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3717 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3718 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3719 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3720 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3721 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3722 i386_call_reg(REG_ITMP1);
3723 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3726 if (src->flags & INMEMORY) {
3727 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3728 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3731 panic("LRETURN: longs have to be in memory");
3733 goto nowperformreturn;
3735 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3738 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3739 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3740 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3741 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3742 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3743 i386_call_reg(REG_ITMP1);
3744 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3747 var_to_reg_flt(s1, src, REG_FRESULT);
3748 /* this may be an early return -- keep the offset correct for the remaining code */
3750 goto nowperformreturn;
3752 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3755 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3756 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3757 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3758 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3759 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3760 i386_call_reg(REG_ITMP1);
3761 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3764 var_to_reg_flt(s1, src, REG_FRESULT);
3765 /* this may be an early return -- keep the offset correct for the remaining code */
3767 goto nowperformreturn;
3769 case ICMD_RETURN: /* ... ==> ... */
3772 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3773 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3774 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3775 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3776 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3777 i386_call_reg(REG_ITMP1);
3778 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3786 p = parentargs_base;
3788 /* restore saved registers */
3789 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3791 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3793 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3795 i386_fldl_membase(REG_SP, p * 8);
3797 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3798 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3800 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3805 /* deallocate stack */
3806 if (parentargs_base) {
3807 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3810 /* call trace function */
3812 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3814 i386_mov_imm_membase((s4) method, REG_SP, 0);
3816 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3817 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3819 i386_fstl_membase(REG_SP, 4 + 8);
3820 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3822 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3823 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3824 i386_call_reg(REG_ITMP1);
3826 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3827 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3829 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3838 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3843 tptr = (void **) iptr->target;
3845 s4ptr = iptr->val.a;
3846 l = s4ptr[1]; /* low */
3847 i = s4ptr[2]; /* high */
3849 var_to_reg_int(s1, src, REG_ITMP1);
3850 M_INTMOVE(s1, REG_ITMP1);
3852 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3858 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3859 i386_jcc(I386_CC_A, 0);
3861 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3862 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3864 /* build jump table top down and use address of lowest entry */
3866 /* s4ptr += 3 + i; */
3870 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3871 dseg_addtarget((basicblock *) tptr[0]);
3875 /* length of dataseg after last dseg_addtarget is used by load */
3877 i386_mov_imm_reg(0, REG_ITMP2);
3878 dseg_adddata(mcodeptr);
3879 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3880 i386_jmp_reg(REG_ITMP1);
3886 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3888 s4 i, l, val, *s4ptr;
3891 tptr = (void **) iptr->target;
3893 s4ptr = iptr->val.a;
3894 l = s4ptr[0]; /* default */
3895 i = s4ptr[1]; /* count */
3897 MCODECHECK((i<<2)+8);
3898 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3904 i386_alu_imm_reg(I386_CMP, val, s1);
3905 i386_jcc(I386_CC_E, 0);
3906 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3907 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3911 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3913 tptr = (void **) iptr->target;
3914 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3921 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3922 /* op1 = return type, val.a = function pointer*/
3926 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3927 /* op1 = return type, val.a = function pointer*/
3931 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3932 /* op1 = return type, val.a = function pointer*/
3936 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3937 /* op1 = arg count, val.a = method pointer */
3939 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3940 /* op1 = arg count, val.a = method pointer */
3942 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3943 /* op1 = arg count, val.a = method pointer */
3945 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3946 /* op1 = arg count, val.a = method pointer */
3954 MCODECHECK((s3 << 1) + 64);
3956 /* copy arguments to registers or stack location */
3958 for (; --s3 >= 0; src = src->prev) {
3959 if (src->varkind == ARGVAR) {
3963 if (IS_INT_LNG_TYPE(src->type)) {
3964 if (s3 < intreg_argnum) {
3965 panic("No integer argument registers available!");
3968 if (!IS_2_WORD_TYPE(src->type)) {
3969 if (src->flags & INMEMORY) {
3970 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3971 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
3974 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
3978 if (src->flags & INMEMORY) {
3979 M_LNGMEMMOVE(src->regoff, s3);
3982 panic("copy arguments: longs have to be in memory");
3988 if (s3 < fltreg_argnum) {
3989 panic("No float argument registers available!");
3992 var_to_reg_flt(d, src, REG_FTMP1);
3993 if (src->type == TYPE_FLT) {
3994 i386_fstps_membase(REG_SP, s3 * 8);
3997 i386_fstpl_membase(REG_SP, s3 * 8);
4004 switch (iptr->opc) {
4012 i386_mov_imm_reg(a, REG_ITMP1);
4013 i386_call_reg(REG_ITMP1);
4016 case ICMD_INVOKESTATIC:
4018 a = (s4) m->stubroutine;
4021 i386_mov_imm_reg(a, REG_ITMP2);
4022 i386_call_reg(REG_ITMP2);
4025 case ICMD_INVOKESPECIAL:
4027 a = (s4) m->stubroutine;
4030 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4031 gen_nullptr_check(REG_ITMP1);
4032 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4034 i386_mov_imm_reg(a, REG_ITMP2);
4035 i386_call_reg(REG_ITMP2);
4038 case ICMD_INVOKEVIRTUAL:
4042 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4043 gen_nullptr_check(REG_ITMP1);
4044 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4045 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4047 i386_call_reg(REG_ITMP1);
4050 case ICMD_INVOKEINTERFACE:
4055 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4056 gen_nullptr_check(REG_ITMP1);
4057 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4058 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4059 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4061 i386_call_reg(REG_ITMP1);
4066 sprintf(logtext, "Unkown ICMD-Command: %d", iptr->opc);
4070 /* d contains return type */
4072 if (d != TYPE_VOID) {
4073 d = reg_of_var(iptr->dst, REG_NULL);
4075 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4076 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4077 if (iptr->dst->flags & INMEMORY) {
4078 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4079 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4082 panic("RETURN: longs have to be in memory");
4086 if (iptr->dst->flags & INMEMORY) {
4087 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4090 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4095 /* fld from called function -- has other fpu_st_offset counter */
4097 store_reg_to_var_flt(iptr->dst, d);
4104 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4106 /* op1: 0 == array, 1 == class */
4107 /* val.a: (classinfo*) superclass */
4109 /* superclass is an interface:
4111 * return (sub != NULL) &&
4112 * (sub->vftbl->interfacetablelength > super->index) &&
4113 * (sub->vftbl->interfacetable[-super->index] != NULL);
4115 * superclass is a class:
4117 * return ((sub != NULL) && (0
4118 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4119 * super->vftbl->diffvall));
4123 classinfo *super = (classinfo*) iptr->val.a;
4125 var_to_reg_int(s1, src, REG_ITMP1);
4126 d = reg_of_var(iptr->dst, REG_ITMP3);
4128 M_INTMOVE(s1, REG_ITMP1);
4131 i386_alu_reg_reg(I386_XOR, d, d);
4132 if (iptr->op1) { /* class/interface */
4133 if (super->flags & ACC_INTERFACE) { /* interface */
4134 i386_test_reg_reg(s1, s1);
4136 /* TODO: clean up this calculation */
4138 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4141 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4144 CALCOFFSETBYTES(a, super->index);
4150 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4157 i386_jcc(I386_CC_E, a);
4159 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4160 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4161 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4163 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4165 /* TODO: clean up this calculation */
4168 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4175 i386_jcc(I386_CC_LE, a);
4176 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4178 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4179 /* i386_setcc_reg(I386_CC_A, d); */
4180 /* i386_jcc(I386_CC_BE, 5); */
4181 i386_jcc(I386_CC_E, 5);
4182 i386_mov_imm_reg(1, d);
4185 } else { /* class */
4186 i386_test_reg_reg(s1, s1);
4188 /* TODO: clean up this calculation */
4190 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4193 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4195 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4198 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4208 i386_jcc(I386_CC_E, a);
4210 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4211 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4212 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4213 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4214 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4215 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4216 i386_alu_reg_reg(I386_XOR, d, d);
4217 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4218 i386_jcc(I386_CC_A, 5);
4219 i386_mov_imm_reg(1, d);
4223 panic ("internal error: no inlined array instanceof");
4225 store_reg_to_var_int(iptr->dst, d);
4228 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4230 /* op1: 0 == array, 1 == class */
4231 /* val.a: (classinfo*) superclass */
4233 /* superclass is an interface:
4235 * OK if ((sub == NULL) ||
4236 * (sub->vftbl->interfacetablelength > super->index) &&
4237 * (sub->vftbl->interfacetable[-super->index] != NULL));
4239 * superclass is a class:
4241 * OK if ((sub == NULL) || (0
4242 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4243 * super->vftbl->diffvall));
4247 classinfo *super = (classinfo*) iptr->val.a;
4249 d = reg_of_var(iptr->dst, REG_ITMP3);
4250 var_to_reg_int(s1, src, d);
4251 if (iptr->op1) { /* class/interface */
4252 if (super->flags & ACC_INTERFACE) { /* interface */
4253 i386_test_reg_reg(s1, s1);
4255 /* TODO: clean up this calculation */
4257 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4260 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4263 CALCOFFSETBYTES(a, super->index);
4269 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4274 i386_jcc(I386_CC_E, a);
4276 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4277 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4278 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4280 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4281 i386_jcc(I386_CC_LE, 0);
4282 codegen_addxcastrefs(mcodeptr);
4283 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4285 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4286 i386_jcc(I386_CC_E, 0);
4287 codegen_addxcastrefs(mcodeptr);
4289 } else { /* class */
4290 i386_test_reg_reg(s1, s1);
4292 /* TODO: clean up this calculation */
4294 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4299 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4301 if (d != REG_ITMP3) {
4303 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4306 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4312 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4319 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4326 i386_jcc(I386_CC_E, a);
4328 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4329 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4330 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4331 if (d != REG_ITMP3) {
4332 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4333 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4334 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4337 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4338 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4339 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4340 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4342 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4343 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4344 codegen_addxcastrefs(mcodeptr);
4348 panic ("internal error: no inlined array checkcast");
4351 store_reg_to_var_int(iptr->dst, d);
4354 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4356 if (src->flags & INMEMORY) {
4357 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4360 i386_test_reg_reg(src->regoff, src->regoff);
4362 i386_jcc(I386_CC_L, 0);
4363 codegen_addxcheckarefs(mcodeptr);
4366 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4367 /* op1 = dimension, val.a = array descriptor */
4369 /* check for negative sizes and copy sizes to stack if necessary */
4371 MCODECHECK((iptr->op1 << 1) + 64);
4373 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4374 if (src->flags & INMEMORY) {
4375 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4378 i386_test_reg_reg(src->regoff, src->regoff);
4380 i386_jcc(I386_CC_L, 0);
4381 codegen_addxcheckarefs(mcodeptr);
4384 * copy sizes to new stack location, be cause native function
4385 * builtin_nmultianewarray access them as (int *)
4387 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4388 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4390 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4392 if (src->varkind != ARGVAR) {
4393 if (src->flags & INMEMORY) {
4394 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4395 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4398 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4402 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4404 /* a0 = dimension count */
4406 /* save stack pointer */
4407 M_INTMOVE(REG_SP, REG_ITMP1);
4409 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4410 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4412 /* a1 = arraydescriptor */
4414 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4416 /* a2 = pointer to dimensions = stack pointer */
4418 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4420 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4421 i386_call_reg(REG_ITMP1);
4422 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4424 s1 = reg_of_var(iptr->dst, REG_RESULT);
4425 M_INTMOVE(REG_RESULT, s1);
4426 store_reg_to_var_int(iptr->dst, s1);
4430 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
4437 } /* for instruction */
4439 /* copy values to interface registers */
4441 src = bptr->outstack;
4442 len = bptr->outdepth;
4446 if ((src->varkind != STACKVAR)) {
4448 if (IS_FLT_DBL_TYPE(s2)) {
4449 var_to_reg_flt(s1, src, REG_FTMP1);
4450 if (!(interfaces[len][s2].flags & INMEMORY)) {
4451 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4454 panic("double store");
4455 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4459 var_to_reg_int(s1, src, REG_ITMP1);
4460 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4461 if (!(interfaces[len][s2].flags & INMEMORY)) {
4462 M_INTMOVE(s1, interfaces[len][s2].regoff);
4465 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4469 if (interfaces[len][s2].flags & INMEMORY) {
4470 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4473 panic("copy interface registers: longs have to be in memory (end)");
4480 } /* if (bptr -> flags >= BBREACHED) */
4481 } /* for basic block */
4483 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4487 /* generate bound check stubs */
4488 u1 *xcodeptr = NULL;
4490 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4491 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4492 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4493 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4498 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4499 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4503 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4504 dseg_adddata(mcodeptr);
4505 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4506 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4508 if (xcodeptr != NULL) {
4509 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4512 xcodeptr = mcodeptr;
4514 i386_mov_imm_reg((s4) proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
4515 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4516 i386_jmp_reg(I386_EDI);
4520 /* generate negative array size check stubs */
4523 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4524 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4525 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4526 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4530 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4531 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4535 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4536 dseg_adddata(mcodeptr);
4537 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4538 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4540 if (xcodeptr != NULL) {
4541 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4544 xcodeptr = mcodeptr;
4546 i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
4547 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4548 i386_jmp_reg(I386_EDI);
4552 /* generate cast check stubs */
4555 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4556 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4557 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4558 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4562 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4563 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4567 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4568 dseg_adddata(mcodeptr);
4569 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4570 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4572 if (xcodeptr != NULL) {
4573 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4576 xcodeptr = mcodeptr;
4578 i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
4579 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4580 i386_jmp_reg(I386_EDI);
4584 /* generate divide by zero check stubs */
4587 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4588 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4589 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4590 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4594 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4595 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4599 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4600 dseg_adddata(mcodeptr);
4601 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4602 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4604 if (xcodeptr != NULL) {
4605 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4608 xcodeptr = mcodeptr;
4610 i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
4611 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4612 i386_jmp_reg(I386_EDI);
4616 /* generate null pointer check stubs */
4619 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4620 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4621 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4622 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4626 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4627 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4631 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4632 dseg_adddata(mcodeptr);
4633 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4634 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4636 if (xcodeptr != NULL) {
4637 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4640 xcodeptr = mcodeptr;
4642 i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
4643 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4644 i386_jmp_reg(I386_EDI);
4649 codegen_finish((int)((u1*) mcodeptr - mcodebase));
4653 /* function createcompilerstub *************************************************
4655 creates a stub routine which calls the compiler
4657 *******************************************************************************/
4659 #define COMPSTUBSIZE 12
4661 u1 *createcompilerstub(methodinfo *m)
4663 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4664 mcodeptr = s; /* code generation pointer */
4666 /* code for the stub */
4667 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4669 /* we use EDI cause EDX (REG_ITMP2) is used for patching */
4670 i386_mov_imm_reg((s4) asm_call_jit_compiler, I386_EDI); /* load address */
4671 i386_jmp_reg(I386_EDI); /* jump to compiler */
4674 count_cstub_len += COMPSTUBSIZE;
4681 /* function removecompilerstub *************************************************
4683 deletes a compilerstub from memory (simply by freeing it)
4685 *******************************************************************************/
4687 void removecompilerstub(u1 *stub)
4689 CFREE(stub, COMPSTUBSIZE);
4692 /* function: createnativestub **************************************************
4694 creates a stub routine which calls a native method
4696 *******************************************************************************/
4698 #define NATIVESTUBSIZE 320
4700 u1 *createnativestub(functionptr f, methodinfo *m)
4702 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4706 int stackframesize = 4; /* initial 4 bytes is space for jni env */
4707 int stackframeoffset = 4;
4711 mcodeptr = s; /* make macros work */
4715 descriptor2types(m); /* set paramcount and paramtypes */
4718 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4720 for (p = 0; p < m->paramcount; p++) {
4721 t = m->paramtypes[p];
4722 if (IS_INT_LNG_TYPE(t)) {
4723 if (IS_2_WORD_TYPE(t)) {
4724 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4725 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4727 } else if (t == TYPE_ADR) {
4728 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4729 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4732 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4735 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4736 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4739 if (t == TYPE_FLT) {
4740 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4741 i386_fstps_membase(REG_SP, p * 8);
4742 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4743 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4746 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4747 i386_fstpl_membase(REG_SP, p * 8);
4753 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4754 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4755 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4756 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4759 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4761 i386_mov_imm_reg((s4) asm_builtin_trace, REG_ITMP1);
4762 i386_call_reg(REG_ITMP1);
4764 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4768 * mark the whole fpu stack as free for native functions
4769 * (only for saved register count == 0)
4781 * calculate stackframe size for native function
4783 tptr = m->paramtypes;
4784 for (i = 0; i < m->paramcount; i++) {
4789 stackframesize += 4;
4794 stackframesize += 8;
4798 panic("unknown parameter type in native function");
4802 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4804 tptr = m->paramtypes;
4805 for (i = 0; i < m->paramcount; i++) {
4810 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4811 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4812 stackframeoffset += 4;
4817 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4818 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
4819 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4820 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
4821 stackframeoffset += 8;
4825 panic("unknown parameter type in native function");
4829 i386_mov_imm_membase((s4) &env, REG_SP, 0);
4830 i386_mov_imm_reg((s4) f, REG_ITMP1);
4831 i386_call_reg(REG_ITMP1);
4832 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
4835 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4837 i386_mov_imm_membase((s4) m, REG_SP, 0);
4839 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4840 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4842 i386_fstl_membase(REG_SP, 4 + 8);
4843 i386_fsts_membase(REG_SP, 4 + 8 + 8);
4845 i386_mov_imm_reg((s4) asm_builtin_exittrace, REG_ITMP1);
4846 i386_call_reg(REG_ITMP1);
4848 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4849 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4851 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4854 /* we can use EDI cause it's not preserved across function calls */
4855 i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4856 i386_mov_membase_reg(I386_EDI, 0, I386_EDI);
4857 i386_test_reg_reg(I386_EDI, I386_EDI);
4858 i386_jcc(I386_CC_NE, 1);
4862 i386_mov_reg_reg(I386_EDI, REG_ITMP1_XPTR);
4863 i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4864 i386_mov_imm_membase(0, I386_EDI, 0);
4865 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
4866 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
4868 i386_mov_imm_reg((s4) asm_handle_nat_exception, I386_EDI);
4869 i386_jmp_reg(I386_EDI);
4872 count_nstub_len += NATIVESTUBSIZE;
4878 /* function: removenativestub **************************************************
4880 removes a previously created native-stub from memory
4882 *******************************************************************************/
4884 void removenativestub(u1 *stub)
4886 CFREE(stub, NATIVESTUBSIZE);
4891 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
4893 if (iptr->dst->flags & INMEMORY) {
4894 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4895 if (src->regoff == iptr->dst->regoff) {
4896 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4897 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4899 } else if (src->prev->regoff == iptr->dst->regoff) {
4900 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4901 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4904 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4905 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
4906 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4909 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4910 if (src->regoff == iptr->dst->regoff) {
4911 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4914 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4915 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
4916 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4919 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4920 if (src->prev->regoff == iptr->dst->regoff) {
4921 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4924 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4925 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
4926 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4930 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4931 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4935 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4936 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4937 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4939 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4940 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4941 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4943 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4944 M_INTMOVE(src->regoff, iptr->dst->regoff);
4945 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4948 if (src->regoff == iptr->dst->regoff) {
4949 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
4952 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4953 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
4961 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
4963 if (iptr->dst->flags & INMEMORY) {
4964 if (src->flags & INMEMORY) {
4965 if (src->regoff == iptr->dst->regoff) {
4966 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4969 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4970 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
4971 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4975 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
4976 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
4980 if (src->flags & INMEMORY) {
4981 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
4982 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
4985 M_INTMOVE(src->regoff, iptr->dst->regoff);
4986 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
4993 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
4995 if (iptr->dst->flags & INMEMORY) {
4996 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4997 if (src->regoff == iptr->dst->regoff) {
4998 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4999 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
5000 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5001 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5003 } else if (src->prev->regoff == iptr->dst->regoff) {
5004 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5005 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5006 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5007 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5010 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5011 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
5012 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5013 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5014 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5015 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5023 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5025 if (iptr->dst->flags & INMEMORY) {
5026 if (src->flags & INMEMORY) {
5027 if (src->regoff == iptr->dst->regoff) {
5028 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5029 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5032 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5033 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5034 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5035 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP2);
5036 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5037 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5045 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5047 if (iptr->dst->flags & INMEMORY) {
5048 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5049 if (src->prev->regoff == iptr->dst->regoff) {
5050 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5051 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5054 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5055 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5056 i386_shift_reg(shift_op, REG_ITMP1);
5057 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5060 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5061 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5062 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5063 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5065 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5066 if (src->prev->regoff == iptr->dst->regoff) {
5067 M_INTMOVE(src->regoff, I386_ECX);
5068 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5071 M_INTMOVE(src->regoff, I386_ECX);
5072 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5073 i386_shift_reg(shift_op, REG_ITMP1);
5074 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5078 M_INTMOVE(src->regoff, I386_ECX);
5079 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5080 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5084 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5085 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5086 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5087 i386_shift_reg(shift_op, iptr->dst->regoff);
5089 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5090 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5091 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5092 i386_shift_reg(shift_op, iptr->dst->regoff);
5094 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5095 M_INTMOVE(src->regoff, I386_ECX);
5096 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5097 i386_shift_reg(shift_op, iptr->dst->regoff);
5100 M_INTMOVE(src->regoff, I386_ECX);
5101 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5102 i386_shift_reg(shift_op, iptr->dst->regoff);
5109 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5111 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5112 if (src->regoff == iptr->dst->regoff) {
5113 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5116 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5117 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5118 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5121 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5122 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5123 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5125 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5126 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5127 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5130 M_INTMOVE(src->regoff, iptr->dst->regoff);
5131 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5137 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5139 if (iptr->dst->flags & INMEMORY) {
5142 if (src->flags & INMEMORY) {
5143 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5146 i386_test_reg_reg(src->regoff, src->regoff);
5150 CALCOFFSETBYTES(offset, iptr->dst->regoff * 8);
5152 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5153 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5155 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5156 i386_jmp_imm(offset);
5157 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5161 if (src->flags & INMEMORY) {
5162 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5165 i386_test_reg_reg(src->regoff, src->regoff);
5168 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5169 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5171 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5173 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5185 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5186 *(mcodeptr++) = (u1) 0x89;
5187 i386_emit_reg((reg),(dreg));
5191 void i386_mov_imm_reg(s4 imm, s4 reg) {
5192 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5193 i386_emit_imm32((imm));
5197 void i386_movb_imm_reg(s4 imm, s4 reg) {
5198 *(mcodeptr++) = (u1) 0xc6;
5199 i386_emit_reg(0,(reg));
5200 i386_emit_imm8((imm));
5204 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5205 *(mcodeptr++) = (u1) 0x8b;
5206 i386_emit_membase((basereg),(disp),(reg));
5211 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5212 * constant membase immediate length of 32bit
5214 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5215 *(mcodeptr++) = (u1) 0x8b;
5216 i386_address_byte(2, (reg), (basereg));
5217 i386_emit_imm32((disp));
5221 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5222 *(mcodeptr++) = (u1) 0x89;
5223 i386_emit_membase((basereg),(disp),(reg));
5227 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5228 *(mcodeptr++) = (u1) 0x8b;
5229 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5233 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5234 *(mcodeptr++) = (u1) 0x89;
5235 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5239 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5240 *(mcodeptr++) = (u1) 0x66;
5241 *(mcodeptr++) = (u1) 0x89;
5242 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5246 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5247 *(mcodeptr++) = (u1) 0x88;
5248 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5252 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5253 *(mcodeptr++) = (u1) 0xc7;
5254 i386_emit_membase((basereg),(disp),0);
5255 i386_emit_imm32((imm));
5259 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5260 *(mcodeptr++) = (u1) 0x0f;
5261 *(mcodeptr++) = (u1) 0xbe;
5262 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5266 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5267 *(mcodeptr++) = (u1) 0x0f;
5268 *(mcodeptr++) = (u1) 0xbf;
5269 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5273 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5274 *(mcodeptr++) = (u1) 0x0f;
5275 *(mcodeptr++) = (u1) 0xb7;
5276 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5284 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5285 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5286 i386_emit_reg((reg),(dreg));
5290 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5291 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5292 i386_emit_membase((basereg),(disp),(reg));
5296 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5297 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5298 i386_emit_membase((basereg),(disp),(reg));
5302 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5303 if (i386_is_imm8(imm)) {
5304 *(mcodeptr++) = (u1) 0x83;
5305 i386_emit_reg((opc),(dreg));
5306 i386_emit_imm8((imm));
5308 *(mcodeptr++) = (u1) 0x81;
5309 i386_emit_reg((opc),(dreg));
5310 i386_emit_imm32((imm));
5315 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5316 if (i386_is_imm8(imm)) {
5317 *(mcodeptr++) = (u1) 0x83;
5318 i386_emit_membase((basereg),(disp),(opc));
5319 i386_emit_imm8((imm));
5321 *(mcodeptr++) = (u1) 0x81;
5322 i386_emit_membase((basereg),(disp),(opc));
5323 i386_emit_imm32((imm));
5328 void i386_test_reg_reg(s4 reg, s4 dreg) {
5329 *(mcodeptr++) = (u1) 0x85;
5330 i386_emit_reg((reg),(dreg));
5334 void i386_test_imm_reg(s4 imm, s4 reg) {
5335 *(mcodeptr++) = (u1) 0xf7;
5336 i386_emit_reg(0,(reg));
5337 i386_emit_imm32((imm));
5343 * inc, dec operations
5345 void i386_inc_reg(s4 reg) {
5346 *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
5350 void i386_inc_membase(s4 basereg, s4 disp) {
5351 *(mcodeptr++) = (u1) 0xff;
5352 i386_emit_membase((basereg),(disp),0);
5356 void i386_dec_reg(s4 reg) {
5357 *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
5361 void i386_dec_membase(s4 basereg, s4 disp) {
5362 *(mcodeptr++) = (u1) 0xff;
5363 i386_emit_membase((basereg),(disp),1);
5369 *(mcodeptr++) = (u1) 0x99;
5374 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5375 *(mcodeptr++) = (u1) 0x0f;
5376 *(mcodeptr++) = (u1) 0xaf;
5377 i386_emit_reg((dreg),(reg));
5381 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5382 *(mcodeptr++) = (u1) 0x0f;
5383 *(mcodeptr++) = (u1) 0xaf;
5384 i386_emit_membase((basereg),(disp),(dreg));
5388 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5389 if (i386_is_imm8((imm))) {
5390 *(mcodeptr++) = (u1) 0x6b;
5391 i386_emit_reg(0,(dreg));
5392 i386_emit_imm8((imm));
5394 *(mcodeptr++) = (u1) 0x69;
5395 i386_emit_reg(0,(dreg));
5396 i386_emit_imm32((imm));
5401 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5402 if (i386_is_imm8((imm))) {
5403 *(mcodeptr++) = (u1) 0x6b;
5404 i386_emit_reg((dreg),(reg));
5405 i386_emit_imm8((imm));
5407 *(mcodeptr++) = (u1) 0x69;
5408 i386_emit_reg((dreg),(reg));
5409 i386_emit_imm32((imm));
5414 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5415 if (i386_is_imm8((imm))) {
5416 *(mcodeptr++) = (u1) 0x6b;
5417 i386_emit_membase((basereg),(disp),(dreg));
5418 i386_emit_imm8((imm));
5420 *(mcodeptr++) = (u1) 0x69;
5421 i386_emit_membase((basereg),(disp),(dreg));
5422 i386_emit_imm32((imm));
5427 void i386_mul_membase(s4 basereg, s4 disp) {
5428 *(mcodeptr++) = (u1) 0xf7;
5429 i386_emit_membase((basereg),(disp),4);
5433 void i386_idiv_reg(s4 reg) {
5434 *(mcodeptr++) = (u1) 0xf7;
5435 i386_emit_reg(7,(reg));
5441 *(mcodeptr++) = (u1) 0xc3;
5449 void i386_shift_reg(s4 opc, s4 reg) {
5450 *(mcodeptr++) = (u1) 0xd3;
5451 i386_emit_reg((opc),(reg));
5455 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5456 *(mcodeptr++) = (u1) 0xd3;
5457 i386_emit_membase((basereg),(disp),(opc));
5461 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5463 *(mcodeptr++) = (u1) 0xd1;
5464 i386_emit_reg((opc),(dreg));
5466 *(mcodeptr++) = (u1) 0xc1;
5467 i386_emit_reg((opc),(dreg));
5468 i386_emit_imm8((imm));
5473 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5475 *(mcodeptr++) = (u1) 0xd1;
5476 i386_emit_membase((basereg),(disp),(opc));
5478 *(mcodeptr++) = (u1) 0xc1;
5479 i386_emit_membase((basereg),(disp),(opc));
5480 i386_emit_imm8((imm));
5485 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5486 *(mcodeptr++) = (u1) 0x0f;
5487 *(mcodeptr++) = (u1) 0xa5;
5488 i386_emit_reg((reg),(dreg));
5492 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5493 *(mcodeptr++) = (u1) 0x0f;
5494 *(mcodeptr++) = (u1) 0xa4;
5495 i386_emit_reg((reg),(dreg));
5496 i386_emit_imm8((imm));
5500 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5501 *(mcodeptr++) = (u1) 0x0f;
5502 *(mcodeptr++) = (u1) 0xa5;
5503 i386_emit_membase((basereg),(disp),(reg));
5507 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5508 *(mcodeptr++) = (u1) 0x0f;
5509 *(mcodeptr++) = (u1) 0xad;
5510 i386_emit_reg((reg),(dreg));
5514 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5515 *(mcodeptr++) = (u1) 0x0f;
5516 *(mcodeptr++) = (u1) 0xac;
5517 i386_emit_reg((reg),(dreg));
5518 i386_emit_imm8((imm));
5522 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5523 *(mcodeptr++) = (u1) 0x0f;
5524 *(mcodeptr++) = (u1) 0xad;
5525 i386_emit_membase((basereg),(disp),(reg));
5533 void i386_jmp_imm(s4 imm) {
5534 *(mcodeptr++) = (u1) 0xe9;
5535 i386_emit_imm32((imm));
5539 void i386_jmp_reg(s4 reg) {
5540 *(mcodeptr++) = (u1) 0xff;
5541 i386_emit_reg(4,(reg));
5545 void i386_jcc(s4 opc, s4 imm) {
5546 *(mcodeptr++) = (u1) 0x0f;
5547 *(mcodeptr++) = (u1) (0x80 + i386_jcc_map[(opc)]);
5548 i386_emit_imm32((imm));
5554 * conditional set operations
5556 void i386_setcc_reg(s4 opc, s4 reg) {
5557 *(mcodeptr++) = (u1) 0x0f;
5558 *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]);
5559 i386_emit_reg(0,(reg));
5563 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5564 *(mcodeptr++) = (u1) 0x0f;
5565 *(mcodeptr++) = (u1) (0x90 + i386_jcc_map[(opc)]);
5566 i386_emit_membase((basereg),(disp),0);
5571 void i386_neg_reg(s4 reg) {
5572 *(mcodeptr++) = (u1) 0xf7;
5573 i386_emit_reg(3,(reg));
5577 void i386_neg_membase(s4 basereg, s4 disp) {
5578 *(mcodeptr++) = (u1) 0xf7;
5579 i386_emit_membase((basereg),(disp),3);
5584 void i386_push_imm(s4 imm) {
5585 *(mcodeptr++) = (u1) 0x68;
5586 i386_emit_imm32((imm));
5590 void i386_pop_reg(s4 reg) {
5591 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5596 *(mcodeptr++) = (u1) 0x90;
5603 void i386_call_reg(s4 reg) {
5604 *(mcodeptr++) = (u1) 0xff;
5605 i386_emit_reg(2,(reg));
5609 void i386_call_imm(s4 imm) {
5610 *(mcodeptr++) = (u1) 0xe8;
5611 i386_emit_imm32((imm));
5617 * floating point instructions
5620 *(mcodeptr++) = (u1) 0xd9;
5621 *(mcodeptr++) = (u1) 0xe8;
5626 *(mcodeptr++) = (u1) 0xd9;
5627 *(mcodeptr++) = (u1) 0xee;
5631 void i386_fld_reg(s4 reg) {
5632 *(mcodeptr++) = (u1) 0xd9;
5633 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5637 void i386_flds_membase(s4 basereg, s4 disp) {
5638 *(mcodeptr++) = (u1) 0xd9;
5639 i386_emit_membase((basereg),(disp),0);
5643 void i386_fldl_membase(s4 basereg, s4 disp) {
5644 *(mcodeptr++) = (u1) 0xdd;
5645 i386_emit_membase((basereg),(disp),0);
5649 void i386_fldt_membase(s4 basereg, s4 disp) {
5650 *(mcodeptr++) = (u1) 0xdb;
5651 i386_emit_membase((basereg),(disp),5);
5655 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5656 *(mcodeptr++) = (u1) 0xd9;
5657 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5661 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5662 *(mcodeptr++) = (u1) 0xdd;
5663 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5669 void i386_fildl_membase(s4 basereg, s4 disp) {
5670 *(mcodeptr++) = (u1) 0xdb;
5671 i386_emit_membase((basereg),(disp),0);
5675 void i386_fildll_membase(s4 basereg, s4 disp) {
5676 *(mcodeptr++) = (u1) 0xdf;
5677 i386_emit_membase((basereg),(disp),5);
5683 void i386_fst_reg(s4 reg) {
5684 *(mcodeptr++) = (u1) 0xdd;
5685 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5689 void i386_fsts_membase(s4 basereg, s4 disp) {
5690 *(mcodeptr++) = (u1) 0xd9;
5691 i386_emit_membase((basereg),(disp),2);
5695 void i386_fstl_membase(s4 basereg, s4 disp) {
5696 *(mcodeptr++) = (u1) 0xdd;
5697 i386_emit_membase((basereg),(disp),2);
5701 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5702 *(mcodeptr++) = (u1) 0xd9;
5703 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5707 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5708 *(mcodeptr++) = (u1) 0xdd;
5709 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5713 void i386_fstp_reg(s4 reg) {
5714 *(mcodeptr++) = (u1) 0xdd;
5715 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5719 void i386_fstps_membase(s4 basereg, s4 disp) {
5720 *(mcodeptr++) = (u1) 0xd9;
5721 i386_emit_membase((basereg),(disp),3);
5725 void i386_fstpl_membase(s4 basereg, s4 disp) {
5726 *(mcodeptr++) = (u1) 0xdd;
5727 i386_emit_membase((basereg),(disp),3);
5731 void i386_fstpt_membase(s4 basereg, s4 disp) {
5732 *(mcodeptr++) = (u1) 0xdb;
5733 i386_emit_membase((basereg),(disp),7);
5737 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5738 *(mcodeptr++) = (u1) 0xd9;
5739 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5743 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5744 *(mcodeptr++) = (u1) 0xdd;
5745 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5749 void i386_fistl_membase(s4 basereg, s4 disp) {
5750 *(mcodeptr++) = (u1) 0xdb;
5751 i386_emit_membase((basereg),(disp),2);
5755 void i386_fistpl_membase(s4 basereg, s4 disp) {
5756 *(mcodeptr++) = (u1) 0xdb;
5757 i386_emit_membase((basereg),(disp),3);
5761 void i386_fistpll_membase(s4 basereg, s4 disp) {
5762 *(mcodeptr++) = (u1) 0xdf;
5763 i386_emit_membase((basereg),(disp),7);
5768 *(mcodeptr++) = (u1) 0xd9;
5769 *(mcodeptr++) = (u1) 0xe0;
5774 *(mcodeptr++) = (u1) 0xde;
5775 *(mcodeptr++) = (u1) 0xc1;
5779 void i386_fadd_reg_st(s4 reg) {
5780 *(mcodeptr++) = (u1) 0xd8;
5781 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5785 void i386_fadd_st_reg(s4 reg) {
5786 *(mcodeptr++) = (u1) 0xdc;
5787 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5791 void i386_faddp_st_reg(s4 reg) {
5792 *(mcodeptr++) = (u1) 0xde;
5793 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5797 void i386_fadds_membase(s4 basereg, s4 disp) {
5798 *(mcodeptr++) = (u1) 0xd8;
5799 i386_emit_membase((basereg),(disp),0);
5803 void i386_faddl_membase(s4 basereg, s4 disp) {
5804 *(mcodeptr++) = (u1) 0xdc;
5805 i386_emit_membase((basereg),(disp),0);
5809 void i386_fsub_reg_st(s4 reg) {
5810 *(mcodeptr++) = (u1) 0xd8;
5811 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5815 void i386_fsub_st_reg(s4 reg) {
5816 *(mcodeptr++) = (u1) 0xdc;
5817 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5821 void i386_fsubp_st_reg(s4 reg) {
5822 *(mcodeptr++) = (u1) 0xde;
5823 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5828 *(mcodeptr++) = (u1) 0xde;
5829 *(mcodeptr++) = (u1) 0xe9;
5833 void i386_fsubs_membase(s4 basereg, s4 disp) {
5834 *(mcodeptr++) = (u1) 0xd8;
5835 i386_emit_membase((basereg),(disp),4);
5839 void i386_fsubl_membase(s4 basereg, s4 disp) {
5840 *(mcodeptr++) = (u1) 0xdc;
5841 i386_emit_membase((basereg),(disp),4);
5845 void i386_fmul_reg_st(s4 reg) {
5846 *(mcodeptr++) = (u1) 0xd8;
5847 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5851 void i386_fmul_st_reg(s4 reg) {
5852 *(mcodeptr++) = (u1) 0xdc;
5853 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5858 *(mcodeptr++) = (u1) 0xde;
5859 *(mcodeptr++) = (u1) 0xc9;
5863 void i386_fmulp_st_reg(s4 reg) {
5864 *(mcodeptr++) = (u1) 0xde;
5865 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5869 void i386_fmuls_membase(s4 basereg, s4 disp) {
5870 *(mcodeptr++) = (u1) 0xd8;
5871 i386_emit_membase((basereg),(disp),1);
5875 void i386_fmull_membase(s4 basereg, s4 disp) {
5876 *(mcodeptr++) = (u1) 0xdc;
5877 i386_emit_membase((basereg),(disp),1);
5881 void i386_fdiv_reg_st(s4 reg) {
5882 *(mcodeptr++) = (u1) 0xd8;
5883 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
5887 void i386_fdiv_st_reg(s4 reg) {
5888 *(mcodeptr++) = (u1) 0xdc;
5889 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5894 *(mcodeptr++) = (u1) 0xde;
5895 *(mcodeptr++) = (u1) 0xf9;
5899 void i386_fdivp_st_reg(s4 reg) {
5900 *(mcodeptr++) = (u1) 0xde;
5901 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5906 *(mcodeptr++) = (u1) 0xd9;
5907 *(mcodeptr++) = (u1) 0xc9;
5911 void i386_fxch_reg(s4 reg) {
5912 *(mcodeptr++) = (u1) 0xd9;
5913 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5918 *(mcodeptr++) = (u1) 0xd9;
5919 *(mcodeptr++) = (u1) 0xf8;
5923 void i386_fprem1() {
5924 *(mcodeptr++) = (u1) 0xd9;
5925 *(mcodeptr++) = (u1) 0xf5;
5930 *(mcodeptr++) = (u1) 0xdd;
5931 *(mcodeptr++) = (u1) 0xe1;
5935 void i386_fucom_reg(s4 reg) {
5936 *(mcodeptr++) = (u1) 0xdd;
5937 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5941 void i386_fucomp_reg(s4 reg) {
5942 *(mcodeptr++) = (u1) 0xdd;
5943 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5947 void i386_fucompp() {
5948 *(mcodeptr++) = (u1) 0xda;
5949 *(mcodeptr++) = (u1) 0xe9;
5953 void i386_fnstsw() {
5954 *(mcodeptr++) = (u1) 0xdf;
5955 *(mcodeptr++) = (u1) 0xe0;
5960 *(mcodeptr++) = (u1) 0x9e;
5965 *(mcodeptr++) = (u1) 0x9b;
5966 *(mcodeptr++) = (u1) 0xdb;
5967 *(mcodeptr++) = (u1) 0xe3;
5971 void i386_fldcw_mem(s4 mem) {
5972 *(mcodeptr++) = (u1) 0xd9;
5973 i386_emit_mem(5,(mem));
5977 void i386_fldcw_membase(s4 basereg, s4 disp) {
5978 *(mcodeptr++) = (u1) 0xd9;
5979 i386_emit_membase((basereg),(disp),5);
5984 *(mcodeptr++) = (u1) 0x9b;
5988 void i386_ffree_reg(s4 reg) {
5989 *(mcodeptr++) = (u1) 0xdd;
5990 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5994 void i386_fdecstp() {
5995 *(mcodeptr++) = (u1) 0xd9;
5996 *(mcodeptr++) = (u1) 0xf6;
6000 void i386_fincstp() {
6001 *(mcodeptr++) = (u1) 0xd9;
6002 *(mcodeptr++) = (u1) 0xf7;
6009 * These are local overrides for various environment variables in Emacs.
6010 * Please do not remove this and leave it at the end of the file, where
6011 * Emacs will automagically detect them.
6012 * ---------------------------------------------------------------------
6015 * indent-tabs-mode: t