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 688 2003-12-04 23:50:25Z jowenn $
49 #include "methodtable.h"
51 /* include independent code generation stuff */
52 #include "codegen.inc"
56 /* register descripton - array ************************************************/
58 /* #define REG_RES 0 reserved register for OS or code generator */
59 /* #define REG_RET 1 return value register */
60 /* #define REG_EXC 2 exception value register (only old jit) */
61 /* #define REG_SAV 3 (callee) saved register */
62 /* #define REG_TMP 4 scratch temporary register (caller saved) */
63 /* #define REG_ARG 5 argument register (caller saved) */
65 /* #define REG_END -1 last entry in tables */
68 REG_RET, REG_RES, REG_RES, REG_SAV, REG_RES, REG_SAV, REG_TMP, REG_TMP,
71 /* for use of reserved registers, see comment above */
73 int nregdescfloat[] = {
74 /* rounding problems with callee saved registers */
75 /* REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
76 /* REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
77 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
81 /* additional functions and macros to generate code ***************************/
83 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
87 #define COUNT_SPILLS count_spills++
93 #define CALCOFFSETBYTES(var, val) \
94 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
95 else if ((s4) (val) != 0) (var) += 1;
98 #define CALCREGOFFBYTES(var, val) \
99 if ((val) > 15) (var) += 4; \
100 else if ((val) != 0) (var) += 1;
103 #define CALCIMMEDIATEBYTES(var, val) \
104 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
108 /* gen_nullptr_check(objreg) */
110 #define gen_nullptr_check(objreg) \
112 i386_test_reg_reg((objreg), (objreg)); \
113 i386_jcc(I386_CC_E, 0); \
114 codegen_addxnullrefs(mcodeptr); \
118 /* MCODECHECK(icnt) */
120 #define MCODECHECK(icnt) \
121 if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
124 generates an integer-move from register a to b.
125 if a and b are the same int-register, no code will be generated.
128 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
132 generates a floating-point-move from register a to b.
133 if a and b are the same float-register, no code will be generated
136 #define M_FLTMOVE(reg,dreg) panic("M_FLTMOVE");
138 #define M_LNGMEMMOVE(reg,dreg) \
140 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
141 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP2); \
142 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
143 i386_mov_reg_membase(REG_ITMP2, REG_SP, (dreg) * 8 + 4); \
148 this function generates code to fetch data from a pseudo-register
149 into a real register.
150 If the pseudo-register has actually been assigned to a real
151 register, no code will be emitted, since following operations
152 can use this register directly.
154 v: pseudoregister to be fetched from
155 tempregnum: temporary register to be used if v is actually spilled to ram
157 return: the register number, where the operand can be found after
158 fetching (this wil be either tempregnum or the register
159 number allready given to v)
162 #define var_to_reg_int(regnr,v,tempnr) \
163 if ((v)->flags & INMEMORY) { \
165 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
168 regnr = (v)->regoff; \
173 #define var_to_reg_flt(regnr,v,tempnr) \
174 if ((v)->type == TYPE_FLT) { \
175 if ((v)->flags & INMEMORY) { \
177 i386_flds_membase(REG_SP, (v)->regoff * 8); \
181 i386_fld_reg((v)->regoff + fpu_st_offset); \
183 regnr = (v)->regoff; \
186 if ((v)->flags & INMEMORY) { \
188 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
192 i386_fld_reg((v)->regoff + fpu_st_offset); \
194 regnr = (v)->regoff; \
198 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
199 if ((v)->type == TYPE_FLT) { \
200 if ((v)->flags & INMEMORY) { \
202 i386_flds_membase(REG_SP, (v)->regoff * 8); \
206 regnr = (v)->regoff; \
209 if ((v)->flags & INMEMORY) { \
211 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
215 regnr = (v)->regoff; \
221 This function determines a register, to which the result of an operation
222 should go, when it is ultimatively intended to store the result in
224 If v is assigned to an actual register, this register will be returned.
225 Otherwise (when v is spilled) this function returns tempregnum.
226 If not already done, regoff and flags are set in the stack location.
229 static int reg_of_var(stackptr v, int tempregnum)
233 switch (v->varkind) {
235 if (!(v->flags & INMEMORY))
239 var = &(interfaces[v->varnum][v->type]);
240 v->regoff = var->regoff;
241 if (!(var->flags & INMEMORY))
245 var = &(locals[v->varnum][v->type]);
246 v->regoff = var->regoff;
247 if (!(var->flags & INMEMORY))
251 v->regoff = v->varnum;
252 if (IS_FLT_DBL_TYPE(v->type)) {
253 if (v->varnum < fltreg_argnum) {
254 v->regoff = argfltregs[v->varnum];
255 return(argfltregs[v->varnum]);
259 if (v->varnum < intreg_argnum) {
260 v->regoff = argintregs[v->varnum];
261 return(argintregs[v->varnum]);
263 v->regoff -= intreg_argnum;
266 v->flags |= INMEMORY;
271 /* store_reg_to_var_xxx:
272 This function generates the code to store the result of an operation
273 back into a spilled pseudo-variable.
274 If the pseudo-variable has not been spilled in the first place, this
275 function will generate nothing.
277 v ............ Pseudovariable
278 tempregnum ... Number of the temporary registers as returned by
282 #define store_reg_to_var_int(sptr, tempregnum) \
283 if ((sptr)->flags & INMEMORY) { \
285 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
289 #define store_reg_to_var_flt(sptr, tempregnum) \
290 if ((sptr)->type == TYPE_FLT) { \
291 if ((sptr)->flags & INMEMORY) { \
293 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
296 /* i386_fxch_reg((sptr)->regoff);*/ \
297 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
301 if ((sptr)->flags & INMEMORY) { \
303 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
306 /* i386_fxch_reg((sptr)->regoff);*/ \
307 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
313 /* NullPointerException signal handler for hardware null pointer check */
315 void catch_NullPointerException(int sig)
319 /* long faultaddr; */
321 void **_p = (void **) &sig;
322 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
324 /* Reset signal handler - necessary for SysV, does no harm for BSD */
326 instr = *((int*)(sigctx->eip));
327 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
329 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip); */
331 /* if (faultaddr == 0) { */
332 signal(sig, (void *) catch_NullPointerException); /* reinstall handler */
334 sigaddset(&nsig, sig);
335 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
336 sigctx->eax = (long) proto_java_lang_NullPointerException; /* REG_ITMP1_XPTR */
337 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
338 sigctx->eip = (long) asm_handle_exception;
343 /* faultaddr += (long) ((instr << 16) >> 16); */
344 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
345 /* panic("Stack overflow"); */
350 /* ArithmeticException signal handler for hardware divide by zero check */
352 void catch_ArithmeticException(int sig)
356 void **_p = (void **) &sig;
357 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
360 java_objectheader *p;
363 /* Reset signal handler - necessary for SysV, does no harm for BSD */
365 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
367 sigaddset(&nsig, sig);
368 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
370 c = loader_load(utf_new_char("java/lang/ArithmeticException"));
372 m = class_findmethod(c,
373 utf_new_char("<init>"),
374 utf_new_char("(Ljava/lang/String;)V"));
376 asm_calljavamethod(m, p, javastring_new_char("/ by zero"), NULL, NULL);
378 sigctx->eax = (long) p; /* REG_ITMP1_XPTR */
379 sigctx->edx = sigctx->eip; /* REG_ITMP2_XPC */
380 sigctx->eip = (long) asm_handle_exception;
386 void init_exceptions(void)
388 /* install signal handlers we need to convert to exceptions */
393 signal(SIGSEGV, (void *) catch_NullPointerException);
397 signal(SIGBUS, (void *) catch_NullPointerException);
401 signal(SIGFPE, (void *) catch_ArithmeticException);
405 /* function gen_mcode **********************************************************
407 generates machine code
409 *******************************************************************************/
411 /* global code generation pointer */
416 int len, s1, s2, s3, d/*, bbs*/;
424 int fpu_st_offset = 0;
433 /* space to save used callee saved registers */
435 savedregs_num += (savintregcnt - maxsavintreguse);
436 savedregs_num += (savfltregcnt - maxsavfltreguse);
438 parentargs_base = maxmemuse + savedregs_num;
440 #ifdef USE_THREADS /* space to save argument of monitor_enter */
442 if (checksync && (method->flags & ACC_SYNCHRONIZED))
447 /* create method header */
449 (void) dseg_addaddress(method); /* MethodPointer */
450 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
454 /* IsSync contains the offset relative to the stack pointer for the
455 argument of monitor_exit used in the exception handler. Since the
456 offset could be zero and give a wrong meaning of the flag it is
460 if (checksync && (method->flags & ACC_SYNCHRONIZED))
461 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
466 (void) dseg_adds4(0); /* IsSync */
468 (void) dseg_adds4(isleafmethod); /* IsLeaf */
469 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
470 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
471 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
473 /* create exception table */
475 for (ex = extable; ex != NULL; ex = ex->down) {
478 if (ex->start != NULL)
479 printf("adding start - %d - ", ex->start->debug_nr);
481 printf("PANIC - start is NULL");
486 dseg_addtarget(ex->start);
490 printf("adding end - %d - ", ex->end->debug_nr);
492 printf("PANIC - end is NULL");
497 dseg_addtarget(ex->end);
500 if (ex->handler != NULL)
501 printf("adding handler - %d\n", ex->handler->debug_nr);
503 printf("PANIC - handler is NULL");
508 dseg_addtarget(ex->handler);
510 (void) dseg_addaddress(ex->catchtype);
513 /* initialize mcode variables */
515 mcodeptr = (u1*) mcodebase;
516 mcodeend = (s4*) (mcodebase + mcodesize);
517 MCODECHECK(128 + mparamcount);
519 /* create stack frame (if necessary) */
521 if (parentargs_base) {
522 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
525 /* save return address and used callee saved registers */
528 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
529 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
531 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
532 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
535 /* save monitorenter argument */
538 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
539 if (method->flags & ACC_STATIC) {
540 i386_mov_imm_reg((s4) class, REG_ITMP1);
541 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
544 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
545 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
550 /* copy argument registers to stack and call trace function with pointer
551 to arguments on stack.
555 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
557 for (p = 0; p < mparamcount; p++) {
559 if (IS_INT_LNG_TYPE(t)) {
560 if (IS_2_WORD_TYPE(t)) {
561 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
562 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
564 } else if (t == TYPE_ADR) {
565 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
566 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
569 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
572 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
573 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
577 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
578 i386_fstps_membase(REG_SP, p * 8);
579 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
580 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
583 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
584 i386_fstpl_membase(REG_SP, p * 8);
589 /* fill up the remaining arguments */
590 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
591 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
592 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
593 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
596 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
598 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
599 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
600 i386_call_reg(REG_ITMP1);
602 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
605 /* take arguments out of register or stack frame */
607 for (p = 0, l = 0; p < mparamcount; p++) {
609 var = &(locals[l][t]);
611 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
616 if (IS_INT_LNG_TYPE(t)) { /* integer args */
617 if (p < intreg_argnum) { /* register arguments */
618 panic("integer register argument");
619 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
620 /* M_INTMOVE (argintregs[p], r); */
622 } else { /* reg arg -> spilled */
623 /* M_LST (argintregs[p], REG_SP, 8 * r); */
625 } else { /* stack arguments */
626 pa = p - intreg_argnum;
627 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
628 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
629 } else { /* stack arg -> spilled */
630 if (!IS_2_WORD_TYPE(t)) {
631 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
632 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
635 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
636 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
637 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
638 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
643 } else { /* floating args */
644 if (p < fltreg_argnum) { /* register arguments */
645 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
646 panic("There are no float argument registers!");
648 } else { /* reg arg -> spilled */
649 panic("There are no float argument registers!");
652 } else { /* stack arguments */
653 pa = p - fltreg_argnum;
654 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
656 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
658 i386_fstp_reg(r + fpu_st_offset);
662 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
664 i386_fstp_reg(r + fpu_st_offset);
668 } else { /* stack-arg -> spilled */
669 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
670 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
672 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
673 i386_fstps_membase(REG_SP, r * 8);
676 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
677 i386_fstpl_membase(REG_SP, r * 8);
684 /* call monitorenter function */
687 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
688 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
689 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
690 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
691 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP2);
692 i386_call_reg(REG_ITMP2);
693 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
698 /* end of header generation */
700 /* walk through all basic blocks */
701 for (/* bbs = block_count, */ bptr = block; /* --bbs >= 0 */ bptr != NULL; bptr = bptr->next) {
703 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
705 if (bptr->flags >= BBREACHED) {
707 /* branch resolving */
710 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
711 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
712 brefs->branchpos, bptr->mpc);
715 /* copy interface registers to their destination */
720 while (src != NULL) {
722 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
723 if (!IS_2_WORD_TYPE(src->type)) {
724 if (bptr->type == BBTYPE_SBR) {
725 d = reg_of_var(src, REG_ITMP1);
727 store_reg_to_var_int(src, d);
729 } else if (bptr->type == BBTYPE_EXH) {
730 d = reg_of_var(src, REG_ITMP1);
731 M_INTMOVE(REG_ITMP1, d);
732 store_reg_to_var_int(src, d);
736 panic("copy interface registers: longs have to me in memory (begin 1)");
740 d = reg_of_var(src, REG_ITMP1);
741 if ((src->varkind != STACKVAR)) {
743 if (IS_FLT_DBL_TYPE(s2)) {
744 s1 = interfaces[len][s2].regoff;
745 if (!(interfaces[len][s2].flags & INMEMORY)) {
749 if (s2 == TYPE_FLT) {
750 i386_flds_membase(REG_SP, s1 * 8);
753 i386_fldl_membase(REG_SP, s1 * 8);
756 store_reg_to_var_flt(src, d);
759 s1 = interfaces[len][s2].regoff;
760 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
761 if (!(interfaces[len][s2].flags & INMEMORY)) {
765 i386_mov_membase_reg(REG_SP, s1 * 8, d);
767 store_reg_to_var_int(src, d);
770 if (interfaces[len][s2].flags & INMEMORY) {
771 M_LNGMEMMOVE(s1, src->regoff);
774 panic("copy interface registers: longs have to be in memory (begin 2)");
783 /* walk through all instructions */
787 for (iptr = bptr->iinstr;
789 src = iptr->dst, len--, iptr++) {
791 MCODECHECK(64); /* an instruction usually needs < 64 words */
794 case ICMD_NOP: /* ... ==> ... */
797 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
798 if (src->flags & INMEMORY) {
799 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
802 i386_test_reg_reg(src->regoff, src->regoff);
804 i386_jcc(I386_CC_E, 0);
805 codegen_addxnullrefs(mcodeptr);
808 /* constant operations ************************************************/
810 case ICMD_ICONST: /* ... ==> ..., constant */
811 /* op1 = 0, val.i = constant */
813 d = reg_of_var(iptr->dst, REG_ITMP1);
814 if (iptr->dst->flags & INMEMORY) {
815 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
818 if (iptr->val.i == 0) {
819 i386_alu_reg_reg(I386_XOR, d, d);
822 i386_mov_imm_reg(iptr->val.i, d);
827 case ICMD_LCONST: /* ... ==> ..., constant */
828 /* op1 = 0, val.l = constant */
830 d = reg_of_var(iptr->dst, REG_ITMP1);
831 if (iptr->dst->flags & INMEMORY) {
832 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
833 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
836 panic("LCONST: longs have to be in memory");
840 case ICMD_FCONST: /* ... ==> ..., constant */
841 /* op1 = 0, val.f = constant */
843 d = reg_of_var(iptr->dst, REG_FTMP1);
844 if (iptr->val.f == 0.0) {
849 if (iptr->val.i == 0x80000000) {
853 } else if (iptr->val.f == 1.0) {
857 } else if (iptr->val.f == 2.0) {
864 a = dseg_addfloat(iptr->val.f);
865 i386_mov_imm_reg(0, REG_ITMP1);
866 dseg_adddata(mcodeptr);
867 i386_flds_membase(REG_ITMP1, a);
870 store_reg_to_var_flt(iptr->dst, d);
873 case ICMD_DCONST: /* ... ==> ..., constant */
874 /* op1 = 0, val.d = constant */
876 d = reg_of_var(iptr->dst, REG_FTMP1);
877 if (iptr->val.d == 0.0) {
882 if (iptr->val.l == 0x8000000000000000LL) {
886 } else if (iptr->val.d == 1.0) {
890 } else if (iptr->val.d == 2.0) {
897 a = dseg_adddouble(iptr->val.d);
898 i386_mov_imm_reg(0, REG_ITMP1);
899 dseg_adddata(mcodeptr);
900 i386_fldl_membase(REG_ITMP1, a);
903 store_reg_to_var_flt(iptr->dst, d);
906 case ICMD_ACONST: /* ... ==> ..., constant */
907 /* op1 = 0, val.a = constant */
909 d = reg_of_var(iptr->dst, REG_ITMP1);
910 if (iptr->dst->flags & INMEMORY) {
911 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
914 if ((s4) iptr->val.a == 0) {
915 i386_alu_reg_reg(I386_XOR, d, d);
918 i386_mov_imm_reg((s4) iptr->val.a, d);
924 /* load/store operations **********************************************/
926 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
927 case ICMD_ALOAD: /* op1 = local variable */
929 d = reg_of_var(iptr->dst, REG_ITMP1);
930 if ((iptr->dst->varkind == LOCALVAR) &&
931 (iptr->dst->varnum == iptr->op1)) {
934 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
935 if (iptr->dst->flags & INMEMORY) {
936 if (var->flags & INMEMORY) {
937 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
938 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
941 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
945 if (var->flags & INMEMORY) {
946 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
949 M_INTMOVE(var->regoff, iptr->dst->regoff);
954 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
955 /* op1 = local variable */
957 d = reg_of_var(iptr->dst, REG_ITMP1);
958 if ((iptr->dst->varkind == LOCALVAR) &&
959 (iptr->dst->varnum == iptr->op1)) {
962 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
963 if (iptr->dst->flags & INMEMORY) {
964 if (var->flags & INMEMORY) {
965 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
968 panic("LLOAD: longs have to be in memory");
972 panic("LLOAD: longs have to be in memory");
976 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
977 /* op1 = local variable */
979 d = reg_of_var(iptr->dst, REG_FTMP1);
980 if ((iptr->dst->varkind == LOCALVAR) &&
981 (iptr->dst->varnum == iptr->op1)) {
984 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
985 if (var->flags & INMEMORY) {
986 i386_flds_membase(REG_SP, var->regoff * 8);
989 i386_fld_reg(var->regoff + fpu_st_offset);
992 store_reg_to_var_flt(iptr->dst, d);
995 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
996 /* op1 = local variable */
998 d = reg_of_var(iptr->dst, REG_FTMP1);
999 if ((iptr->dst->varkind == LOCALVAR) &&
1000 (iptr->dst->varnum == iptr->op1)) {
1003 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
1004 if (var->flags & INMEMORY) {
1005 i386_fldl_membase(REG_SP, var->regoff * 8);
1008 i386_fld_reg(var->regoff + fpu_st_offset);
1011 store_reg_to_var_flt(iptr->dst, d);
1014 case ICMD_ISTORE: /* ..., value ==> ... */
1015 case ICMD_ASTORE: /* op1 = local variable */
1017 if ((src->varkind == LOCALVAR) &&
1018 (src->varnum == iptr->op1)) {
1021 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1022 if (var->flags & INMEMORY) {
1023 if (src->flags & INMEMORY) {
1024 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1025 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
1028 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
1032 var_to_reg_int(s1, src, var->regoff);
1033 M_INTMOVE(s1, var->regoff);
1037 case ICMD_LSTORE: /* ..., value ==> ... */
1038 /* op1 = local variable */
1040 if ((src->varkind == LOCALVAR) &&
1041 (src->varnum == iptr->op1)) {
1044 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1045 if (var->flags & INMEMORY) {
1046 if (src->flags & INMEMORY) {
1047 M_LNGMEMMOVE(src->regoff, var->regoff);
1050 panic("LSTORE: longs have to be in memory");
1054 panic("LSTORE: longs have to be in memory");
1058 case ICMD_FSTORE: /* ..., value ==> ... */
1059 /* op1 = local variable */
1061 if ((src->varkind == LOCALVAR) &&
1062 (src->varnum == iptr->op1)) {
1065 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1066 if (var->flags & INMEMORY) {
1067 var_to_reg_flt(s1, src, REG_FTMP1);
1068 i386_fstps_membase(REG_SP, var->regoff * 8);
1071 var_to_reg_flt(s1, src, var->regoff);
1072 /* M_FLTMOVE(s1, var->regoff); */
1073 i386_fstp_reg(var->regoff + fpu_st_offset);
1078 case ICMD_DSTORE: /* ..., value ==> ... */
1079 /* op1 = local variable */
1081 if ((src->varkind == LOCALVAR) &&
1082 (src->varnum == iptr->op1)) {
1085 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1086 if (var->flags & INMEMORY) {
1087 var_to_reg_flt(s1, src, REG_FTMP1);
1088 i386_fstpl_membase(REG_SP, var->regoff * 8);
1091 var_to_reg_flt(s1, src, var->regoff);
1092 /* M_FLTMOVE(s1, var->regoff); */
1093 i386_fstp_reg(var->regoff + fpu_st_offset);
1099 /* pop/dup/swap operations ********************************************/
1101 /* attention: double and longs are only one entry in CACAO ICMDs */
1103 case ICMD_POP: /* ..., value ==> ... */
1104 case ICMD_POP2: /* ..., value, value ==> ... */
1107 #define M_COPY(from,to) \
1108 d = reg_of_var(to, REG_ITMP1); \
1109 if ((from->regoff != to->regoff) || \
1110 ((from->flags ^ to->flags) & INMEMORY)) { \
1111 if (IS_FLT_DBL_TYPE(from->type)) { \
1112 var_to_reg_flt(s1, from, d); \
1113 /* M_FLTMOVE(s1, d);*/ \
1114 store_reg_to_var_flt(to, d); \
1116 if (!IS_2_WORD_TYPE(from->type)) { \
1117 if (to->flags & INMEMORY) { \
1118 if (from->flags & INMEMORY) { \
1119 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1120 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1122 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1125 if (from->flags & INMEMORY) { \
1126 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1128 i386_mov_reg_reg(from->regoff, to->regoff); \
1132 M_LNGMEMMOVE(from->regoff, to->regoff); \
1137 case ICMD_DUP: /* ..., a ==> ..., a, a */
1138 M_COPY(src, iptr->dst);
1141 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1143 M_COPY(src, iptr->dst->prev->prev);
1145 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1147 M_COPY(src, iptr->dst);
1148 M_COPY(src->prev, iptr->dst->prev);
1151 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1153 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1155 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1157 M_COPY(src, iptr->dst);
1158 M_COPY(src->prev, iptr->dst->prev);
1159 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1160 M_COPY(src, iptr->dst->prev->prev->prev);
1163 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1165 M_COPY(src, iptr->dst);
1166 M_COPY(src->prev, iptr->dst->prev);
1167 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1168 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1169 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1170 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1173 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1175 M_COPY(src, iptr->dst->prev);
1176 M_COPY(src->prev, iptr->dst);
1180 /* integer operations *************************************************/
1182 case ICMD_INEG: /* ..., value ==> ..., - value */
1184 d = reg_of_var(iptr->dst, REG_NULL);
1185 if (iptr->dst->flags & INMEMORY) {
1186 if (src->flags & INMEMORY) {
1187 if (src->regoff == iptr->dst->regoff) {
1188 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1191 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1192 i386_neg_reg(REG_ITMP1);
1193 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1197 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1198 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1202 if (src->flags & INMEMORY) {
1203 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1204 i386_neg_reg(iptr->dst->regoff);
1207 M_INTMOVE(src->regoff, iptr->dst->regoff);
1208 i386_neg_reg(iptr->dst->regoff);
1213 case ICMD_LNEG: /* ..., value ==> ..., - value */
1215 d = reg_of_var(iptr->dst, REG_NULL);
1216 if (iptr->dst->flags & INMEMORY) {
1217 if (src->flags & INMEMORY) {
1218 if (src->regoff == iptr->dst->regoff) {
1219 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1220 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1221 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1224 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1225 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1226 i386_neg_reg(REG_ITMP1);
1227 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1228 i386_neg_reg(REG_ITMP2);
1229 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1230 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1236 case ICMD_I2L: /* ..., value ==> ..., value */
1238 d = reg_of_var(iptr->dst, REG_NULL);
1239 if (iptr->dst->flags & INMEMORY) {
1240 if (src->flags & INMEMORY) {
1241 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_EAX);
1243 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1244 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1247 M_INTMOVE(src->regoff, I386_EAX);
1249 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1250 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1255 case ICMD_L2I: /* ..., value ==> ..., value */
1257 d = reg_of_var(iptr->dst, REG_NULL);
1258 if (iptr->dst->flags & INMEMORY) {
1259 if (src->flags & INMEMORY) {
1260 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1261 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1265 if (src->flags & INMEMORY) {
1266 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1271 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1273 d = reg_of_var(iptr->dst, REG_NULL);
1274 if (iptr->dst->flags & INMEMORY) {
1275 if (src->flags & INMEMORY) {
1276 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1277 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1278 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1279 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1282 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1283 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1284 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1288 if (src->flags & INMEMORY) {
1289 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1290 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1291 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1294 M_INTMOVE(src->regoff, iptr->dst->regoff);
1295 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1296 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1301 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1303 d = reg_of_var(iptr->dst, REG_NULL);
1304 if (iptr->dst->flags & INMEMORY) {
1305 if (src->flags & INMEMORY) {
1306 if (src->regoff == iptr->dst->regoff) {
1307 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1310 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1311 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1312 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1316 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1317 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1321 if (src->flags & INMEMORY) {
1322 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1323 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1326 M_INTMOVE(src->regoff, iptr->dst->regoff);
1327 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1332 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1334 d = reg_of_var(iptr->dst, REG_NULL);
1335 if (iptr->dst->flags & INMEMORY) {
1336 if (src->flags & INMEMORY) {
1337 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1338 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1339 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1340 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1343 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1344 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1345 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1349 if (src->flags & INMEMORY) {
1350 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1351 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1352 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1355 M_INTMOVE(src->regoff, iptr->dst->regoff);
1356 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1357 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1363 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1365 d = reg_of_var(iptr->dst, REG_NULL);
1366 i386_emit_ialu(I386_ADD, src, iptr);
1369 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1370 /* val.i = constant */
1372 d = reg_of_var(iptr->dst, REG_NULL);
1373 /* should we use a inc optimization for smaller code size? */
1374 i386_emit_ialuconst(I386_ADD, src, iptr);
1377 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1379 d = reg_of_var(iptr->dst, REG_NULL);
1380 if (iptr->dst->flags & INMEMORY) {
1381 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1382 if (src->regoff == iptr->dst->regoff) {
1383 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1384 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1385 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1386 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1388 } else if (src->prev->regoff == iptr->dst->regoff) {
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_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1392 i386_alu_reg_membase(I386_ADC, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1395 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1396 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1397 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1398 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1399 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1400 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1407 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1408 /* val.l = constant */
1410 d = reg_of_var(iptr->dst, REG_NULL);
1411 if (iptr->dst->flags & INMEMORY) {
1412 if (src->flags & INMEMORY) {
1413 if (src->regoff == iptr->dst->regoff) {
1414 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1415 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1418 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1419 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1420 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1421 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP2);
1422 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1423 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1429 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1431 d = reg_of_var(iptr->dst, REG_NULL);
1432 if (iptr->dst->flags & INMEMORY) {
1433 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1434 if (src->prev->regoff == iptr->dst->regoff) {
1435 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1436 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1439 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1440 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1441 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1444 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1445 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1446 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1447 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1449 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1450 if (src->prev->regoff == iptr->dst->regoff) {
1451 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1454 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1455 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1456 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1460 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1461 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1465 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1466 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1467 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1469 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1470 M_INTMOVE(src->prev->regoff, d);
1471 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1473 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1474 /* workaround for reg alloc */
1475 if (src->regoff == iptr->dst->regoff) {
1476 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1477 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1478 M_INTMOVE(REG_ITMP1, d);
1481 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1482 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1486 /* workaround for reg alloc */
1487 if (src->regoff == iptr->dst->regoff) {
1488 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1489 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1490 M_INTMOVE(REG_ITMP1, d);
1493 M_INTMOVE(src->prev->regoff, d);
1494 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1500 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1501 /* val.i = constant */
1503 d = reg_of_var(iptr->dst, REG_NULL);
1504 i386_emit_ialuconst(I386_SUB, src, iptr);
1507 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1509 d = reg_of_var(iptr->dst, REG_NULL);
1510 if (iptr->dst->flags & INMEMORY) {
1511 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1512 if (src->prev->regoff == iptr->dst->regoff) {
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_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1516 i386_alu_reg_membase(I386_SBB, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1519 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1520 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1521 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1522 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1523 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1524 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1530 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1531 /* val.l = constant */
1533 d = reg_of_var(iptr->dst, REG_NULL);
1534 if (iptr->dst->flags & INMEMORY) {
1535 if (src->flags & INMEMORY) {
1536 if (src->regoff == iptr->dst->regoff) {
1537 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1538 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1541 /* TODO: could be size optimized with lea -- see gcc output */
1542 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1543 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1544 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1545 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP2);
1546 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1547 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1553 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1555 d = reg_of_var(iptr->dst, REG_NULL);
1556 if (iptr->dst->flags & INMEMORY) {
1557 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1558 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1559 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1560 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1562 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1563 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1564 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1565 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1567 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1568 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1569 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1570 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1573 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1574 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1575 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1579 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1580 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1581 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1583 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1584 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1585 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1587 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1588 M_INTMOVE(src->regoff, iptr->dst->regoff);
1589 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1592 if (src->regoff == iptr->dst->regoff) {
1593 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1596 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1597 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1603 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1604 /* val.i = constant */
1606 d = reg_of_var(iptr->dst, REG_NULL);
1607 if (iptr->dst->flags & INMEMORY) {
1608 if (src->flags & INMEMORY) {
1609 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1610 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1613 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1614 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1618 if (src->flags & INMEMORY) {
1619 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1622 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1627 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1629 d = reg_of_var(iptr->dst, REG_NULL);
1630 if (iptr->dst->flags & INMEMORY) {
1631 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1632 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX); /* mem -> EAX */
1633 /* optimize move EAX -> REG_ITMP3 is slower??? */
1634 /* i386_mov_reg_reg(I386_EAX, REG_ITMP3); */
1635 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1637 /* TODO: optimize move EAX -> REG_ITMP3 */
1638 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3); /* mem -> ITMP3 */
1639 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1640 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1642 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP3); /* mem -> ITMP3 */
1643 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1645 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1646 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1647 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1652 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1653 /* val.l = constant */
1655 d = reg_of_var(iptr->dst, REG_NULL);
1656 if (iptr->dst->flags & INMEMORY) {
1657 if (src->flags & INMEMORY) {
1658 i386_mov_imm_reg(iptr->val.l, I386_EAX); /* imm -> EAX */
1659 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1660 /* TODO: optimize move EAX -> REG_ITMP3 */
1661 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP3); /* imm -> ITMP3 */
1662 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1664 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1665 i386_mov_imm_reg(iptr->val.l, REG_ITMP3); /* imm -> ITMP3 */
1666 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); /* mem * ITMP3 -> ITMP3 */
1668 i386_alu_reg_reg(I386_ADD, REG_ITMP3, I386_EDX); /* ITMP3 + EDX -> EDX */
1669 i386_mov_reg_membase(I386_EAX, REG_SP, iptr->dst->regoff * 8);
1670 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1675 #define gen_div_check(v) \
1677 if ((v)->flags & INMEMORY) { \
1678 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1680 i386_test_reg_reg(src->regoff, src->regoff); \
1682 i386_jcc(I386_CC_E, 0); \
1683 codegen_addxdivrefs(mcodeptr); \
1686 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1688 d = reg_of_var(iptr->dst, REG_NULL);
1689 var_to_reg_int(s1, src, REG_ITMP3);
1691 if (src->prev->flags & INMEMORY) {
1692 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1695 M_INTMOVE(src->prev->regoff, I386_EAX);
1698 i386_alu_imm_reg(I386_CMP, 0x80000000, I386_EAX); /* check as described in jvm spec */
1699 i386_jcc(I386_CC_NE, 3 + 6);
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_EAX, REG_SP, iptr->dst->regoff * 8);
1710 M_INTMOVE(I386_EAX, iptr->dst->regoff);
1714 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1716 d = reg_of_var(iptr->dst, REG_NULL);
1717 var_to_reg_int(s1, src, REG_ITMP3);
1719 if (src->prev->flags & INMEMORY) {
1720 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, I386_EAX);
1723 M_INTMOVE(src->prev->regoff, I386_EAX);
1726 i386_alu_imm_reg(I386_CMP, 0x80000000, I386_EAX); /* check as described in jvm spec */
1727 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1728 i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EDX);
1729 i386_alu_imm_reg(I386_CMP, -1, s1);
1730 i386_jcc(I386_CC_E, 1 + 2);
1735 if (iptr->dst->flags & INMEMORY) {
1736 i386_mov_reg_membase(I386_EDX, REG_SP, iptr->dst->regoff * 8);
1739 M_INTMOVE(I386_EDX, iptr->dst->regoff);
1743 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1744 /* val.i = constant */
1746 /* TODO: optimize for `/ 2' */
1747 var_to_reg_int(s1, src, REG_ITMP1);
1748 d = reg_of_var(iptr->dst, REG_ITMP1);
1751 i386_test_reg_reg(d, d);
1753 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1754 i386_jcc(I386_CC_NS, a);
1755 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1757 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1758 store_reg_to_var_int(iptr->dst, d);
1761 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1762 /* val.i = constant */
1764 d = reg_of_var(iptr->dst, REG_NULL);
1765 if (iptr->dst->flags & INMEMORY) {
1766 if (src->flags & INMEMORY) {
1768 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1770 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1771 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1773 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1774 i386_jcc(I386_CC_NS, a);
1775 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1776 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1777 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1778 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1780 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1781 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1786 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1787 /* val.i = constant */
1789 var_to_reg_int(s1, src, REG_ITMP1);
1790 d = reg_of_var(iptr->dst, REG_ITMP2);
1792 M_INTMOVE(s1, REG_ITMP1);
1799 CALCIMMEDIATEBYTES(a, iptr->val.i);
1802 /* TODO: optimize */
1804 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1805 i386_test_reg_reg(s1, s1);
1806 i386_jcc(I386_CC_GE, a);
1807 i386_mov_reg_reg(s1, d);
1809 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1812 /* M_INTMOVE(s1, I386_EAX); */
1814 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
1815 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
1816 /* i386_alu_reg_reg(I386_AND, iptr->val.i, I386_EAX); */
1817 /* i386_alu_reg_reg(I386_XOR, I386_EDX, I386_EAX); */
1818 /* i386_alu_reg_reg(I386_SUB, I386_EDX, I386_EAX); */
1819 /* M_INTMOVE(I386_EAX, d); */
1821 /* i386_alu_reg_reg(I386_XOR, d, d); */
1822 /* i386_mov_imm_reg(iptr->val.i, I386_ECX); */
1823 /* i386_shrd_reg_reg(s1, d); */
1824 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1826 store_reg_to_var_int(iptr->dst, d);
1829 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1830 /* val.l = constant */
1832 d = reg_of_var(iptr->dst, REG_NULL);
1833 if (iptr->dst->flags & INMEMORY) {
1834 if (src->flags & INMEMORY) {
1835 /* Intel algorithm -- does not work, because constant is wrong */
1836 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1837 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1839 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1840 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1841 /* i386_jcc(I386_CC_NS, offset); */
1842 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1843 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1845 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1846 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1847 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1849 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1851 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1852 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1853 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1855 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1856 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1858 /* Alpha algorithm */
1860 CALCOFFSETBYTES(a, src->regoff * 8);
1862 CALCOFFSETBYTES(a, src->regoff * 8 + 4);
1868 /* TODO: hmm, don't know if this is always correct */
1870 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1872 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1878 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1879 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1881 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1882 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1883 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1884 i386_jcc(I386_CC_GE, a);
1886 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1887 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1889 i386_neg_reg(REG_ITMP1);
1890 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1891 i386_neg_reg(REG_ITMP2);
1893 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1894 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1896 i386_neg_reg(REG_ITMP1);
1897 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1898 i386_neg_reg(REG_ITMP2);
1900 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1901 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1906 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1908 d = reg_of_var(iptr->dst, REG_NULL);
1909 i386_emit_ishift(I386_SHL, src, iptr);
1912 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1913 /* val.i = constant */
1915 d = reg_of_var(iptr->dst, REG_NULL);
1916 i386_emit_ishiftconst(I386_SHL, src, iptr);
1919 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1921 d = reg_of_var(iptr->dst, REG_NULL);
1922 i386_emit_ishift(I386_SAR, src, iptr);
1925 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1926 /* val.i = constant */
1928 d = reg_of_var(iptr->dst, REG_NULL);
1929 i386_emit_ishiftconst(I386_SAR, src, iptr);
1932 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1934 d = reg_of_var(iptr->dst, REG_NULL);
1935 i386_emit_ishift(I386_SHR, src, iptr);
1938 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1939 /* val.i = constant */
1941 d = reg_of_var(iptr->dst, REG_NULL);
1942 i386_emit_ishiftconst(I386_SHR, src, iptr);
1945 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1947 d = reg_of_var(iptr->dst, REG_NULL);
1948 if (iptr->dst->flags & INMEMORY ){
1949 if (src->prev->flags & INMEMORY) {
1950 /* if (src->prev->regoff == iptr->dst->regoff) { */
1951 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1953 /* if (src->flags & INMEMORY) { */
1954 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
1956 /* M_INTMOVE(src->regoff, I386_ECX); */
1959 /* i386_test_imm_reg(32, I386_ECX); */
1960 /* i386_jcc(I386_CC_E, 2 + 2); */
1961 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1962 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1964 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1965 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1968 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1969 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
1971 if (src->flags & INMEMORY) {
1972 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
1974 M_INTMOVE(src->regoff, I386_ECX);
1977 i386_test_imm_reg(32, I386_ECX);
1978 i386_jcc(I386_CC_E, 2 + 2);
1979 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
1980 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1982 i386_shld_reg_reg(REG_ITMP1, REG_ITMP2);
1983 i386_shift_reg(I386_SHL, REG_ITMP1);
1984 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1985 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1991 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1992 /* val.i = constant */
1994 d = reg_of_var(iptr->dst, REG_NULL);
1995 if (iptr->dst->flags & INMEMORY ) {
1996 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1997 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1999 if (iptr->val.i & 0x20) {
2000 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2001 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2002 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2005 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2006 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2009 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2010 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2014 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2016 d = reg_of_var(iptr->dst, REG_NULL);
2017 if (iptr->dst->flags & INMEMORY ){
2018 if (src->prev->flags & INMEMORY) {
2019 /* if (src->prev->regoff == iptr->dst->regoff) { */
2020 /* TODO: optimize */
2021 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2022 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2024 /* if (src->flags & INMEMORY) { */
2025 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2027 /* M_INTMOVE(src->regoff, I386_ECX); */
2030 /* i386_test_imm_reg(32, I386_ECX); */
2031 /* i386_jcc(I386_CC_E, 2 + 3); */
2032 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2033 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2035 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2036 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2037 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2038 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2041 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2042 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2044 if (src->flags & INMEMORY) {
2045 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2047 M_INTMOVE(src->regoff, I386_ECX);
2050 i386_test_imm_reg(32, I386_ECX);
2051 i386_jcc(I386_CC_E, 2 + 3);
2052 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2053 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2055 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2056 i386_shift_reg(I386_SAR, REG_ITMP2);
2057 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2058 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2064 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2065 /* val.i = constant */
2067 d = reg_of_var(iptr->dst, REG_NULL);
2068 if (iptr->dst->flags & INMEMORY ) {
2069 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2070 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2072 if (iptr->val.i & 0x20) {
2073 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2074 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2075 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2078 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2079 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2082 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2083 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2087 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2089 d = reg_of_var(iptr->dst, REG_NULL);
2090 if (iptr->dst->flags & INMEMORY ){
2091 if (src->prev->flags & INMEMORY) {
2092 /* if (src->prev->regoff == iptr->dst->regoff) { */
2093 /* TODO: optimize */
2094 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2095 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2097 /* if (src->flags & INMEMORY) { */
2098 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX); */
2100 /* M_INTMOVE(src->regoff, I386_ECX); */
2103 /* i386_test_imm_reg(32, I386_ECX); */
2104 /* i386_jcc(I386_CC_E, 2 + 2); */
2105 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2106 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2108 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2109 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2110 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2111 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2114 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2115 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
2117 if (src->flags & INMEMORY) {
2118 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
2120 M_INTMOVE(src->regoff, I386_ECX);
2123 i386_test_imm_reg(32, I386_ECX);
2124 i386_jcc(I386_CC_E, 2 + 2);
2125 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2126 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2128 i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1);
2129 i386_shift_reg(I386_SHR, REG_ITMP2);
2130 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2131 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2137 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2138 /* val.l = constant */
2140 d = reg_of_var(iptr->dst, REG_NULL);
2141 if (iptr->dst->flags & INMEMORY ) {
2142 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2143 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2145 if (iptr->val.i & 0x20) {
2146 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2147 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2148 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2151 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2152 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2155 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2156 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2160 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2162 d = reg_of_var(iptr->dst, REG_NULL);
2163 i386_emit_ialu(I386_AND, src, iptr);
2166 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2167 /* val.i = constant */
2169 d = reg_of_var(iptr->dst, REG_NULL);
2170 i386_emit_ialuconst(I386_AND, src, iptr);
2173 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2175 d = reg_of_var(iptr->dst, REG_NULL);
2176 i386_emit_lalu(I386_AND, src, iptr);
2179 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2180 /* val.l = constant */
2182 d = reg_of_var(iptr->dst, REG_NULL);
2183 i386_emit_laluconst(I386_AND, src, iptr);
2186 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2188 d = reg_of_var(iptr->dst, REG_NULL);
2189 i386_emit_ialu(I386_OR, src, iptr);
2192 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2193 /* val.i = constant */
2195 d = reg_of_var(iptr->dst, REG_NULL);
2196 i386_emit_ialuconst(I386_OR, src, iptr);
2199 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2201 d = reg_of_var(iptr->dst, REG_NULL);
2202 i386_emit_lalu(I386_OR, src, iptr);
2205 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2206 /* val.l = constant */
2208 d = reg_of_var(iptr->dst, REG_NULL);
2209 i386_emit_laluconst(I386_OR, src, iptr);
2212 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2214 d = reg_of_var(iptr->dst, REG_NULL);
2215 i386_emit_ialu(I386_XOR, src, iptr);
2218 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2219 /* val.i = constant */
2221 d = reg_of_var(iptr->dst, REG_NULL);
2222 i386_emit_ialuconst(I386_XOR, src, iptr);
2225 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2227 d = reg_of_var(iptr->dst, REG_NULL);
2228 i386_emit_lalu(I386_XOR, src, iptr);
2231 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2232 /* val.l = constant */
2234 d = reg_of_var(iptr->dst, REG_NULL);
2235 i386_emit_laluconst(I386_XOR, src, iptr);
2238 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2239 /* op1 = variable, val.i = constant */
2241 var = &(locals[iptr->op1][TYPE_INT]);
2242 if (var->flags & INMEMORY) {
2243 if (iptr->val.i == 1) {
2244 i386_inc_membase(REG_SP, var->regoff * 8);
2246 } else if (iptr->val.i == -1) {
2247 i386_dec_membase(REG_SP, var->regoff * 8);
2250 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2254 if (iptr->val.i == 1) {
2255 i386_inc_reg(var->regoff);
2257 } else if (iptr->val.i == -1) {
2258 i386_dec_reg(var->regoff);
2261 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2267 /* floating operations ************************************************/
2269 #define ROUND_TO_SINGLE \
2270 i386_fstps_membase(REG_SP, -8); \
2271 i386_flds_membase(REG_SP, -8);
2273 #define ROUND_TO_DOUBLE \
2274 i386_fstpl_membase(REG_SP, -8); \
2275 i386_fldl_membase(REG_SP, -8);
2277 #define FPU_SET_24BIT_MODE \
2278 if (!fpu_in_24bit_mode) { \
2279 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2280 fpu_in_24bit_mode = 1; \
2283 #define FPU_SET_53BIT_MODE \
2284 if (fpu_in_24bit_mode) { \
2285 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2286 fpu_in_24bit_mode = 0; \
2289 #define ROUND_TO_SINGLE
2290 #define ROUND_TO_DOUBLE
2291 #define FPU_SET_24BIT_MODE
2292 #define FPU_SET_53BIT_MODE
2294 case ICMD_FNEG: /* ..., value ==> ..., - value */
2297 var_to_reg_flt(s1, src, REG_FTMP1);
2298 d = reg_of_var(iptr->dst, REG_FTMP3);
2300 store_reg_to_var_flt(iptr->dst, d);
2303 case ICMD_DNEG: /* ..., value ==> ..., - value */
2306 var_to_reg_flt(s1, src, REG_FTMP1);
2307 d = reg_of_var(iptr->dst, REG_FTMP3);
2309 store_reg_to_var_flt(iptr->dst, d);
2312 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2315 d = reg_of_var(iptr->dst, REG_FTMP3);
2316 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2317 var_to_reg_flt(s2, src, REG_FTMP2);
2320 store_reg_to_var_flt(iptr->dst, d);
2323 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2326 d = reg_of_var(iptr->dst, REG_FTMP3);
2327 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2328 var_to_reg_flt(s2, src, REG_FTMP2);
2331 store_reg_to_var_flt(iptr->dst, d);
2334 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2337 d = reg_of_var(iptr->dst, REG_FTMP3);
2338 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2339 var_to_reg_flt(s2, src, REG_FTMP2);
2342 store_reg_to_var_flt(iptr->dst, d);
2345 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2348 d = reg_of_var(iptr->dst, REG_FTMP3);
2349 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2350 var_to_reg_flt(s2, src, REG_FTMP2);
2353 store_reg_to_var_flt(iptr->dst, d);
2356 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2359 d = reg_of_var(iptr->dst, REG_FTMP3);
2360 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2361 var_to_reg_flt(s2, src, REG_FTMP2);
2365 store_reg_to_var_flt(iptr->dst, d);
2368 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2371 d = reg_of_var(iptr->dst, REG_FTMP3);
2372 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2374 /* i386_fldt_mem(subnormal_bias1); */
2377 var_to_reg_flt(s2, src, REG_FTMP2);
2382 /* i386_fldt_mem(subnormal_bias2); */
2385 store_reg_to_var_flt(iptr->dst, d);
2388 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2391 d = reg_of_var(iptr->dst, REG_FTMP3);
2392 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2393 var_to_reg_flt(s2, src, REG_FTMP2);
2397 store_reg_to_var_flt(iptr->dst, d);
2400 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2403 d = reg_of_var(iptr->dst, REG_FTMP3);
2404 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2406 /* i386_fldt_mem(subnormal_bias1); */
2409 var_to_reg_flt(s2, src, REG_FTMP2);
2414 /* i386_fldt_mem(subnormal_bias2); */
2417 store_reg_to_var_flt(iptr->dst, d);
2420 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2423 /* exchanged to skip fxch */
2424 var_to_reg_flt(s2, src, REG_FTMP2);
2425 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2426 d = reg_of_var(iptr->dst, REG_FTMP3);
2432 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2433 store_reg_to_var_flt(iptr->dst, d);
2439 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2442 /* exchanged to skip fxch */
2443 var_to_reg_flt(s2, src, REG_FTMP2);
2444 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2445 d = reg_of_var(iptr->dst, REG_FTMP3);
2451 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2452 store_reg_to_var_flt(iptr->dst, d);
2458 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2459 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2461 d = reg_of_var(iptr->dst, REG_FTMP1);
2462 if (src->flags & INMEMORY) {
2463 i386_fildl_membase(REG_SP, src->regoff * 8);
2468 i386_mov_imm_reg(0, REG_ITMP1);
2469 dseg_adddata(mcodeptr);
2470 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2471 i386_fildl_membase(REG_ITMP1, a);
2474 store_reg_to_var_flt(iptr->dst, d);
2477 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2478 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2480 d = reg_of_var(iptr->dst, REG_FTMP1);
2481 if (src->flags & INMEMORY) {
2482 i386_fildll_membase(REG_SP, src->regoff * 8);
2486 panic("L2F: longs have to be in memory");
2488 store_reg_to_var_flt(iptr->dst, d);
2491 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2493 var_to_reg_flt(s1, src, REG_FTMP1);
2494 d = reg_of_var(iptr->dst, REG_ITMP1);
2496 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2497 i386_mov_imm_reg(0, REG_ITMP1);
2498 dseg_adddata(mcodeptr);
2499 i386_fldcw_membase(REG_ITMP1, a);
2501 if (iptr->dst->flags & INMEMORY) {
2502 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2505 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2506 i386_fldcw_membase(REG_ITMP1, a);
2508 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2511 CALCOFFSETBYTES(a, src->regoff * 8);
2513 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2517 i386_fistpl_membase(REG_ITMP1, a);
2519 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2521 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2522 i386_fldcw_membase(REG_ITMP1, a);
2524 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2527 CALCOFFSETBYTES(a, src->regoff * 8);
2528 a += 5 + 2 + ((REG_RESULT == d) ? 0 : 2);
2531 i386_jcc(I386_CC_NE, a);
2533 /* XXX: change this when we use registers */
2534 i386_flds_membase(REG_SP, src->regoff * 8);
2535 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP2);
2536 i386_call_reg(REG_ITMP2);
2538 if (iptr->dst->flags & INMEMORY) {
2539 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2542 M_INTMOVE(REG_RESULT, d);
2546 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2548 var_to_reg_flt(s1, src, REG_FTMP1);
2549 d = reg_of_var(iptr->dst, REG_ITMP1);
2551 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2552 i386_mov_imm_reg(0, REG_ITMP1);
2553 dseg_adddata(mcodeptr);
2554 i386_fldcw_membase(REG_ITMP1, a);
2556 if (iptr->dst->flags & INMEMORY) {
2557 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2560 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2561 i386_fldcw_membase(REG_ITMP1, a);
2563 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2566 CALCOFFSETBYTES(a, src->regoff * 8);
2568 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2572 i386_fistpl_membase(REG_ITMP1, a);
2574 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2576 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2577 i386_fldcw_membase(REG_ITMP1, a);
2579 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2582 CALCOFFSETBYTES(a, src->regoff * 8);
2583 a += 5 + 2 + ((REG_RESULT == d) ? 0 : 2);
2586 i386_jcc(I386_CC_NE, a);
2588 /* XXX: change this when we use registers */
2589 i386_fldl_membase(REG_SP, src->regoff * 8);
2590 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP2);
2591 i386_call_reg(REG_ITMP2);
2593 if (iptr->dst->flags & INMEMORY) {
2594 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2596 M_INTMOVE(REG_RESULT, d);
2600 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2602 var_to_reg_flt(s1, src, REG_FTMP1);
2603 d = reg_of_var(iptr->dst, REG_ITMP1);
2605 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2606 i386_mov_imm_reg(0, REG_ITMP1);
2607 dseg_adddata(mcodeptr);
2608 i386_fldcw_membase(REG_ITMP1, a);
2610 if (iptr->dst->flags & INMEMORY) {
2611 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2614 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2615 i386_fldcw_membase(REG_ITMP1, a);
2617 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2620 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2622 CALCOFFSETBYTES(a, src->regoff * 8);
2625 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2627 CALCOFFSETBYTES(a, iptr->dst->regoff * 8 + 4);
2629 i386_jcc(I386_CC_NE, a);
2631 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2634 CALCOFFSETBYTES(a, src->regoff * 8);
2636 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2638 i386_jcc(I386_CC_NE, a);
2640 /* XXX: change this when we use registers */
2641 i386_flds_membase(REG_SP, src->regoff * 8);
2642 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP2);
2643 i386_call_reg(REG_ITMP2);
2644 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2645 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2648 panic("F2L: longs have to be in memory");
2652 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2654 var_to_reg_flt(s1, src, REG_FTMP1);
2655 d = reg_of_var(iptr->dst, REG_ITMP1);
2657 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2658 i386_mov_imm_reg(0, REG_ITMP1);
2659 dseg_adddata(mcodeptr);
2660 i386_fldcw_membase(REG_ITMP1, a);
2662 if (iptr->dst->flags & INMEMORY) {
2663 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2666 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2667 i386_fldcw_membase(REG_ITMP1, a);
2669 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2672 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2674 CALCOFFSETBYTES(a, src->regoff * 8);
2677 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2679 CALCOFFSETBYTES(a, iptr->dst->regoff * 8 + 4);
2681 i386_jcc(I386_CC_NE, a);
2683 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2686 CALCOFFSETBYTES(a, src->regoff * 8);
2688 CALCOFFSETBYTES(a, iptr->dst->regoff * 8);
2690 i386_jcc(I386_CC_NE, a);
2692 /* XXX: change this when we use registers */
2693 i386_fldl_membase(REG_SP, src->regoff * 8);
2694 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP2);
2695 i386_call_reg(REG_ITMP2);
2696 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2697 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2700 panic("D2L: longs have to be in memory");
2704 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2706 var_to_reg_flt(s1, src, REG_FTMP1);
2707 d = reg_of_var(iptr->dst, REG_FTMP3);
2709 store_reg_to_var_flt(iptr->dst, d);
2712 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2714 var_to_reg_flt(s1, src, REG_FTMP1);
2715 d = reg_of_var(iptr->dst, REG_FTMP3);
2717 store_reg_to_var_flt(iptr->dst, d);
2720 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2723 /* exchanged to skip fxch */
2724 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2725 var_to_reg_flt(s1, src, REG_FTMP2);
2726 d = reg_of_var(iptr->dst, REG_ITMP2);
2727 i386_alu_reg_reg(I386_XOR, d, d);
2732 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as GT */
2733 i386_jcc(I386_CC_E, 6);
2734 i386_alu_imm_reg(I386_AND, 0x000000ff, I386_EAX);
2736 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2737 i386_jcc(I386_CC_B, 1 + 5);
2741 store_reg_to_var_int(iptr->dst, d);
2744 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2747 /* exchanged to skip fxch */
2748 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2749 var_to_reg_flt(s1, src, REG_FTMP2);
2750 d = reg_of_var(iptr->dst, REG_ITMP2);
2751 i386_alu_reg_reg(I386_XOR, d, d);
2756 i386_test_imm_reg(0x400, I386_EAX); /* unordered treat as LT */
2757 i386_jcc(I386_CC_E, 3);
2758 i386_movb_imm_reg(1, I386_AH);
2760 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2761 i386_jcc(I386_CC_B, 1 + 5);
2765 store_reg_to_var_int(iptr->dst, d);
2769 /* memory operations **************************************************/
2771 #define gen_bound_check \
2772 if (checkbounds) { \
2773 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2774 i386_jcc(I386_CC_AE, 0); \
2775 codegen_addxboundrefs(mcodeptr); \
2778 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2780 var_to_reg_int(s1, src, REG_ITMP1);
2781 d = reg_of_var(iptr->dst, REG_ITMP2);
2782 gen_nullptr_check(s1);
2783 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2784 store_reg_to_var_int(iptr->dst, d);
2787 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2789 var_to_reg_int(s1, src->prev, REG_ITMP1);
2790 var_to_reg_int(s2, src, REG_ITMP2);
2791 d = reg_of_var(iptr->dst, REG_ITMP1);
2792 if (iptr->op1 == 0) {
2793 gen_nullptr_check(s1);
2796 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2797 store_reg_to_var_int(iptr->dst, d);
2800 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2802 var_to_reg_int(s1, src->prev, REG_ITMP1);
2803 var_to_reg_int(s2, src, REG_ITMP2);
2804 d = reg_of_var(iptr->dst, REG_ITMP3);
2805 if (iptr->op1 == 0) {
2806 gen_nullptr_check(s1);
2810 if (iptr->dst->flags & INMEMORY) {
2811 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2812 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2813 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2814 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2818 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2820 var_to_reg_int(s1, src->prev, REG_ITMP1);
2821 var_to_reg_int(s2, src, REG_ITMP2);
2822 d = reg_of_var(iptr->dst, REG_ITMP1);
2823 if (iptr->op1 == 0) {
2824 gen_nullptr_check(s1);
2827 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2828 store_reg_to_var_int(iptr->dst, d);
2831 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2833 var_to_reg_int(s1, src->prev, REG_ITMP1);
2834 var_to_reg_int(s2, src, REG_ITMP2);
2835 d = reg_of_var(iptr->dst, REG_FTMP1);
2836 if (iptr->op1 == 0) {
2837 gen_nullptr_check(s1);
2840 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2842 store_reg_to_var_flt(iptr->dst, d);
2845 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2847 var_to_reg_int(s1, src->prev, REG_ITMP1);
2848 var_to_reg_int(s2, src, REG_ITMP2);
2849 d = reg_of_var(iptr->dst, REG_FTMP3);
2850 if (iptr->op1 == 0) {
2851 gen_nullptr_check(s1);
2854 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2856 store_reg_to_var_flt(iptr->dst, d);
2859 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2861 var_to_reg_int(s1, src->prev, REG_ITMP1);
2862 var_to_reg_int(s2, src, REG_ITMP2);
2863 d = reg_of_var(iptr->dst, REG_ITMP1);
2864 if (iptr->op1 == 0) {
2865 gen_nullptr_check(s1);
2868 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2869 store_reg_to_var_int(iptr->dst, d);
2872 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2874 var_to_reg_int(s1, src->prev, REG_ITMP1);
2875 var_to_reg_int(s2, src, REG_ITMP2);
2876 d = reg_of_var(iptr->dst, REG_ITMP1);
2877 if (iptr->op1 == 0) {
2878 gen_nullptr_check(s1);
2881 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2882 store_reg_to_var_int(iptr->dst, d);
2885 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2887 var_to_reg_int(s1, src->prev, REG_ITMP1);
2888 var_to_reg_int(s2, src, REG_ITMP2);
2889 d = reg_of_var(iptr->dst, REG_ITMP1);
2890 if (iptr->op1 == 0) {
2891 gen_nullptr_check(s1);
2894 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2895 store_reg_to_var_int(iptr->dst, d);
2899 case ICMD_AASTORE: /* ..., 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_objectarray, data[0]), s1, s2, 2);
2911 case ICMD_LASTORE: /* ..., 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);
2920 if (src->flags & INMEMORY) {
2921 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2922 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2923 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2924 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2928 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2930 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2931 var_to_reg_int(s2, src->prev, REG_ITMP2);
2932 if (iptr->op1 == 0) {
2933 gen_nullptr_check(s1);
2936 var_to_reg_int(s3, src, REG_ITMP3);
2937 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2940 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2942 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2943 var_to_reg_int(s2, src->prev, REG_ITMP2);
2944 if (iptr->op1 == 0) {
2945 gen_nullptr_check(s1);
2948 var_to_reg_flt(s3, src, REG_FTMP1);
2949 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2953 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2955 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2956 var_to_reg_int(s2, src->prev, REG_ITMP2);
2957 if (iptr->op1 == 0) {
2958 gen_nullptr_check(s1);
2961 var_to_reg_flt(s3, src, REG_FTMP1);
2962 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2966 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2968 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2969 var_to_reg_int(s2, src->prev, REG_ITMP2);
2970 if (iptr->op1 == 0) {
2971 gen_nullptr_check(s1);
2974 var_to_reg_int(s3, src, REG_ITMP3);
2975 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2978 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2980 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2981 var_to_reg_int(s2, src->prev, REG_ITMP2);
2982 if (iptr->op1 == 0) {
2983 gen_nullptr_check(s1);
2986 var_to_reg_int(s3, src, REG_ITMP3);
2987 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2990 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2992 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2993 var_to_reg_int(s2, src->prev, REG_ITMP2);
2994 if (iptr->op1 == 0) {
2995 gen_nullptr_check(s1);
2998 var_to_reg_int(s3, src, REG_ITMP3);
2999 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
3000 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3004 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3005 /* op1 = type, val.a = field address */
3007 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3008 /* here it's slightly slower */
3009 i386_mov_imm_reg(0, REG_ITMP2);
3010 dseg_adddata(mcodeptr);
3011 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3012 switch (iptr->op1) {
3015 var_to_reg_int(s2, src, REG_ITMP1);
3016 i386_mov_reg_membase(s2, REG_ITMP2, 0);
3019 if (src->flags & INMEMORY) {
3020 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3021 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
3022 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3023 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
3025 panic("PUTSTATIC: longs have to be in memory");
3029 var_to_reg_flt(s2, src, REG_FTMP1);
3030 i386_fstps_membase(REG_ITMP2, 0);
3034 var_to_reg_flt(s2, src, REG_FTMP1);
3035 i386_fstpl_membase(REG_ITMP2, 0);
3038 default: panic ("internal error");
3042 case ICMD_GETSTATIC: /* ... ==> ..., value */
3043 /* op1 = type, val.a = field address */
3045 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3046 i386_mov_imm_reg(0, REG_ITMP2);
3047 dseg_adddata(mcodeptr);
3048 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3049 switch (iptr->op1) {
3052 d = reg_of_var(iptr->dst, REG_ITMP1);
3053 i386_mov_membase_reg(REG_ITMP2, 0, d);
3054 store_reg_to_var_int(iptr->dst, d);
3057 d = reg_of_var(iptr->dst, REG_NULL);
3058 if (iptr->dst->flags & INMEMORY) {
3059 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3060 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3061 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3062 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3064 panic("GETSTATIC: longs have to be in memory");
3068 d = reg_of_var(iptr->dst, REG_FTMP1);
3069 i386_flds_membase(REG_ITMP2, 0);
3071 store_reg_to_var_flt(iptr->dst, d);
3074 d = reg_of_var(iptr->dst, REG_FTMP1);
3075 i386_fldl_membase(REG_ITMP2, 0);
3077 store_reg_to_var_flt(iptr->dst, d);
3079 default: panic ("internal error");
3083 case ICMD_PUTFIELD: /* ..., value ==> ... */
3084 /* op1 = type, val.i = field offset */
3086 a = ((fieldinfo *)(iptr->val.a))->offset;
3087 switch (iptr->op1) {
3090 var_to_reg_int(s1, src->prev, REG_ITMP1);
3091 var_to_reg_int(s2, src, REG_ITMP2);
3092 gen_nullptr_check(s1);
3093 i386_mov_reg_membase(s2, s1, a);
3096 var_to_reg_int(s1, src->prev, REG_ITMP1);
3097 gen_nullptr_check(s1);
3098 if (src->flags & INMEMORY) {
3099 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3100 i386_mov_reg_membase(REG_ITMP2, s1, a);
3101 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3102 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3104 panic("PUTFIELD: longs have to be in memory");
3108 var_to_reg_int(s1, src->prev, REG_ITMP1);
3109 var_to_reg_flt(s2, src, REG_FTMP1);
3110 gen_nullptr_check(s1);
3111 i386_fstps_membase(s1, a);
3115 var_to_reg_int(s1, src->prev, REG_ITMP1);
3116 var_to_reg_flt(s2, src, REG_FTMP1);
3117 gen_nullptr_check(s1);
3118 i386_fstpl_membase(s1, a);
3121 default: panic ("internal error");
3125 case ICMD_GETFIELD: /* ... ==> ..., value */
3126 /* op1 = type, val.i = field offset */
3128 a = ((fieldinfo *)(iptr->val.a))->offset;
3129 switch (iptr->op1) {
3132 var_to_reg_int(s1, src, REG_ITMP1);
3133 d = reg_of_var(iptr->dst, REG_ITMP2);
3134 gen_nullptr_check(s1);
3135 i386_mov_membase_reg(s1, a, d);
3136 store_reg_to_var_int(iptr->dst, d);
3139 var_to_reg_int(s1, src, REG_ITMP1);
3140 d = reg_of_var(iptr->dst, REG_NULL);
3141 gen_nullptr_check(s1);
3142 i386_mov_membase_reg(s1, a, REG_ITMP2);
3143 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3144 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3145 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3148 var_to_reg_int(s1, src, REG_ITMP1);
3149 d = reg_of_var(iptr->dst, REG_FTMP1);
3150 gen_nullptr_check(s1);
3151 i386_flds_membase(s1, a);
3153 store_reg_to_var_flt(iptr->dst, d);
3156 var_to_reg_int(s1, src, REG_ITMP1);
3157 d = reg_of_var(iptr->dst, REG_FTMP1);
3158 gen_nullptr_check(s1);
3159 i386_fldl_membase(s1, a);
3161 store_reg_to_var_flt(iptr->dst, d);
3163 default: panic ("internal error");
3168 /* branch operations **************************************************/
3171 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3172 #define ALIGNCODENOP do {} while (0)
3174 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3176 var_to_reg_int(s1, src, REG_ITMP1);
3177 M_INTMOVE(s1, REG_ITMP1_XPTR);
3179 i386_call_imm(0); /* passing exception pointer */
3180 i386_pop_reg(REG_ITMP2_XPC);
3182 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
3183 i386_jmp_reg(I386_EDI);
3187 case ICMD_GOTO: /* ... ==> ... */
3188 /* op1 = target JavaVM pc */
3191 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3195 case ICMD_JSR: /* ... ==> ... */
3196 /* op1 = target JavaVM pc */
3199 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3202 case ICMD_RET: /* ... ==> ... */
3203 /* op1 = local variable */
3205 var = &(locals[iptr->op1][TYPE_ADR]);
3206 var_to_reg_int(s1, var, REG_ITMP1);
3210 case ICMD_IFNULL: /* ..., value ==> ... */
3211 /* op1 = target JavaVM pc */
3213 if (src->flags & INMEMORY) {
3214 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3217 i386_test_reg_reg(src->regoff, src->regoff);
3219 i386_jcc(I386_CC_E, 0);
3220 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3223 case ICMD_IFNONNULL: /* ..., value ==> ... */
3224 /* op1 = target JavaVM pc */
3226 if (src->flags & INMEMORY) {
3227 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3230 i386_test_reg_reg(src->regoff, src->regoff);
3232 i386_jcc(I386_CC_NE, 0);
3233 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3236 case ICMD_IFEQ: /* ..., value ==> ... */
3237 /* op1 = target JavaVM pc, val.i = constant */
3239 if (src->flags & INMEMORY) {
3240 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3243 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3245 i386_jcc(I386_CC_E, 0);
3246 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3249 case ICMD_IFLT: /* ..., value ==> ... */
3250 /* op1 = target JavaVM pc, val.i = constant */
3252 if (src->flags & INMEMORY) {
3253 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3256 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3258 i386_jcc(I386_CC_L, 0);
3259 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3262 case ICMD_IFLE: /* ..., value ==> ... */
3263 /* op1 = target JavaVM pc, val.i = constant */
3265 if (src->flags & INMEMORY) {
3266 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3269 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3271 i386_jcc(I386_CC_LE, 0);
3272 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3275 case ICMD_IFNE: /* ..., value ==> ... */
3276 /* op1 = target JavaVM pc, val.i = constant */
3278 if (src->flags & INMEMORY) {
3279 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3282 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3284 i386_jcc(I386_CC_NE, 0);
3285 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3288 case ICMD_IFGT: /* ..., value ==> ... */
3289 /* op1 = target JavaVM pc, val.i = constant */
3291 if (src->flags & INMEMORY) {
3292 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3295 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3297 i386_jcc(I386_CC_G, 0);
3298 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3301 case ICMD_IFGE: /* ..., value ==> ... */
3302 /* op1 = target JavaVM pc, val.i = constant */
3304 if (src->flags & INMEMORY) {
3305 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3308 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3310 i386_jcc(I386_CC_GE, 0);
3311 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3314 case ICMD_IF_LEQ: /* ..., value ==> ... */
3315 /* op1 = target JavaVM pc, val.l = constant */
3317 if (src->flags & INMEMORY) {
3318 if (iptr->val.l == 0) {
3319 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3320 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3323 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3324 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3325 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3326 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3327 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3330 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3331 i386_jcc(I386_CC_E, 0);
3332 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3335 case ICMD_IF_LLT: /* ..., value ==> ... */
3336 /* op1 = target JavaVM pc, val.l = constant */
3338 if (src->flags & INMEMORY) {
3339 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3340 i386_jcc(I386_CC_L, 0);
3341 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3344 CALCREGOFFBYTES(a, src->regoff);
3345 CALCIMMEDIATEBYTES(a, iptr->val.l);
3347 i386_jcc(I386_CC_G, a);
3349 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3350 i386_jcc(I386_CC_B, 0);
3351 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3355 case ICMD_IF_LLE: /* ..., value ==> ... */
3356 /* op1 = target JavaVM pc, val.l = constant */
3358 if (src->flags & INMEMORY) {
3359 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3360 i386_jcc(I386_CC_L, 0);
3361 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3364 CALCREGOFFBYTES(a, src->regoff);
3365 CALCIMMEDIATEBYTES(a, iptr->val.l);
3367 i386_jcc(I386_CC_G, a);
3369 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3370 i386_jcc(I386_CC_BE, 0);
3371 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3375 case ICMD_IF_LNE: /* ..., value ==> ... */
3376 /* op1 = target JavaVM pc, val.l = constant */
3378 if (src->flags & INMEMORY) {
3379 if (iptr->val.l == 0) {
3380 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3381 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3384 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3385 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3386 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3387 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3388 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3391 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3392 i386_jcc(I386_CC_NE, 0);
3393 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3396 case ICMD_IF_LGT: /* ..., value ==> ... */
3397 /* op1 = target JavaVM pc, val.l = constant */
3399 if (src->flags & INMEMORY) {
3400 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3401 i386_jcc(I386_CC_G, 0);
3402 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3405 CALCREGOFFBYTES(a, src->regoff);
3406 CALCIMMEDIATEBYTES(a, iptr->val.l);
3408 i386_jcc(I386_CC_L, a);
3410 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3411 i386_jcc(I386_CC_A, 0);
3412 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3416 case ICMD_IF_LGE: /* ..., value ==> ... */
3417 /* op1 = target JavaVM pc, val.l = constant */
3419 if (src->flags & INMEMORY) {
3420 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3421 i386_jcc(I386_CC_G, 0);
3422 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3425 CALCREGOFFBYTES(a, src->regoff);
3426 CALCIMMEDIATEBYTES(a, iptr->val.l);
3428 i386_jcc(I386_CC_L, a);
3430 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3431 i386_jcc(I386_CC_AE, 0);
3432 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3436 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3437 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3439 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3440 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3441 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3443 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3444 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3446 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3447 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3450 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3452 i386_jcc(I386_CC_E, 0);
3453 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3456 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3457 /* op1 = target JavaVM pc */
3459 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3460 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3461 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3462 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3463 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3464 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3465 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3467 i386_jcc(I386_CC_E, 0);
3468 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3471 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3472 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3474 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3475 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3476 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3478 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3479 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3481 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3482 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3485 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3487 i386_jcc(I386_CC_NE, 0);
3488 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3491 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3492 /* op1 = target JavaVM pc */
3494 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3495 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3496 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3497 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3498 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3499 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3500 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3502 i386_jcc(I386_CC_NE, 0);
3503 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3506 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3507 /* op1 = target JavaVM pc */
3509 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3510 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3511 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3513 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3514 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3516 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3517 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3520 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3522 i386_jcc(I386_CC_L, 0);
3523 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3526 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3527 /* op1 = target JavaVM pc */
3529 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3530 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3531 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3532 i386_jcc(I386_CC_L, 0);
3533 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3536 CALCREGOFFBYTES(a, src->prev->regoff);
3537 CALCREGOFFBYTES(a, src->regoff);
3539 i386_jcc(I386_CC_G, a);
3541 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3542 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3543 i386_jcc(I386_CC_B, 0);
3544 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3548 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3549 /* op1 = target JavaVM pc */
3551 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3552 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3553 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3555 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3556 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3558 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3559 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3562 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3564 i386_jcc(I386_CC_G, 0);
3565 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3568 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3569 /* op1 = target JavaVM pc */
3571 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3572 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3573 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3574 i386_jcc(I386_CC_G, 0);
3575 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3578 CALCREGOFFBYTES(a, src->prev->regoff);
3579 CALCREGOFFBYTES(a, src->regoff);
3581 i386_jcc(I386_CC_L, a);
3583 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3584 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3585 i386_jcc(I386_CC_A, 0);
3586 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3590 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3591 /* op1 = target JavaVM pc */
3593 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3594 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3595 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3597 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3598 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3600 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3601 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3604 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3606 i386_jcc(I386_CC_LE, 0);
3607 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3610 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3611 /* op1 = target JavaVM pc */
3613 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3614 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3615 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3616 i386_jcc(I386_CC_L, 0);
3617 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3620 CALCREGOFFBYTES(a, src->prev->regoff);
3621 CALCREGOFFBYTES(a, src->regoff);
3623 i386_jcc(I386_CC_G, a);
3625 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3626 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3627 i386_jcc(I386_CC_BE, 0);
3628 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3632 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3633 /* op1 = target JavaVM pc */
3635 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3636 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3637 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3639 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3640 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3642 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3643 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3646 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3648 i386_jcc(I386_CC_GE, 0);
3649 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3652 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3653 /* op1 = target JavaVM pc */
3655 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3656 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3657 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3658 i386_jcc(I386_CC_G, 0);
3659 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3662 CALCREGOFFBYTES(a, src->prev->regoff);
3663 CALCREGOFFBYTES(a, src->regoff);
3665 i386_jcc(I386_CC_L, a);
3667 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3668 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3669 i386_jcc(I386_CC_AE, 0);
3670 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3674 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3676 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3679 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3680 /* val.i = constant */
3682 d = reg_of_var(iptr->dst, REG_NULL);
3683 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3686 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3687 /* val.i = constant */
3689 d = reg_of_var(iptr->dst, REG_NULL);
3690 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3693 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3694 /* val.i = constant */
3696 d = reg_of_var(iptr->dst, REG_NULL);
3697 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3700 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3701 /* val.i = constant */
3703 d = reg_of_var(iptr->dst, REG_NULL);
3704 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3707 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3708 /* val.i = constant */
3710 d = reg_of_var(iptr->dst, REG_NULL);
3711 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3714 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3715 /* val.i = constant */
3717 d = reg_of_var(iptr->dst, REG_NULL);
3718 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3722 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3726 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3727 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3728 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3729 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3730 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3731 i386_call_reg(REG_ITMP1);
3732 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3735 var_to_reg_int(s1, src, REG_RESULT);
3736 M_INTMOVE(s1, REG_RESULT);
3737 goto nowperformreturn;
3739 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3742 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3743 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3744 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3745 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3746 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3747 i386_call_reg(REG_ITMP1);
3748 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3751 if (src->flags & INMEMORY) {
3752 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3753 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3756 panic("LRETURN: longs have to be in memory");
3758 goto nowperformreturn;
3760 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3763 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3764 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3765 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3766 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3767 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3768 i386_call_reg(REG_ITMP1);
3769 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3772 var_to_reg_flt(s1, src, REG_FRESULT);
3773 /* this may be an early return -- keep the offset correct for the remaining code */
3775 goto nowperformreturn;
3777 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3780 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3781 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3782 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3783 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3784 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3785 i386_call_reg(REG_ITMP1);
3786 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3789 var_to_reg_flt(s1, src, REG_FRESULT);
3790 /* this may be an early return -- keep the offset correct for the remaining code */
3792 goto nowperformreturn;
3794 case ICMD_RETURN: /* ... ==> ... */
3797 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3798 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3799 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3800 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3801 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3802 i386_call_reg(REG_ITMP1);
3803 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3811 p = parentargs_base;
3813 /* restore saved registers */
3814 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3816 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3818 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3820 i386_fldl_membase(REG_SP, p * 8);
3822 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3823 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3825 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3830 /* deallocate stack */
3831 if (parentargs_base) {
3832 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3835 /* call trace function */
3837 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3839 i386_mov_imm_membase((s4) method, REG_SP, 0);
3841 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3842 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3844 i386_fstl_membase(REG_SP, 4 + 8);
3845 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3847 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3848 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3849 i386_call_reg(REG_ITMP1);
3851 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3852 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3854 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3863 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3868 tptr = (void **) iptr->target;
3870 s4ptr = iptr->val.a;
3871 l = s4ptr[1]; /* low */
3872 i = s4ptr[2]; /* high */
3874 var_to_reg_int(s1, src, REG_ITMP1);
3875 M_INTMOVE(s1, REG_ITMP1);
3877 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3883 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3884 i386_jcc(I386_CC_A, 0);
3886 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3887 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3889 /* build jump table top down and use address of lowest entry */
3891 /* s4ptr += 3 + i; */
3895 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3896 dseg_addtarget((basicblock *) tptr[0]);
3900 /* length of dataseg after last dseg_addtarget is used by load */
3902 i386_mov_imm_reg(0, REG_ITMP2);
3903 dseg_adddata(mcodeptr);
3904 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3905 i386_jmp_reg(REG_ITMP1);
3911 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3913 s4 i, l, val, *s4ptr;
3916 tptr = (void **) iptr->target;
3918 s4ptr = iptr->val.a;
3919 l = s4ptr[0]; /* default */
3920 i = s4ptr[1]; /* count */
3922 MCODECHECK((i<<2)+8);
3923 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3929 i386_alu_imm_reg(I386_CMP, val, s1);
3930 i386_jcc(I386_CC_E, 0);
3931 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3932 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3936 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3938 tptr = (void **) iptr->target;
3939 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3946 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3947 /* op1 = return type, val.a = function pointer*/
3951 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3952 /* op1 = return type, val.a = function pointer*/
3956 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3957 /* op1 = return type, val.a = function pointer*/
3961 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3962 /* op1 = arg count, val.a = method pointer */
3964 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3965 /* op1 = arg count, val.a = method pointer */
3967 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3968 /* op1 = arg count, val.a = method pointer */
3970 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3971 /* op1 = arg count, val.a = method pointer */
3979 MCODECHECK((s3 << 1) + 64);
3981 /* copy arguments to registers or stack location */
3983 for (; --s3 >= 0; src = src->prev) {
3984 if (src->varkind == ARGVAR) {
3988 if (IS_INT_LNG_TYPE(src->type)) {
3989 if (s3 < intreg_argnum) {
3990 panic("No integer argument registers available!");
3993 if (!IS_2_WORD_TYPE(src->type)) {
3994 if (src->flags & INMEMORY) {
3995 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3996 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
3999 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4003 if (src->flags & INMEMORY) {
4004 M_LNGMEMMOVE(src->regoff, s3);
4007 panic("copy arguments: longs have to be in memory");
4013 if (s3 < fltreg_argnum) {
4014 panic("No float argument registers available!");
4017 var_to_reg_flt(d, src, REG_FTMP1);
4018 if (src->type == TYPE_FLT) {
4019 i386_fstps_membase(REG_SP, s3 * 8);
4022 i386_fstpl_membase(REG_SP, s3 * 8);
4029 switch (iptr->opc) {
4037 i386_mov_imm_reg(a, REG_ITMP1);
4038 i386_call_reg(REG_ITMP1);
4041 case ICMD_INVOKESTATIC:
4043 a = (s4) m->stubroutine;
4046 i386_mov_imm_reg(a, REG_ITMP2);
4047 i386_call_reg(REG_ITMP2);
4050 case ICMD_INVOKESPECIAL:
4052 a = (s4) m->stubroutine;
4055 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4056 gen_nullptr_check(REG_ITMP1);
4057 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4059 i386_mov_imm_reg(a, REG_ITMP2);
4060 i386_call_reg(REG_ITMP2);
4063 case ICMD_INVOKEVIRTUAL:
4067 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4068 gen_nullptr_check(REG_ITMP1);
4069 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4070 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4072 i386_call_reg(REG_ITMP1);
4075 case ICMD_INVOKEINTERFACE:
4080 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4081 gen_nullptr_check(REG_ITMP1);
4082 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4083 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4084 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4086 i386_call_reg(REG_ITMP1);
4091 sprintf(logtext, "Unkown ICMD-Command: %d", iptr->opc);
4095 /* d contains return type */
4097 if (d != TYPE_VOID) {
4098 d = reg_of_var(iptr->dst, REG_NULL);
4100 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4101 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4102 if (iptr->dst->flags & INMEMORY) {
4103 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4104 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4107 panic("RETURN: longs have to be in memory");
4111 if (iptr->dst->flags & INMEMORY) {
4112 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4115 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4120 /* fld from called function -- has other fpu_st_offset counter */
4122 store_reg_to_var_flt(iptr->dst, d);
4129 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4131 /* op1: 0 == array, 1 == class */
4132 /* val.a: (classinfo*) superclass */
4134 /* superclass is an interface:
4136 * return (sub != NULL) &&
4137 * (sub->vftbl->interfacetablelength > super->index) &&
4138 * (sub->vftbl->interfacetable[-super->index] != NULL);
4140 * superclass is a class:
4142 * return ((sub != NULL) && (0
4143 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4144 * super->vftbl->diffvall));
4148 classinfo *super = (classinfo*) iptr->val.a;
4150 var_to_reg_int(s1, src, REG_ITMP1);
4151 d = reg_of_var(iptr->dst, REG_ITMP3);
4153 M_INTMOVE(s1, REG_ITMP1);
4156 i386_alu_reg_reg(I386_XOR, d, d);
4157 if (iptr->op1) { /* class/interface */
4158 if (super->flags & ACC_INTERFACE) { /* interface */
4159 i386_test_reg_reg(s1, s1);
4161 /* TODO: clean up this calculation */
4163 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4166 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4169 CALCOFFSETBYTES(a, super->index);
4175 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4182 i386_jcc(I386_CC_E, a);
4184 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4185 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4186 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4188 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4190 /* TODO: clean up this calculation */
4193 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4200 i386_jcc(I386_CC_LE, a);
4201 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4203 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4204 /* i386_setcc_reg(I386_CC_A, d); */
4205 /* i386_jcc(I386_CC_BE, 5); */
4206 i386_jcc(I386_CC_E, 5);
4207 i386_mov_imm_reg(1, d);
4210 } else { /* class */
4211 i386_test_reg_reg(s1, s1);
4213 /* TODO: clean up this calculation */
4215 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4218 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4220 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4223 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4233 i386_jcc(I386_CC_E, a);
4235 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4236 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4237 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4238 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4239 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4240 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4241 i386_alu_reg_reg(I386_XOR, d, d);
4242 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4243 i386_jcc(I386_CC_A, 5);
4244 i386_mov_imm_reg(1, d);
4248 panic ("internal error: no inlined array instanceof");
4250 store_reg_to_var_int(iptr->dst, d);
4253 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4255 /* op1: 0 == array, 1 == class */
4256 /* val.a: (classinfo*) superclass */
4258 /* superclass is an interface:
4260 * OK if ((sub == NULL) ||
4261 * (sub->vftbl->interfacetablelength > super->index) &&
4262 * (sub->vftbl->interfacetable[-super->index] != NULL));
4264 * superclass is a class:
4266 * OK if ((sub == NULL) || (0
4267 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4268 * super->vftbl->diffvall));
4272 classinfo *super = (classinfo*) iptr->val.a;
4274 d = reg_of_var(iptr->dst, REG_ITMP3);
4275 var_to_reg_int(s1, src, d);
4276 if (iptr->op1) { /* class/interface */
4277 if (super->flags & ACC_INTERFACE) { /* interface */
4278 i386_test_reg_reg(s1, s1);
4280 /* TODO: clean up this calculation */
4282 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4285 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetablelength));
4288 CALCOFFSETBYTES(a, super->index);
4294 CALCOFFSETBYTES(a, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4299 i386_jcc(I386_CC_E, a);
4301 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4302 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4303 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4305 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4306 i386_jcc(I386_CC_LE, 0);
4307 codegen_addxcastrefs(mcodeptr);
4308 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4310 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4311 i386_jcc(I386_CC_E, 0);
4312 codegen_addxcastrefs(mcodeptr);
4314 } else { /* class */
4315 i386_test_reg_reg(s1, s1);
4317 /* TODO: clean up this calculation */
4319 CALCOFFSETBYTES(a, OFFSET(java_objectheader, vftbl));
4324 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4326 if (d != REG_ITMP3) {
4328 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4331 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4337 CALCOFFSETBYTES(a, OFFSET(vftbl, baseval));
4344 CALCOFFSETBYTES(a, OFFSET(vftbl, diffval));
4351 i386_jcc(I386_CC_E, a);
4353 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4354 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4355 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4356 if (d != REG_ITMP3) {
4357 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4358 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4359 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4362 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4363 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4364 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4365 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4367 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4368 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4369 codegen_addxcastrefs(mcodeptr);
4373 panic ("internal error: no inlined array checkcast");
4376 store_reg_to_var_int(iptr->dst, d);
4379 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4381 if (src->flags & INMEMORY) {
4382 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4385 i386_test_reg_reg(src->regoff, src->regoff);
4387 i386_jcc(I386_CC_L, 0);
4388 codegen_addxcheckarefs(mcodeptr);
4391 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4392 /* op1 = dimension, val.a = array descriptor */
4394 /* check for negative sizes and copy sizes to stack if necessary */
4396 MCODECHECK((iptr->op1 << 1) + 64);
4398 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4399 if (src->flags & INMEMORY) {
4400 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4403 i386_test_reg_reg(src->regoff, src->regoff);
4405 i386_jcc(I386_CC_L, 0);
4406 codegen_addxcheckarefs(mcodeptr);
4409 * copy sizes to new stack location, be cause native function
4410 * builtin_nmultianewarray access them as (int *)
4412 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4413 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4415 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4417 if (src->varkind != ARGVAR) {
4418 if (src->flags & INMEMORY) {
4419 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4420 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4423 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4427 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4429 /* a0 = dimension count */
4431 /* save stack pointer */
4432 M_INTMOVE(REG_SP, REG_ITMP1);
4434 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4435 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4437 /* a1 = arraydescriptor */
4439 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4441 /* a2 = pointer to dimensions = stack pointer */
4443 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4445 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4446 i386_call_reg(REG_ITMP1);
4447 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4449 s1 = reg_of_var(iptr->dst, REG_RESULT);
4450 M_INTMOVE(REG_RESULT, s1);
4451 store_reg_to_var_int(iptr->dst, s1);
4455 default: sprintf (logtext, "Unknown pseudo command: %d", iptr->opc);
4462 } /* for instruction */
4464 /* copy values to interface registers */
4466 src = bptr->outstack;
4467 len = bptr->outdepth;
4471 if ((src->varkind != STACKVAR)) {
4473 if (IS_FLT_DBL_TYPE(s2)) {
4474 var_to_reg_flt(s1, src, REG_FTMP1);
4475 if (!(interfaces[len][s2].flags & INMEMORY)) {
4476 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4479 panic("double store");
4480 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4484 var_to_reg_int(s1, src, REG_ITMP1);
4485 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4486 if (!(interfaces[len][s2].flags & INMEMORY)) {
4487 M_INTMOVE(s1, interfaces[len][s2].regoff);
4490 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4494 if (interfaces[len][s2].flags & INMEMORY) {
4495 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4498 panic("copy interface registers: longs have to be in memory (end)");
4505 } /* if (bptr -> flags >= BBREACHED) */
4506 } /* for basic block */
4508 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4512 /* generate bound check stubs */
4513 u1 *xcodeptr = NULL;
4515 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4516 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4517 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4518 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4523 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4524 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4528 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4529 dseg_adddata(mcodeptr);
4530 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4531 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4533 if (xcodeptr != NULL) {
4534 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4537 xcodeptr = mcodeptr;
4539 i386_mov_imm_reg((s4) proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
4540 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4541 i386_jmp_reg(I386_EDI);
4545 /* generate negative array size check stubs */
4548 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4549 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4550 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4551 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4555 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4556 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4560 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4561 dseg_adddata(mcodeptr);
4562 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4563 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4565 if (xcodeptr != NULL) {
4566 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4569 xcodeptr = mcodeptr;
4571 i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
4572 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4573 i386_jmp_reg(I386_EDI);
4577 /* generate cast check stubs */
4580 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4581 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4582 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4583 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4587 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4588 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4592 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4593 dseg_adddata(mcodeptr);
4594 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4595 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4597 if (xcodeptr != NULL) {
4598 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4601 xcodeptr = mcodeptr;
4603 i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
4604 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4605 i386_jmp_reg(I386_EDI);
4609 /* generate divide by zero check stubs */
4612 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4613 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4614 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4615 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4619 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4620 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4624 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4625 dseg_adddata(mcodeptr);
4626 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4627 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4629 if (xcodeptr != NULL) {
4630 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4633 xcodeptr = mcodeptr;
4635 i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
4636 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4637 i386_jmp_reg(I386_EDI);
4641 /* generate null pointer check stubs */
4644 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4645 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4646 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4647 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4651 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4652 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4656 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4657 dseg_adddata(mcodeptr);
4658 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4659 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4661 if (xcodeptr != NULL) {
4662 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4665 xcodeptr = mcodeptr;
4667 i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
4668 i386_mov_imm_reg((s4) asm_handle_exception, I386_EDI);
4669 i386_jmp_reg(I386_EDI);
4674 codegen_finish((int)((u1*) mcodeptr - mcodebase));
4678 /* function createcompilerstub *************************************************
4680 creates a stub routine which calls the compiler
4682 *******************************************************************************/
4684 #define COMPSTUBSIZE 12
4686 u1 *createcompilerstub(methodinfo *m)
4688 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4689 mcodeptr = s; /* code generation pointer */
4691 /* code for the stub */
4692 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4694 /* we use EDI cause EDX (REG_ITMP2) is used for patching */
4695 i386_mov_imm_reg((s4) asm_call_jit_compiler, I386_EDI); /* load address */
4696 i386_jmp_reg(I386_EDI); /* jump to compiler */
4699 count_cstub_len += COMPSTUBSIZE;
4706 /* function removecompilerstub *************************************************
4708 deletes a compilerstub from memory (simply by freeing it)
4710 *******************************************************************************/
4712 void removecompilerstub(u1 *stub)
4714 CFREE(stub, COMPSTUBSIZE);
4717 /* function: createnativestub **************************************************
4719 creates a stub routine which calls a native method
4721 *******************************************************************************/
4723 #define NATIVESTUBSIZE 320
4724 #define NATIVESTUBOFFSET 9
4726 u1 *createnativestub(functionptr f, methodinfo *m)
4728 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4732 int stackframesize = 4; /* initial 4 bytes is space for jni env */
4733 int stackframeoffset = 4;
4736 u8 *cs=((u8*)s)+NATIVESTUBOFFSET;
4738 *(cs-1) = (u8) f; /* address of native method */
4739 *(cs-2) = (u8) (&exceptionptr); /* address of exceptionptr */
4740 *(cs-3) = (u8) asm_handle_nat_exception; /* addr of asm exception handler */
4741 *(cs-4) = (u8) (&env); /* addr of jni_environement */
4742 *(cs-5) = (u8) asm_builtin_trace;
4744 *(cs-7) = (u8) asm_builtin_exittrace;
4745 *(cs-8) = (u8) builtin_trace_exception;
4746 *(cs-9) = (u8) m->class;
4748 mcodeptr = (u1*)cs; /* make macros work */
4750 if (m->flags & ACC_STATIC) {
4751 stackframesize += 4;
4752 stackframeoffset += 4;
4758 descriptor2types(m); /* set paramcount and paramtypes */
4761 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4763 for (p = 0; p < m->paramcount; p++) {
4764 t = m->paramtypes[p];
4765 if (IS_INT_LNG_TYPE(t)) {
4766 if (IS_2_WORD_TYPE(t)) {
4767 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4768 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4770 } else if (t == TYPE_ADR) {
4771 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4772 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4775 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4778 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4779 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4782 if (t == TYPE_FLT) {
4783 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4784 i386_fstps_membase(REG_SP, p * 8);
4785 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4786 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4789 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4790 i386_fstpl_membase(REG_SP, p * 8);
4796 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4797 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4798 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4799 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4802 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4804 i386_mov_imm_reg((s4) asm_builtin_trace, REG_ITMP1);
4805 i386_call_reg(REG_ITMP1);
4807 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4811 * mark the whole fpu stack as free for native functions
4812 * (only for saved register count == 0)
4824 * calculate stackframe size for native function
4826 tptr = m->paramtypes;
4827 for (i = 0; i < m->paramcount; i++) {
4832 stackframesize += 4;
4837 stackframesize += 8;
4841 panic("unknown parameter type in native function");
4845 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4847 tptr = m->paramtypes;
4848 for (i = 0; i < m->paramcount; i++) {
4853 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4854 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4855 stackframeoffset += 4;
4860 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4861 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
4862 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4863 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
4864 stackframeoffset += 8;
4868 panic("unknown parameter type in native function");
4872 i386_mov_imm_membase((s4) &env, REG_SP, 0);
4873 if (m->flags & ACC_STATIC)
4874 i386_mov_imm_membase((s4) m->class, REG_SP,4);
4876 i386_mov_imm_reg((s4) f, REG_ITMP1);
4877 i386_call_reg(REG_ITMP1);
4878 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
4881 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4883 i386_mov_imm_membase((s4) m, REG_SP, 0);
4885 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4886 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4888 i386_fstl_membase(REG_SP, 4 + 8);
4889 i386_fsts_membase(REG_SP, 4 + 8 + 8);
4891 i386_mov_imm_reg((s4) asm_builtin_exittrace, REG_ITMP1);
4892 i386_call_reg(REG_ITMP1);
4894 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4895 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4897 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4900 /* we can use EDI cause it's not preserved across function calls */
4901 i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4902 i386_mov_membase_reg(I386_EDI, 0, I386_EDI);
4903 i386_test_reg_reg(I386_EDI, I386_EDI);
4904 i386_jcc(I386_CC_NE, 1);
4908 i386_mov_reg_reg(I386_EDI, REG_ITMP1_XPTR);
4909 i386_mov_imm_reg((s4) &exceptionptr, I386_EDI);
4910 i386_mov_imm_membase(0, I386_EDI, 0);
4911 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
4912 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
4914 i386_mov_imm_reg((s4) asm_handle_nat_exception, I386_EDI);
4915 i386_jmp_reg(I386_EDI);
4918 count_nstub_len += NATIVESTUBSIZE;
4924 /* function: removenativestub **************************************************
4926 removes a previously created native-stub from memory
4928 *******************************************************************************/
4930 void removenativestub(u1 *stub)
4932 CFREE(((u8*)stub)-NATIVESTUBOFFSET, NATIVESTUBSIZE);
4937 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
4939 if (iptr->dst->flags & INMEMORY) {
4940 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4941 if (src->regoff == iptr->dst->regoff) {
4942 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4943 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4945 } else if (src->prev->regoff == iptr->dst->regoff) {
4946 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4947 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4950 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4951 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
4952 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4955 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4956 if (src->regoff == iptr->dst->regoff) {
4957 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4960 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4961 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
4962 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4965 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4966 if (src->prev->regoff == iptr->dst->regoff) {
4967 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4970 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4971 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
4972 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4976 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4977 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4981 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4982 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4983 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4985 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4986 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4987 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4989 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4990 M_INTMOVE(src->regoff, iptr->dst->regoff);
4991 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4994 if (src->regoff == iptr->dst->regoff) {
4995 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
4998 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4999 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
5007 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
5009 if (iptr->dst->flags & INMEMORY) {
5010 if (src->flags & INMEMORY) {
5011 if (src->regoff == iptr->dst->regoff) {
5012 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5015 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5016 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
5017 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5021 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5022 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5026 if (src->flags & INMEMORY) {
5027 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5028 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5031 M_INTMOVE(src->regoff, iptr->dst->regoff);
5032 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5039 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
5041 if (iptr->dst->flags & INMEMORY) {
5042 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5043 if (src->regoff == iptr->dst->regoff) {
5044 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5045 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
5046 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5047 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5049 } else if (src->prev->regoff == iptr->dst->regoff) {
5050 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5051 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5052 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5053 i386_alu_reg_membase(alu_op, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5056 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5057 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
5058 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5059 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5060 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5061 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5069 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5071 if (iptr->dst->flags & INMEMORY) {
5072 if (src->flags & INMEMORY) {
5073 if (src->regoff == iptr->dst->regoff) {
5074 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5075 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5078 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5079 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
5080 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5081 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP2);
5082 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5083 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
5091 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5093 if (iptr->dst->flags & INMEMORY) {
5094 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5095 if (src->prev->regoff == iptr->dst->regoff) {
5096 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5097 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5100 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5101 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5102 i386_shift_reg(shift_op, REG_ITMP1);
5103 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5106 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5107 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5108 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5109 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5111 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5112 if (src->prev->regoff == iptr->dst->regoff) {
5113 M_INTMOVE(src->regoff, I386_ECX);
5114 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5117 M_INTMOVE(src->regoff, I386_ECX);
5118 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5119 i386_shift_reg(shift_op, REG_ITMP1);
5120 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5124 M_INTMOVE(src->regoff, I386_ECX);
5125 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5126 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5130 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5131 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5132 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5133 i386_shift_reg(shift_op, iptr->dst->regoff);
5135 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5136 i386_mov_membase_reg(REG_SP, src->regoff * 8, I386_ECX);
5137 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5138 i386_shift_reg(shift_op, iptr->dst->regoff);
5140 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5141 M_INTMOVE(src->regoff, I386_ECX);
5142 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5143 i386_shift_reg(shift_op, iptr->dst->regoff);
5146 M_INTMOVE(src->regoff, I386_ECX);
5147 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5148 i386_shift_reg(shift_op, iptr->dst->regoff);
5155 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5157 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5158 if (src->regoff == iptr->dst->regoff) {
5159 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5162 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5163 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5164 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5167 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5168 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5169 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5171 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5172 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5173 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5176 M_INTMOVE(src->regoff, iptr->dst->regoff);
5177 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5183 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5185 if (iptr->dst->flags & INMEMORY) {
5188 if (src->flags & INMEMORY) {
5189 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5192 i386_test_reg_reg(src->regoff, src->regoff);
5196 CALCOFFSETBYTES(offset, iptr->dst->regoff * 8);
5198 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5199 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5201 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5202 i386_jmp_imm(offset);
5203 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5207 if (src->flags & INMEMORY) {
5208 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5211 i386_test_reg_reg(src->regoff, src->regoff);
5214 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5215 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5217 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5219 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5229 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5230 *(mcodeptr++) = (u1) 0x89;
5231 i386_emit_reg((reg),(dreg));
5235 void i386_mov_imm_reg(s4 imm, s4 reg) {
5236 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5237 i386_emit_imm32((imm));
5241 void i386_movb_imm_reg(s4 imm, s4 reg) {
5242 *(mcodeptr++) = (u1) 0xc6;
5243 i386_emit_reg(0,(reg));
5244 i386_emit_imm8((imm));
5248 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5249 *(mcodeptr++) = (u1) 0x8b;
5250 i386_emit_membase((basereg),(disp),(reg));
5255 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5256 * constant membase immediate length of 32bit
5258 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5259 *(mcodeptr++) = (u1) 0x8b;
5260 i386_address_byte(2, (reg), (basereg));
5261 i386_emit_imm32((disp));
5265 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5266 *(mcodeptr++) = (u1) 0x89;
5267 i386_emit_membase((basereg),(disp),(reg));
5271 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5272 *(mcodeptr++) = (u1) 0x8b;
5273 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5277 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5278 *(mcodeptr++) = (u1) 0x89;
5279 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5283 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5284 *(mcodeptr++) = (u1) 0x66;
5285 *(mcodeptr++) = (u1) 0x89;
5286 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5290 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5291 *(mcodeptr++) = (u1) 0x88;
5292 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5296 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5297 *(mcodeptr++) = (u1) 0xc7;
5298 i386_emit_membase((basereg),(disp),0);
5299 i386_emit_imm32((imm));
5303 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5304 *(mcodeptr++) = (u1) 0x0f;
5305 *(mcodeptr++) = (u1) 0xbe;
5306 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5310 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5311 *(mcodeptr++) = (u1) 0x0f;
5312 *(mcodeptr++) = (u1) 0xbf;
5313 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5317 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5318 *(mcodeptr++) = (u1) 0x0f;
5319 *(mcodeptr++) = (u1) 0xb7;
5320 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5328 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5329 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5330 i386_emit_reg((reg),(dreg));
5334 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5335 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5336 i386_emit_membase((basereg),(disp),(reg));
5340 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5341 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5342 i386_emit_membase((basereg),(disp),(reg));
5346 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5347 if (i386_is_imm8(imm)) {
5348 *(mcodeptr++) = (u1) 0x83;
5349 i386_emit_reg((opc),(dreg));
5350 i386_emit_imm8((imm));
5352 *(mcodeptr++) = (u1) 0x81;
5353 i386_emit_reg((opc),(dreg));
5354 i386_emit_imm32((imm));
5359 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5360 if (i386_is_imm8(imm)) {
5361 *(mcodeptr++) = (u1) 0x83;
5362 i386_emit_membase((basereg),(disp),(opc));
5363 i386_emit_imm8((imm));
5365 *(mcodeptr++) = (u1) 0x81;
5366 i386_emit_membase((basereg),(disp),(opc));
5367 i386_emit_imm32((imm));
5372 void i386_test_reg_reg(s4 reg, s4 dreg) {
5373 *(mcodeptr++) = (u1) 0x85;
5374 i386_emit_reg((reg),(dreg));
5378 void i386_test_imm_reg(s4 imm, s4 reg) {
5379 *(mcodeptr++) = (u1) 0xf7;
5380 i386_emit_reg(0,(reg));
5381 i386_emit_imm32((imm));
5387 * inc, dec operations
5389 void i386_inc_reg(s4 reg) {
5390 *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
5394 void i386_inc_membase(s4 basereg, s4 disp) {
5395 *(mcodeptr++) = (u1) 0xff;
5396 i386_emit_membase((basereg),(disp),0);
5400 void i386_dec_reg(s4 reg) {
5401 *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
5405 void i386_dec_membase(s4 basereg, s4 disp) {
5406 *(mcodeptr++) = (u1) 0xff;
5407 i386_emit_membase((basereg),(disp),1);
5413 *(mcodeptr++) = (u1) 0x99;
5418 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5419 *(mcodeptr++) = (u1) 0x0f;
5420 *(mcodeptr++) = (u1) 0xaf;
5421 i386_emit_reg((dreg),(reg));
5425 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5426 *(mcodeptr++) = (u1) 0x0f;
5427 *(mcodeptr++) = (u1) 0xaf;
5428 i386_emit_membase((basereg),(disp),(dreg));
5432 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5433 if (i386_is_imm8((imm))) {
5434 *(mcodeptr++) = (u1) 0x6b;
5435 i386_emit_reg(0,(dreg));
5436 i386_emit_imm8((imm));
5438 *(mcodeptr++) = (u1) 0x69;
5439 i386_emit_reg(0,(dreg));
5440 i386_emit_imm32((imm));
5445 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5446 if (i386_is_imm8((imm))) {
5447 *(mcodeptr++) = (u1) 0x6b;
5448 i386_emit_reg((dreg),(reg));
5449 i386_emit_imm8((imm));
5451 *(mcodeptr++) = (u1) 0x69;
5452 i386_emit_reg((dreg),(reg));
5453 i386_emit_imm32((imm));
5458 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5459 if (i386_is_imm8((imm))) {
5460 *(mcodeptr++) = (u1) 0x6b;
5461 i386_emit_membase((basereg),(disp),(dreg));
5462 i386_emit_imm8((imm));
5464 *(mcodeptr++) = (u1) 0x69;
5465 i386_emit_membase((basereg),(disp),(dreg));
5466 i386_emit_imm32((imm));
5471 void i386_mul_membase(s4 basereg, s4 disp) {
5472 *(mcodeptr++) = (u1) 0xf7;
5473 i386_emit_membase((basereg),(disp),4);
5477 void i386_idiv_reg(s4 reg) {
5478 *(mcodeptr++) = (u1) 0xf7;
5479 i386_emit_reg(7,(reg));
5485 *(mcodeptr++) = (u1) 0xc3;
5493 void i386_shift_reg(s4 opc, s4 reg) {
5494 *(mcodeptr++) = (u1) 0xd3;
5495 i386_emit_reg((opc),(reg));
5499 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5500 *(mcodeptr++) = (u1) 0xd3;
5501 i386_emit_membase((basereg),(disp),(opc));
5505 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5507 *(mcodeptr++) = (u1) 0xd1;
5508 i386_emit_reg((opc),(dreg));
5510 *(mcodeptr++) = (u1) 0xc1;
5511 i386_emit_reg((opc),(dreg));
5512 i386_emit_imm8((imm));
5517 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5519 *(mcodeptr++) = (u1) 0xd1;
5520 i386_emit_membase((basereg),(disp),(opc));
5522 *(mcodeptr++) = (u1) 0xc1;
5523 i386_emit_membase((basereg),(disp),(opc));
5524 i386_emit_imm8((imm));
5529 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5530 *(mcodeptr++) = (u1) 0x0f;
5531 *(mcodeptr++) = (u1) 0xa5;
5532 i386_emit_reg((reg),(dreg));
5536 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5537 *(mcodeptr++) = (u1) 0x0f;
5538 *(mcodeptr++) = (u1) 0xa4;
5539 i386_emit_reg((reg),(dreg));
5540 i386_emit_imm8((imm));
5544 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5545 *(mcodeptr++) = (u1) 0x0f;
5546 *(mcodeptr++) = (u1) 0xa5;
5547 i386_emit_membase((basereg),(disp),(reg));
5551 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5552 *(mcodeptr++) = (u1) 0x0f;
5553 *(mcodeptr++) = (u1) 0xad;
5554 i386_emit_reg((reg),(dreg));
5558 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5559 *(mcodeptr++) = (u1) 0x0f;
5560 *(mcodeptr++) = (u1) 0xac;
5561 i386_emit_reg((reg),(dreg));
5562 i386_emit_imm8((imm));
5566 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5567 *(mcodeptr++) = (u1) 0x0f;
5568 *(mcodeptr++) = (u1) 0xad;
5569 i386_emit_membase((basereg),(disp),(reg));
5577 void i386_jmp_imm(s4 imm) {
5578 *(mcodeptr++) = (u1) 0xe9;
5579 i386_emit_imm32((imm));
5583 void i386_jmp_reg(s4 reg) {
5584 *(mcodeptr++) = (u1) 0xff;
5585 i386_emit_reg(4,(reg));
5589 void i386_jcc(s4 opc, s4 imm) {
5590 *(mcodeptr++) = (u1) 0x0f;
5591 *(mcodeptr++) = (u1) (0x80 + (opc));
5592 i386_emit_imm32((imm));
5598 * conditional set operations
5600 void i386_setcc_reg(s4 opc, s4 reg) {
5601 *(mcodeptr++) = (u1) 0x0f;
5602 *(mcodeptr++) = (u1) (0x90 + (opc));
5603 i386_emit_reg(0,(reg));
5607 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5608 *(mcodeptr++) = (u1) 0x0f;
5609 *(mcodeptr++) = (u1) (0x90 + (opc));
5610 i386_emit_membase((basereg),(disp),0);
5615 void i386_neg_reg(s4 reg) {
5616 *(mcodeptr++) = (u1) 0xf7;
5617 i386_emit_reg(3,(reg));
5621 void i386_neg_membase(s4 basereg, s4 disp) {
5622 *(mcodeptr++) = (u1) 0xf7;
5623 i386_emit_membase((basereg),(disp),3);
5628 void i386_push_imm(s4 imm) {
5629 *(mcodeptr++) = (u1) 0x68;
5630 i386_emit_imm32((imm));
5634 void i386_pop_reg(s4 reg) {
5635 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5640 *(mcodeptr++) = (u1) 0x90;
5647 void i386_call_reg(s4 reg) {
5648 *(mcodeptr++) = (u1) 0xff;
5649 i386_emit_reg(2,(reg));
5653 void i386_call_imm(s4 imm) {
5654 *(mcodeptr++) = (u1) 0xe8;
5655 i386_emit_imm32((imm));
5661 * floating point instructions
5664 *(mcodeptr++) = (u1) 0xd9;
5665 *(mcodeptr++) = (u1) 0xe8;
5670 *(mcodeptr++) = (u1) 0xd9;
5671 *(mcodeptr++) = (u1) 0xee;
5675 void i386_fld_reg(s4 reg) {
5676 *(mcodeptr++) = (u1) 0xd9;
5677 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5681 void i386_flds_membase(s4 basereg, s4 disp) {
5682 *(mcodeptr++) = (u1) 0xd9;
5683 i386_emit_membase((basereg),(disp),0);
5687 void i386_fldl_membase(s4 basereg, s4 disp) {
5688 *(mcodeptr++) = (u1) 0xdd;
5689 i386_emit_membase((basereg),(disp),0);
5693 void i386_fldt_membase(s4 basereg, s4 disp) {
5694 *(mcodeptr++) = (u1) 0xdb;
5695 i386_emit_membase((basereg),(disp),5);
5699 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5700 *(mcodeptr++) = (u1) 0xd9;
5701 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5705 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5706 *(mcodeptr++) = (u1) 0xdd;
5707 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5713 void i386_fildl_membase(s4 basereg, s4 disp) {
5714 *(mcodeptr++) = (u1) 0xdb;
5715 i386_emit_membase((basereg),(disp),0);
5719 void i386_fildll_membase(s4 basereg, s4 disp) {
5720 *(mcodeptr++) = (u1) 0xdf;
5721 i386_emit_membase((basereg),(disp),5);
5727 void i386_fst_reg(s4 reg) {
5728 *(mcodeptr++) = (u1) 0xdd;
5729 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5733 void i386_fsts_membase(s4 basereg, s4 disp) {
5734 *(mcodeptr++) = (u1) 0xd9;
5735 i386_emit_membase((basereg),(disp),2);
5739 void i386_fstl_membase(s4 basereg, s4 disp) {
5740 *(mcodeptr++) = (u1) 0xdd;
5741 i386_emit_membase((basereg),(disp),2);
5745 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5746 *(mcodeptr++) = (u1) 0xd9;
5747 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5751 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5752 *(mcodeptr++) = (u1) 0xdd;
5753 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5757 void i386_fstp_reg(s4 reg) {
5758 *(mcodeptr++) = (u1) 0xdd;
5759 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5763 void i386_fstps_membase(s4 basereg, s4 disp) {
5764 *(mcodeptr++) = (u1) 0xd9;
5765 i386_emit_membase((basereg),(disp),3);
5769 void i386_fstpl_membase(s4 basereg, s4 disp) {
5770 *(mcodeptr++) = (u1) 0xdd;
5771 i386_emit_membase((basereg),(disp),3);
5775 void i386_fstpt_membase(s4 basereg, s4 disp) {
5776 *(mcodeptr++) = (u1) 0xdb;
5777 i386_emit_membase((basereg),(disp),7);
5781 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5782 *(mcodeptr++) = (u1) 0xd9;
5783 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5787 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5788 *(mcodeptr++) = (u1) 0xdd;
5789 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5793 void i386_fistl_membase(s4 basereg, s4 disp) {
5794 *(mcodeptr++) = (u1) 0xdb;
5795 i386_emit_membase((basereg),(disp),2);
5799 void i386_fistpl_membase(s4 basereg, s4 disp) {
5800 *(mcodeptr++) = (u1) 0xdb;
5801 i386_emit_membase((basereg),(disp),3);
5805 void i386_fistpll_membase(s4 basereg, s4 disp) {
5806 *(mcodeptr++) = (u1) 0xdf;
5807 i386_emit_membase((basereg),(disp),7);
5812 *(mcodeptr++) = (u1) 0xd9;
5813 *(mcodeptr++) = (u1) 0xe0;
5818 *(mcodeptr++) = (u1) 0xde;
5819 *(mcodeptr++) = (u1) 0xc1;
5823 void i386_fadd_reg_st(s4 reg) {
5824 *(mcodeptr++) = (u1) 0xd8;
5825 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5829 void i386_fadd_st_reg(s4 reg) {
5830 *(mcodeptr++) = (u1) 0xdc;
5831 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5835 void i386_faddp_st_reg(s4 reg) {
5836 *(mcodeptr++) = (u1) 0xde;
5837 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5841 void i386_fadds_membase(s4 basereg, s4 disp) {
5842 *(mcodeptr++) = (u1) 0xd8;
5843 i386_emit_membase((basereg),(disp),0);
5847 void i386_faddl_membase(s4 basereg, s4 disp) {
5848 *(mcodeptr++) = (u1) 0xdc;
5849 i386_emit_membase((basereg),(disp),0);
5853 void i386_fsub_reg_st(s4 reg) {
5854 *(mcodeptr++) = (u1) 0xd8;
5855 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5859 void i386_fsub_st_reg(s4 reg) {
5860 *(mcodeptr++) = (u1) 0xdc;
5861 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5865 void i386_fsubp_st_reg(s4 reg) {
5866 *(mcodeptr++) = (u1) 0xde;
5867 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5872 *(mcodeptr++) = (u1) 0xde;
5873 *(mcodeptr++) = (u1) 0xe9;
5877 void i386_fsubs_membase(s4 basereg, s4 disp) {
5878 *(mcodeptr++) = (u1) 0xd8;
5879 i386_emit_membase((basereg),(disp),4);
5883 void i386_fsubl_membase(s4 basereg, s4 disp) {
5884 *(mcodeptr++) = (u1) 0xdc;
5885 i386_emit_membase((basereg),(disp),4);
5889 void i386_fmul_reg_st(s4 reg) {
5890 *(mcodeptr++) = (u1) 0xd8;
5891 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5895 void i386_fmul_st_reg(s4 reg) {
5896 *(mcodeptr++) = (u1) 0xdc;
5897 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5902 *(mcodeptr++) = (u1) 0xde;
5903 *(mcodeptr++) = (u1) 0xc9;
5907 void i386_fmulp_st_reg(s4 reg) {
5908 *(mcodeptr++) = (u1) 0xde;
5909 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5913 void i386_fmuls_membase(s4 basereg, s4 disp) {
5914 *(mcodeptr++) = (u1) 0xd8;
5915 i386_emit_membase((basereg),(disp),1);
5919 void i386_fmull_membase(s4 basereg, s4 disp) {
5920 *(mcodeptr++) = (u1) 0xdc;
5921 i386_emit_membase((basereg),(disp),1);
5925 void i386_fdiv_reg_st(s4 reg) {
5926 *(mcodeptr++) = (u1) 0xd8;
5927 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
5931 void i386_fdiv_st_reg(s4 reg) {
5932 *(mcodeptr++) = (u1) 0xdc;
5933 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5938 *(mcodeptr++) = (u1) 0xde;
5939 *(mcodeptr++) = (u1) 0xf9;
5943 void i386_fdivp_st_reg(s4 reg) {
5944 *(mcodeptr++) = (u1) 0xde;
5945 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5950 *(mcodeptr++) = (u1) 0xd9;
5951 *(mcodeptr++) = (u1) 0xc9;
5955 void i386_fxch_reg(s4 reg) {
5956 *(mcodeptr++) = (u1) 0xd9;
5957 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5962 *(mcodeptr++) = (u1) 0xd9;
5963 *(mcodeptr++) = (u1) 0xf8;
5967 void i386_fprem1() {
5968 *(mcodeptr++) = (u1) 0xd9;
5969 *(mcodeptr++) = (u1) 0xf5;
5974 *(mcodeptr++) = (u1) 0xdd;
5975 *(mcodeptr++) = (u1) 0xe1;
5979 void i386_fucom_reg(s4 reg) {
5980 *(mcodeptr++) = (u1) 0xdd;
5981 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5985 void i386_fucomp_reg(s4 reg) {
5986 *(mcodeptr++) = (u1) 0xdd;
5987 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5991 void i386_fucompp() {
5992 *(mcodeptr++) = (u1) 0xda;
5993 *(mcodeptr++) = (u1) 0xe9;
5997 void i386_fnstsw() {
5998 *(mcodeptr++) = (u1) 0xdf;
5999 *(mcodeptr++) = (u1) 0xe0;
6004 *(mcodeptr++) = (u1) 0x9e;
6009 *(mcodeptr++) = (u1) 0x9b;
6010 *(mcodeptr++) = (u1) 0xdb;
6011 *(mcodeptr++) = (u1) 0xe3;
6015 void i386_fldcw_mem(s4 mem) {
6016 *(mcodeptr++) = (u1) 0xd9;
6017 i386_emit_mem(5,(mem));
6021 void i386_fldcw_membase(s4 basereg, s4 disp) {
6022 *(mcodeptr++) = (u1) 0xd9;
6023 i386_emit_membase((basereg),(disp),5);
6028 *(mcodeptr++) = (u1) 0x9b;
6032 void i386_ffree_reg(s4 reg) {
6033 *(mcodeptr++) = (u1) 0xdd;
6034 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
6038 void i386_fdecstp() {
6039 *(mcodeptr++) = (u1) 0xd9;
6040 *(mcodeptr++) = (u1) 0xf6;
6044 void i386_fincstp() {
6045 *(mcodeptr++) = (u1) 0xd9;
6046 *(mcodeptr++) = (u1) 0xf7;
6051 * These are local overrides for various environment variables in Emacs.
6052 * Please do not remove this and leave it at the end of the file, where
6053 * Emacs will automagically detect them.
6054 * ---------------------------------------------------------------------
6057 * indent-tabs-mode: t