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 771 2003-12-13 23:11:08Z stefan $
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 we initially try to use %edx as scratch register, it cannot be used if we
69 have one of these ICMDs:
70 LMUL, LMULCONST, IDIV, IREM, LALOAD, AASTORE, LASTORE, IASTORE, CASTORE,
71 SASTORE, BASTORE, INSTANCEOF, CHECKCAST, I2L, F2L, D2L
74 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_SAV, REG_SAV, REG_SAV,
79 int nregdescfloat[] = {
80 /* rounding problems with callee saved registers */
81 /* REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
82 /* REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
83 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
88 /* additional functions and macros to generate code ***************************/
90 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
94 #define COUNT_SPILLS count_spills++
100 #define CALCOFFSETBYTES(var, reg, val) \
101 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
102 else if ((s4) (val) != 0) (var) += 1; \
103 else if ((reg) == EBP) (var) += 1;
106 #define CALCIMMEDIATEBYTES(var, val) \
107 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
111 /* gen_nullptr_check(objreg) */
113 #define gen_nullptr_check(objreg) \
115 i386_test_reg_reg((objreg), (objreg)); \
116 i386_jcc(I386_CC_E, 0); \
117 codegen_addxnullrefs(mcodeptr); \
121 /* MCODECHECK(icnt) */
123 #define MCODECHECK(icnt) \
124 if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
127 generates an integer-move from register a to b.
128 if a and b are the same int-register, no code will be generated.
131 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
135 generates a floating-point-move from register a to b.
136 if a and b are the same float-register, no code will be generated
139 #define M_FLTMOVE(reg,dreg) panic("M_FLTMOVE");
141 #define M_LNGMEMMOVE(reg,dreg) \
143 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
144 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
145 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP1); \
146 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8 + 4); \
151 this function generates code to fetch data from a pseudo-register
152 into a real register.
153 If the pseudo-register has actually been assigned to a real
154 register, no code will be emitted, since following operations
155 can use this register directly.
157 v: pseudoregister to be fetched from
158 tempregnum: temporary register to be used if v is actually spilled to ram
160 return: the register number, where the operand can be found after
161 fetching (this wil be either tempregnum or the register
162 number allready given to v)
165 #define var_to_reg_int(regnr,v,tempnr) \
166 if ((v)->flags & INMEMORY) { \
168 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
171 regnr = (v)->regoff; \
176 #define var_to_reg_flt(regnr,v,tempnr) \
177 if ((v)->type == TYPE_FLT) { \
178 if ((v)->flags & INMEMORY) { \
180 i386_flds_membase(REG_SP, (v)->regoff * 8); \
184 i386_fld_reg((v)->regoff + fpu_st_offset); \
186 regnr = (v)->regoff; \
189 if ((v)->flags & INMEMORY) { \
191 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
195 i386_fld_reg((v)->regoff + fpu_st_offset); \
197 regnr = (v)->regoff; \
201 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
202 if ((v)->type == TYPE_FLT) { \
203 if ((v)->flags & INMEMORY) { \
205 i386_flds_membase(REG_SP, (v)->regoff * 8); \
209 regnr = (v)->regoff; \
212 if ((v)->flags & INMEMORY) { \
214 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
218 regnr = (v)->regoff; \
224 This function determines a register, to which the result of an operation
225 should go, when it is ultimatively intended to store the result in
227 If v is assigned to an actual register, this register will be returned.
228 Otherwise (when v is spilled) this function returns tempregnum.
229 If not already done, regoff and flags are set in the stack location.
232 static int reg_of_var(stackptr v, int tempregnum)
236 switch (v->varkind) {
238 if (!(v->flags & INMEMORY))
242 var = &(interfaces[v->varnum][v->type]);
243 v->regoff = var->regoff;
244 if (!(var->flags & INMEMORY))
248 var = &(locals[v->varnum][v->type]);
249 v->regoff = var->regoff;
250 if (!(var->flags & INMEMORY))
254 v->regoff = v->varnum;
255 if (IS_FLT_DBL_TYPE(v->type)) {
256 if (v->varnum < fltreg_argnum) {
257 v->regoff = argfltregs[v->varnum];
258 return(argfltregs[v->varnum]);
262 if (v->varnum < intreg_argnum) {
263 v->regoff = argintregs[v->varnum];
264 return(argintregs[v->varnum]);
266 v->regoff -= intreg_argnum;
269 v->flags |= INMEMORY;
274 /* store_reg_to_var_xxx:
275 This function generates the code to store the result of an operation
276 back into a spilled pseudo-variable.
277 If the pseudo-variable has not been spilled in the first place, this
278 function will generate nothing.
280 v ............ Pseudovariable
281 tempregnum ... Number of the temporary registers as returned by
285 #define store_reg_to_var_int(sptr, tempregnum) \
286 if ((sptr)->flags & INMEMORY) { \
288 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
292 #define store_reg_to_var_flt(sptr, tempregnum) \
293 if ((sptr)->type == TYPE_FLT) { \
294 if ((sptr)->flags & INMEMORY) { \
296 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
299 /* i386_fxch_reg((sptr)->regoff);*/ \
300 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
304 if ((sptr)->flags & INMEMORY) { \
306 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
309 /* i386_fxch_reg((sptr)->regoff);*/ \
310 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
316 /* NullPointerException signal handler for hardware null pointer check */
318 void catch_NullPointerException(int sig)
322 /* long faultaddr; */
324 void **_p = (void **) &sig;
325 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
327 /* Reset signal handler - necessary for SysV, does no harm for BSD */
329 /* instr = *((int*)(sigctx->eip)); */
330 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
332 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip); */
334 /* if (faultaddr == 0) { */
335 signal(sig, (void *) catch_NullPointerException); /* reinstall handler */
337 sigaddset(&nsig, sig);
338 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
339 sigctx->eax = (long) proto_java_lang_NullPointerException; /* REG_ITMP1_XPTR */
340 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
341 sigctx->eip = (long) asm_handle_exception;
346 /* faultaddr += (long) ((instr << 16) >> 16); */
347 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
348 /* panic("Stack overflow"); */
353 /* ArithmeticException signal handler for hardware divide by zero check */
355 void catch_ArithmeticException(int sig)
359 void **_p = (void **) &sig;
360 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
363 java_objectheader *p;
366 /* Reset signal handler - necessary for SysV, does no harm for BSD */
368 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
370 sigaddset(&nsig, sig);
371 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
373 c = loader_load_sysclass(NULL,utf_new_char("java/lang/ArithmeticException"));
375 m = class_findmethod(c,
376 utf_new_char("<init>"),
377 utf_new_char("(Ljava/lang/String;)V"));
379 asm_calljavafunction(m, p, javastring_new_char("/ by zero"), NULL, NULL);
381 sigctx->eax = (long) p; /* REG_ITMP1_XPTR */
382 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
383 sigctx->eip = (long) asm_handle_exception;
389 void init_exceptions(void)
391 /* install signal handlers we need to convert to exceptions */
396 signal(SIGSEGV, (void *) catch_NullPointerException);
400 signal(SIGBUS, (void *) catch_NullPointerException);
404 signal(SIGFPE, (void *) catch_ArithmeticException);
408 /* function gen_mcode **********************************************************
410 generates machine code
412 *******************************************************************************/
414 /* global code generation pointer */
419 int len, s1, s2, s3, d;
426 int fpu_st_offset = 0;
435 /* space to save used callee saved registers */
437 savedregs_num += (savintregcnt - maxsavintreguse);
438 savedregs_num += (savfltregcnt - maxsavfltreguse);
440 parentargs_base = maxmemuse + savedregs_num;
442 #ifdef USE_THREADS /* space to save argument of monitor_enter */
444 if (checksync && (method->flags & ACC_SYNCHRONIZED))
449 /* create method header */
451 (void) dseg_addaddress(method); /* MethodPointer */
452 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
456 /* IsSync contains the offset relative to the stack pointer for the
457 argument of monitor_exit used in the exception handler. Since the
458 offset could be zero and give a wrong meaning of the flag it is
462 if (checksync && (method->flags & ACC_SYNCHRONIZED))
463 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
468 (void) dseg_adds4(0); /* IsSync */
470 (void) dseg_adds4(isleafmethod); /* IsLeaf */
471 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
472 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
473 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
475 /* create exception table */
477 for (ex = extable; ex != NULL; ex = ex->down) {
480 if (ex->start != NULL)
481 printf("adding start - %d - ", ex->start->debug_nr);
483 printf("PANIC - start is NULL");
488 dseg_addtarget(ex->start);
492 printf("adding end - %d - ", ex->end->debug_nr);
494 printf("PANIC - end is NULL");
499 dseg_addtarget(ex->end);
502 if (ex->handler != NULL)
503 printf("adding handler - %d\n", ex->handler->debug_nr);
505 printf("PANIC - handler is NULL");
510 dseg_addtarget(ex->handler);
512 (void) dseg_addaddress(ex->catchtype);
515 /* initialize mcode variables */
517 mcodeptr = (u1*) mcodebase;
518 mcodeend = (s4*) (mcodebase + mcodesize);
519 MCODECHECK(128 + mparamcount);
521 /* create stack frame (if necessary) */
523 if (parentargs_base) {
524 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
527 /* save return address and used callee saved registers */
530 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
531 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
533 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
534 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
537 /* save monitorenter argument */
540 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
541 if (method->flags & ACC_STATIC) {
542 i386_mov_imm_reg((s4) class, REG_ITMP1);
543 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
546 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
547 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
552 /* copy argument registers to stack and call trace function with pointer
553 to arguments on stack.
557 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
559 for (p = 0; p < mparamcount; p++) {
561 if (IS_INT_LNG_TYPE(t)) {
562 if (IS_2_WORD_TYPE(t)) {
563 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
564 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
565 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
566 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
568 } else if (t == TYPE_ADR) {
569 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
570 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
571 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
572 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
575 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX);
577 i386_mov_reg_membase(EAX, REG_SP, p * 8);
578 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
583 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
584 i386_fstps_membase(REG_SP, p * 8);
585 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
586 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
589 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
590 i386_fstpl_membase(REG_SP, p * 8);
595 /* fill up the remaining arguments */
596 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
597 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
598 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
599 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
602 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
604 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
605 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
606 i386_call_reg(REG_ITMP1);
608 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
611 /* take arguments out of register or stack frame */
613 for (p = 0, l = 0; p < mparamcount; p++) {
615 var = &(locals[l][t]);
617 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
622 if (IS_INT_LNG_TYPE(t)) { /* integer args */
623 if (p < intreg_argnum) { /* register arguments */
624 panic("integer register argument");
625 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
626 /* M_INTMOVE (argintregs[p], r); */
628 } else { /* reg arg -> spilled */
629 /* M_LST (argintregs[p], REG_SP, 8 * r); */
631 } else { /* stack arguments */
632 pa = p - intreg_argnum;
633 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
634 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
635 } else { /* stack arg -> spilled */
636 if (!IS_2_WORD_TYPE(t)) {
637 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
638 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
641 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
642 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
643 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
644 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
649 } else { /* floating args */
650 if (p < fltreg_argnum) { /* register arguments */
651 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
652 panic("There are no float argument registers!");
654 } else { /* reg arg -> spilled */
655 panic("There are no float argument registers!");
658 } else { /* stack arguments */
659 pa = p - fltreg_argnum;
660 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
662 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
664 i386_fstp_reg(r + fpu_st_offset);
668 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
670 i386_fstp_reg(r + fpu_st_offset);
674 } else { /* stack-arg -> spilled */
675 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
676 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
678 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
679 i386_fstps_membase(REG_SP, r * 8);
682 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
683 i386_fstpl_membase(REG_SP, r * 8);
690 /* call monitorenter function */
693 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
694 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
695 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
696 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
697 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP2);
698 i386_call_reg(REG_ITMP2);
699 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
704 /* end of header generation */
706 /* walk through all basic blocks */
707 for (bptr = block; bptr != NULL; bptr = bptr->next) {
709 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
711 if (bptr->flags >= BBREACHED) {
713 /* branch resolving */
716 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
717 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
718 brefs->branchpos, bptr->mpc);
721 /* copy interface registers to their destination */
726 while (src != NULL) {
728 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
729 if (!IS_2_WORD_TYPE(src->type)) {
730 if (bptr->type == BBTYPE_SBR) {
731 d = reg_of_var(src, REG_ITMP1);
733 store_reg_to_var_int(src, d);
735 } else if (bptr->type == BBTYPE_EXH) {
736 d = reg_of_var(src, REG_ITMP1);
737 M_INTMOVE(REG_ITMP1, d);
738 store_reg_to_var_int(src, d);
742 panic("copy interface registers: longs have to me in memory (begin 1)");
746 d = reg_of_var(src, REG_ITMP1);
747 if ((src->varkind != STACKVAR)) {
749 if (IS_FLT_DBL_TYPE(s2)) {
750 s1 = interfaces[len][s2].regoff;
751 if (!(interfaces[len][s2].flags & INMEMORY)) {
755 if (s2 == TYPE_FLT) {
756 i386_flds_membase(REG_SP, s1 * 8);
759 i386_fldl_membase(REG_SP, s1 * 8);
762 store_reg_to_var_flt(src, d);
765 s1 = interfaces[len][s2].regoff;
766 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
767 if (!(interfaces[len][s2].flags & INMEMORY)) {
771 i386_mov_membase_reg(REG_SP, s1 * 8, d);
773 store_reg_to_var_int(src, d);
776 if (interfaces[len][s2].flags & INMEMORY) {
777 M_LNGMEMMOVE(s1, src->regoff);
780 panic("copy interface registers: longs have to be in memory (begin 2)");
789 /* walk through all instructions */
793 for (iptr = bptr->iinstr;
795 src = iptr->dst, len--, iptr++) {
797 MCODECHECK(64); /* an instruction usually needs < 64 words */
800 case ICMD_NOP: /* ... ==> ... */
803 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
804 if (src->flags & INMEMORY) {
805 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
808 i386_test_reg_reg(src->regoff, src->regoff);
810 i386_jcc(I386_CC_E, 0);
811 codegen_addxnullrefs(mcodeptr);
814 /* constant operations ************************************************/
816 case ICMD_ICONST: /* ... ==> ..., constant */
817 /* op1 = 0, val.i = constant */
819 d = reg_of_var(iptr->dst, REG_ITMP1);
820 if (iptr->dst->flags & INMEMORY) {
821 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
824 if (iptr->val.i == 0) {
825 i386_alu_reg_reg(I386_XOR, d, d);
828 i386_mov_imm_reg(iptr->val.i, d);
833 case ICMD_LCONST: /* ... ==> ..., constant */
834 /* op1 = 0, val.l = constant */
836 d = reg_of_var(iptr->dst, REG_ITMP1);
837 if (iptr->dst->flags & INMEMORY) {
838 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
839 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
842 panic("LCONST: longs have to be in memory");
846 case ICMD_FCONST: /* ... ==> ..., constant */
847 /* op1 = 0, val.f = constant */
849 d = reg_of_var(iptr->dst, REG_FTMP1);
850 if (iptr->val.f == 0.0) {
855 if (iptr->val.i == 0x80000000) {
859 } else if (iptr->val.f == 1.0) {
863 } else if (iptr->val.f == 2.0) {
870 a = dseg_addfloat(iptr->val.f);
871 i386_mov_imm_reg(0, REG_ITMP1);
872 dseg_adddata(mcodeptr);
873 i386_flds_membase(REG_ITMP1, a);
876 store_reg_to_var_flt(iptr->dst, d);
879 case ICMD_DCONST: /* ... ==> ..., constant */
880 /* op1 = 0, val.d = constant */
882 d = reg_of_var(iptr->dst, REG_FTMP1);
883 if (iptr->val.d == 0.0) {
888 if (iptr->val.l == 0x8000000000000000LL) {
892 } else if (iptr->val.d == 1.0) {
896 } else if (iptr->val.d == 2.0) {
903 a = dseg_adddouble(iptr->val.d);
904 i386_mov_imm_reg(0, REG_ITMP1);
905 dseg_adddata(mcodeptr);
906 i386_fldl_membase(REG_ITMP1, a);
909 store_reg_to_var_flt(iptr->dst, d);
912 case ICMD_ACONST: /* ... ==> ..., constant */
913 /* op1 = 0, val.a = constant */
915 d = reg_of_var(iptr->dst, REG_ITMP1);
916 if (iptr->dst->flags & INMEMORY) {
917 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
920 if ((s4) iptr->val.a == 0) {
921 i386_alu_reg_reg(I386_XOR, d, d);
924 i386_mov_imm_reg((s4) iptr->val.a, d);
930 /* load/store operations **********************************************/
932 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
933 case ICMD_ALOAD: /* op1 = local variable */
935 d = reg_of_var(iptr->dst, REG_ITMP1);
936 if ((iptr->dst->varkind == LOCALVAR) &&
937 (iptr->dst->varnum == iptr->op1)) {
940 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
941 if (iptr->dst->flags & INMEMORY) {
942 if (var->flags & INMEMORY) {
943 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
944 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
947 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
951 if (var->flags & INMEMORY) {
952 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
955 M_INTMOVE(var->regoff, iptr->dst->regoff);
960 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
961 /* op1 = local variable */
963 d = reg_of_var(iptr->dst, REG_ITMP1);
964 if ((iptr->dst->varkind == LOCALVAR) &&
965 (iptr->dst->varnum == iptr->op1)) {
968 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
969 if (iptr->dst->flags & INMEMORY) {
970 if (var->flags & INMEMORY) {
971 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
974 panic("LLOAD: longs have to be in memory");
978 panic("LLOAD: longs have to be in memory");
982 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
983 /* op1 = local variable */
985 d = reg_of_var(iptr->dst, REG_FTMP1);
986 if ((iptr->dst->varkind == LOCALVAR) &&
987 (iptr->dst->varnum == iptr->op1)) {
990 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
991 if (var->flags & INMEMORY) {
992 i386_flds_membase(REG_SP, var->regoff * 8);
995 i386_fld_reg(var->regoff + fpu_st_offset);
998 store_reg_to_var_flt(iptr->dst, d);
1001 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
1002 /* op1 = local variable */
1004 d = reg_of_var(iptr->dst, REG_FTMP1);
1005 if ((iptr->dst->varkind == LOCALVAR) &&
1006 (iptr->dst->varnum == iptr->op1)) {
1009 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
1010 if (var->flags & INMEMORY) {
1011 i386_fldl_membase(REG_SP, var->regoff * 8);
1014 i386_fld_reg(var->regoff + fpu_st_offset);
1017 store_reg_to_var_flt(iptr->dst, d);
1020 case ICMD_ISTORE: /* ..., value ==> ... */
1021 case ICMD_ASTORE: /* op1 = local variable */
1023 if ((src->varkind == LOCALVAR) &&
1024 (src->varnum == iptr->op1)) {
1027 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1028 if (var->flags & INMEMORY) {
1029 if (src->flags & INMEMORY) {
1030 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1031 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
1034 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
1038 var_to_reg_int(s1, src, var->regoff);
1039 M_INTMOVE(s1, var->regoff);
1043 case ICMD_LSTORE: /* ..., value ==> ... */
1044 /* op1 = local variable */
1046 if ((src->varkind == LOCALVAR) &&
1047 (src->varnum == iptr->op1)) {
1050 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1051 if (var->flags & INMEMORY) {
1052 if (src->flags & INMEMORY) {
1053 M_LNGMEMMOVE(src->regoff, var->regoff);
1056 panic("LSTORE: longs have to be in memory");
1060 panic("LSTORE: longs have to be in memory");
1064 case ICMD_FSTORE: /* ..., value ==> ... */
1065 /* op1 = local variable */
1067 if ((src->varkind == LOCALVAR) &&
1068 (src->varnum == iptr->op1)) {
1071 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1072 if (var->flags & INMEMORY) {
1073 var_to_reg_flt(s1, src, REG_FTMP1);
1074 i386_fstps_membase(REG_SP, var->regoff * 8);
1077 var_to_reg_flt(s1, src, var->regoff);
1078 /* M_FLTMOVE(s1, var->regoff); */
1079 i386_fstp_reg(var->regoff + fpu_st_offset);
1084 case ICMD_DSTORE: /* ..., value ==> ... */
1085 /* op1 = local variable */
1087 if ((src->varkind == LOCALVAR) &&
1088 (src->varnum == iptr->op1)) {
1091 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1092 if (var->flags & INMEMORY) {
1093 var_to_reg_flt(s1, src, REG_FTMP1);
1094 i386_fstpl_membase(REG_SP, var->regoff * 8);
1097 var_to_reg_flt(s1, src, var->regoff);
1098 /* M_FLTMOVE(s1, var->regoff); */
1099 i386_fstp_reg(var->regoff + fpu_st_offset);
1105 /* pop/dup/swap operations ********************************************/
1107 /* attention: double and longs are only one entry in CACAO ICMDs */
1109 case ICMD_POP: /* ..., value ==> ... */
1110 case ICMD_POP2: /* ..., value, value ==> ... */
1113 #define M_COPY(from,to) \
1114 d = reg_of_var(to, REG_ITMP1); \
1115 if ((from->regoff != to->regoff) || \
1116 ((from->flags ^ to->flags) & INMEMORY)) { \
1117 if (IS_FLT_DBL_TYPE(from->type)) { \
1118 var_to_reg_flt(s1, from, d); \
1119 /* M_FLTMOVE(s1, d);*/ \
1120 store_reg_to_var_flt(to, d); \
1122 if (!IS_2_WORD_TYPE(from->type)) { \
1123 if (to->flags & INMEMORY) { \
1124 if (from->flags & INMEMORY) { \
1125 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1126 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1128 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1131 if (from->flags & INMEMORY) { \
1132 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1134 i386_mov_reg_reg(from->regoff, to->regoff); \
1138 M_LNGMEMMOVE(from->regoff, to->regoff); \
1143 case ICMD_DUP: /* ..., a ==> ..., a, a */
1144 M_COPY(src, iptr->dst);
1147 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1149 M_COPY(src, iptr->dst->prev->prev);
1151 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1153 M_COPY(src, iptr->dst);
1154 M_COPY(src->prev, iptr->dst->prev);
1157 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1159 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1161 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1163 M_COPY(src, iptr->dst);
1164 M_COPY(src->prev, iptr->dst->prev);
1165 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1166 M_COPY(src, iptr->dst->prev->prev->prev);
1169 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1171 M_COPY(src, iptr->dst);
1172 M_COPY(src->prev, iptr->dst->prev);
1173 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1174 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1175 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1176 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1179 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1181 M_COPY(src, iptr->dst->prev);
1182 M_COPY(src->prev, iptr->dst);
1186 /* integer operations *************************************************/
1188 case ICMD_INEG: /* ..., value ==> ..., - value */
1190 d = reg_of_var(iptr->dst, REG_NULL);
1191 if (iptr->dst->flags & INMEMORY) {
1192 if (src->flags & INMEMORY) {
1193 if (src->regoff == iptr->dst->regoff) {
1194 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1197 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1198 i386_neg_reg(REG_ITMP1);
1199 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1203 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1204 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1208 if (src->flags & INMEMORY) {
1209 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1210 i386_neg_reg(iptr->dst->regoff);
1213 M_INTMOVE(src->regoff, iptr->dst->regoff);
1214 i386_neg_reg(iptr->dst->regoff);
1219 case ICMD_LNEG: /* ..., value ==> ..., - value */
1221 d = reg_of_var(iptr->dst, REG_NULL);
1222 if (iptr->dst->flags & INMEMORY) {
1223 if (src->flags & INMEMORY) {
1224 if (src->regoff == iptr->dst->regoff) {
1225 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1226 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1227 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1230 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1231 i386_neg_reg(REG_ITMP1);
1232 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1233 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1234 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP1);
1235 i386_neg_reg(REG_ITMP1);
1236 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1242 case ICMD_I2L: /* ..., value ==> ..., value */
1244 d = reg_of_var(iptr->dst, REG_NULL);
1245 if (iptr->dst->flags & INMEMORY) {
1246 if (src->flags & INMEMORY) {
1247 i386_mov_membase_reg(REG_SP, src->regoff * 8, EAX);
1249 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1250 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1253 M_INTMOVE(src->regoff, EAX);
1255 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1256 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1261 case ICMD_L2I: /* ..., value ==> ..., value */
1263 d = reg_of_var(iptr->dst, REG_NULL);
1264 if (iptr->dst->flags & INMEMORY) {
1265 if (src->flags & INMEMORY) {
1266 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1267 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1271 if (src->flags & INMEMORY) {
1272 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1277 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1279 d = reg_of_var(iptr->dst, REG_NULL);
1280 if (iptr->dst->flags & INMEMORY) {
1281 if (src->flags & INMEMORY) {
1282 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1283 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1284 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1285 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1288 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1289 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1290 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1294 if (src->flags & INMEMORY) {
1295 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1296 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1297 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1300 M_INTMOVE(src->regoff, iptr->dst->regoff);
1301 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1302 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1307 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1309 d = reg_of_var(iptr->dst, REG_NULL);
1310 if (iptr->dst->flags & INMEMORY) {
1311 if (src->flags & INMEMORY) {
1312 if (src->regoff == iptr->dst->regoff) {
1313 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1316 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1317 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1318 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1322 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1323 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1327 if (src->flags & INMEMORY) {
1328 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1329 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1332 M_INTMOVE(src->regoff, iptr->dst->regoff);
1333 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1338 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1340 d = reg_of_var(iptr->dst, REG_NULL);
1341 if (iptr->dst->flags & INMEMORY) {
1342 if (src->flags & INMEMORY) {
1343 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1344 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1345 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1346 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1349 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1350 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1351 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1355 if (src->flags & INMEMORY) {
1356 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1357 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1358 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1361 M_INTMOVE(src->regoff, iptr->dst->regoff);
1362 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1363 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1369 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1371 d = reg_of_var(iptr->dst, REG_NULL);
1372 i386_emit_ialu(I386_ADD, src, iptr);
1375 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1376 /* val.i = constant */
1378 d = reg_of_var(iptr->dst, REG_NULL);
1379 /* should we use a inc optimization for smaller code size? */
1380 i386_emit_ialuconst(I386_ADD, src, iptr);
1383 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1385 d = reg_of_var(iptr->dst, REG_NULL);
1386 if (iptr->dst->flags & INMEMORY) {
1387 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1388 if (src->regoff == iptr->dst->regoff) {
1389 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1390 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1391 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1392 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1394 } else if (src->prev->regoff == iptr->dst->regoff) {
1395 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1396 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1397 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1398 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1401 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1402 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1403 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1404 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1405 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1406 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1413 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1414 /* val.l = constant */
1416 d = reg_of_var(iptr->dst, REG_NULL);
1417 if (iptr->dst->flags & INMEMORY) {
1418 if (src->flags & INMEMORY) {
1419 if (src->regoff == iptr->dst->regoff) {
1420 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1421 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1424 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1425 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1426 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1427 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1428 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1429 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1435 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1437 d = reg_of_var(iptr->dst, REG_NULL);
1438 if (iptr->dst->flags & INMEMORY) {
1439 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1440 if (src->prev->regoff == iptr->dst->regoff) {
1441 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1442 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1445 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, 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);
1450 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1451 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1452 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1453 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1455 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1456 if (src->prev->regoff == iptr->dst->regoff) {
1457 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1460 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1461 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1462 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1466 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1467 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1471 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1472 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1473 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1475 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1476 M_INTMOVE(src->prev->regoff, d);
1477 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1479 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1480 /* workaround for reg alloc */
1481 if (src->regoff == iptr->dst->regoff) {
1482 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1483 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1484 M_INTMOVE(REG_ITMP1, d);
1487 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1488 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1492 /* workaround for reg alloc */
1493 if (src->regoff == iptr->dst->regoff) {
1494 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1495 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1496 M_INTMOVE(REG_ITMP1, d);
1499 M_INTMOVE(src->prev->regoff, d);
1500 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1506 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1507 /* val.i = constant */
1509 d = reg_of_var(iptr->dst, REG_NULL);
1510 i386_emit_ialuconst(I386_SUB, src, iptr);
1513 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1515 d = reg_of_var(iptr->dst, REG_NULL);
1516 if (iptr->dst->flags & INMEMORY) {
1517 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1518 if (src->prev->regoff == iptr->dst->regoff) {
1519 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1520 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1521 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1522 i386_alu_reg_membase(I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1525 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1526 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1527 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1528 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1529 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1530 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1536 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1537 /* val.l = constant */
1539 d = reg_of_var(iptr->dst, REG_NULL);
1540 if (iptr->dst->flags & INMEMORY) {
1541 if (src->flags & INMEMORY) {
1542 if (src->regoff == iptr->dst->regoff) {
1543 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1544 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1547 /* TODO: could be size optimized with lea -- see gcc output */
1548 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1549 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1550 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1551 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1552 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1553 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1559 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1561 d = reg_of_var(iptr->dst, REG_NULL);
1562 if (iptr->dst->flags & INMEMORY) {
1563 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1564 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1565 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1566 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1568 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1569 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1570 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1571 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1573 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1574 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1575 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1576 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1579 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1580 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1581 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1585 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1586 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1587 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1589 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1590 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1591 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1593 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1594 M_INTMOVE(src->regoff, iptr->dst->regoff);
1595 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1598 if (src->regoff == iptr->dst->regoff) {
1599 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1602 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1603 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1609 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1610 /* val.i = constant */
1612 d = reg_of_var(iptr->dst, REG_NULL);
1613 if (iptr->dst->flags & INMEMORY) {
1614 if (src->flags & INMEMORY) {
1615 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1616 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1619 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1620 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1624 if (src->flags & INMEMORY) {
1625 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1628 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1633 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1635 d = reg_of_var(iptr->dst, REG_NULL);
1636 if (iptr->dst->flags & INMEMORY) {
1637 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1638 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX); /* mem -> EAX */
1639 /* optimize move EAX -> REG_ITMP3 is slower??? */
1640 /* i386_mov_reg_reg(EAX, REG_ITMP3); */
1641 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1643 /* TODO: optimize move EAX -> REG_ITMP3 */
1644 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem -> ITMP3 */
1645 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1646 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1648 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP2); /* mem -> ITMP3 */
1649 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1651 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1652 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1653 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1658 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1659 /* val.l = constant */
1661 d = reg_of_var(iptr->dst, REG_NULL);
1662 if (iptr->dst->flags & INMEMORY) {
1663 if (src->flags & INMEMORY) {
1664 i386_mov_imm_reg(iptr->val.l, EAX); /* imm -> EAX */
1665 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1666 /* TODO: optimize move EAX -> REG_ITMP3 */
1667 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2); /* imm -> ITMP3 */
1668 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1670 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1671 i386_mov_imm_reg(iptr->val.l, REG_ITMP2); /* imm -> ITMP3 */
1672 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1674 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1675 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1676 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1681 #define gen_div_check(v) \
1683 if ((v)->flags & INMEMORY) { \
1684 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1686 i386_test_reg_reg(src->regoff, src->regoff); \
1688 i386_jcc(I386_CC_E, 0); \
1689 codegen_addxdivrefs(mcodeptr); \
1692 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1694 d = reg_of_var(iptr->dst, REG_NULL);
1695 var_to_reg_int(s1, src, REG_ITMP2);
1697 if (src->prev->flags & INMEMORY) {
1698 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1701 M_INTMOVE(src->prev->regoff, EAX);
1704 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1705 i386_jcc(I386_CC_NE, 3 + 6);
1706 i386_alu_imm_reg(I386_CMP, -1, s1);
1707 i386_jcc(I386_CC_E, 1 + 2);
1712 if (iptr->dst->flags & INMEMORY) {
1713 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1716 M_INTMOVE(EAX, iptr->dst->regoff);
1720 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1722 d = reg_of_var(iptr->dst, REG_NULL);
1723 var_to_reg_int(s1, src, REG_ITMP2);
1725 if (src->prev->flags & INMEMORY) {
1726 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1729 M_INTMOVE(src->prev->regoff, EAX);
1732 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1733 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1734 i386_alu_reg_reg(I386_XOR, EDX, EDX);
1735 i386_alu_imm_reg(I386_CMP, -1, s1);
1736 i386_jcc(I386_CC_E, 1 + 2);
1741 if (iptr->dst->flags & INMEMORY) {
1742 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8);
1745 M_INTMOVE(EDX, iptr->dst->regoff);
1749 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1750 /* val.i = constant */
1752 /* TODO: optimize for `/ 2' */
1753 var_to_reg_int(s1, src, REG_ITMP1);
1754 d = reg_of_var(iptr->dst, REG_ITMP1);
1757 i386_test_reg_reg(d, d);
1759 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1760 i386_jcc(I386_CC_NS, a);
1761 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1763 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1764 store_reg_to_var_int(iptr->dst, d);
1767 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1768 /* val.i = constant */
1770 d = reg_of_var(iptr->dst, REG_NULL);
1771 if (iptr->dst->flags & INMEMORY) {
1772 if (src->flags & INMEMORY) {
1774 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1776 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1777 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1779 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1780 i386_jcc(I386_CC_NS, a);
1781 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1782 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1783 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1784 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1786 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1787 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1792 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1793 /* val.i = constant */
1795 var_to_reg_int(s1, src, REG_ITMP1);
1796 d = reg_of_var(iptr->dst, REG_ITMP2);
1798 M_INTMOVE(s1, REG_ITMP1);
1805 CALCIMMEDIATEBYTES(a, iptr->val.i);
1808 /* TODO: optimize */
1810 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1811 i386_test_reg_reg(s1, s1);
1812 i386_jcc(I386_CC_GE, a);
1813 i386_mov_reg_reg(s1, d);
1815 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1818 /* M_INTMOVE(s1, EAX); */
1820 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1821 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1822 /* i386_alu_reg_reg(I386_AND, iptr->val.i, EAX); */
1823 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1824 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1825 /* M_INTMOVE(EAX, d); */
1827 /* i386_alu_reg_reg(I386_XOR, d, d); */
1828 /* i386_mov_imm_reg(iptr->val.i, ECX); */
1829 /* i386_shrd_reg_reg(s1, d); */
1830 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1832 store_reg_to_var_int(iptr->dst, d);
1835 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1836 /* val.l = constant */
1838 d = reg_of_var(iptr->dst, REG_NULL);
1839 if (iptr->dst->flags & INMEMORY) {
1840 if (src->flags & INMEMORY) {
1841 /* Intel algorithm -- does not work, because constant is wrong */
1842 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1843 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1845 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1846 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1847 /* i386_jcc(I386_CC_NS, offset); */
1848 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1849 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1851 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1852 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1853 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1855 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1857 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1858 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1859 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1861 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1862 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1864 /* Alpha algorithm */
1866 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1868 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1874 /* TODO: hmm, don't know if this is always correct */
1876 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1878 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1884 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1885 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1887 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1888 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1889 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1890 i386_jcc(I386_CC_GE, a);
1892 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1893 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1895 i386_neg_reg(REG_ITMP1);
1896 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1897 i386_neg_reg(REG_ITMP2);
1899 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1900 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1902 i386_neg_reg(REG_ITMP1);
1903 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1904 i386_neg_reg(REG_ITMP2);
1906 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1907 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1912 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1914 d = reg_of_var(iptr->dst, REG_NULL);
1915 i386_emit_ishift(I386_SHL, src, iptr);
1918 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1919 /* val.i = constant */
1921 d = reg_of_var(iptr->dst, REG_NULL);
1922 i386_emit_ishiftconst(I386_SHL, src, iptr);
1925 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1927 d = reg_of_var(iptr->dst, REG_NULL);
1928 i386_emit_ishift(I386_SAR, src, iptr);
1931 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1932 /* val.i = constant */
1934 d = reg_of_var(iptr->dst, REG_NULL);
1935 i386_emit_ishiftconst(I386_SAR, src, iptr);
1938 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1940 d = reg_of_var(iptr->dst, REG_NULL);
1941 i386_emit_ishift(I386_SHR, src, iptr);
1944 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1945 /* val.i = constant */
1947 d = reg_of_var(iptr->dst, REG_NULL);
1948 i386_emit_ishiftconst(I386_SHR, src, iptr);
1951 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1953 d = reg_of_var(iptr->dst, REG_NULL);
1954 if (iptr->dst->flags & INMEMORY ){
1955 if (src->prev->flags & INMEMORY) {
1956 /* if (src->prev->regoff == iptr->dst->regoff) { */
1957 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1959 /* if (src->flags & INMEMORY) { */
1960 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
1962 /* M_INTMOVE(src->regoff, ECX); */
1965 /* i386_test_imm_reg(32, ECX); */
1966 /* i386_jcc(I386_CC_E, 2 + 2); */
1967 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1968 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1970 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1971 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1974 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1975 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1977 if (src->flags & INMEMORY) {
1978 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
1980 M_INTMOVE(src->regoff, ECX);
1983 i386_test_imm_reg(32, ECX);
1984 i386_jcc(I386_CC_E, 2 + 2);
1985 i386_mov_reg_reg(REG_ITMP1, REG_ITMP3);
1986 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1988 i386_shld_reg_reg(REG_ITMP1, REG_ITMP3);
1989 i386_shift_reg(I386_SHL, REG_ITMP1);
1990 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1991 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1997 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1998 /* val.i = constant */
2000 d = reg_of_var(iptr->dst, REG_NULL);
2001 if (iptr->dst->flags & INMEMORY ) {
2002 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2003 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2005 if (iptr->val.i & 0x20) {
2006 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2007 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2008 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2011 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2012 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2015 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2016 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2020 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2022 d = reg_of_var(iptr->dst, REG_NULL);
2023 if (iptr->dst->flags & INMEMORY ){
2024 if (src->prev->flags & INMEMORY) {
2025 /* if (src->prev->regoff == iptr->dst->regoff) { */
2026 /* TODO: optimize */
2027 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2028 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2030 /* if (src->flags & INMEMORY) { */
2031 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2033 /* M_INTMOVE(src->regoff, ECX); */
2036 /* i386_test_imm_reg(32, ECX); */
2037 /* i386_jcc(I386_CC_E, 2 + 3); */
2038 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2039 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2041 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2042 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2043 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2044 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2047 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2048 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2050 if (src->flags & INMEMORY) {
2051 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2053 M_INTMOVE(src->regoff, ECX);
2056 i386_test_imm_reg(32, ECX);
2057 i386_jcc(I386_CC_E, 2 + 3);
2058 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2059 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP3);
2061 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2062 i386_shift_reg(I386_SAR, REG_ITMP3);
2063 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2064 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2070 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2071 /* val.i = constant */
2073 d = reg_of_var(iptr->dst, REG_NULL);
2074 if (iptr->dst->flags & INMEMORY ) {
2075 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2076 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2078 if (iptr->val.i & 0x20) {
2079 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2080 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2081 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2084 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2085 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2088 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2089 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2093 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2095 d = reg_of_var(iptr->dst, REG_NULL);
2096 if (iptr->dst->flags & INMEMORY ){
2097 if (src->prev->flags & INMEMORY) {
2098 /* if (src->prev->regoff == iptr->dst->regoff) { */
2099 /* TODO: optimize */
2100 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2101 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2103 /* if (src->flags & INMEMORY) { */
2104 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2106 /* M_INTMOVE(src->regoff, ECX); */
2109 /* i386_test_imm_reg(32, ECX); */
2110 /* i386_jcc(I386_CC_E, 2 + 2); */
2111 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2112 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2114 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2115 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2116 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2117 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2120 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2121 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2123 if (src->flags & INMEMORY) {
2124 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2126 M_INTMOVE(src->regoff, ECX);
2129 i386_test_imm_reg(32, ECX);
2130 i386_jcc(I386_CC_E, 2 + 2);
2131 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2132 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2134 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2135 i386_shift_reg(I386_SHR, REG_ITMP3);
2136 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2137 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2143 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2144 /* val.l = constant */
2146 d = reg_of_var(iptr->dst, REG_NULL);
2147 if (iptr->dst->flags & INMEMORY ) {
2148 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2149 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2151 if (iptr->val.i & 0x20) {
2152 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2153 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2154 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2157 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2158 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2161 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2162 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2166 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2168 d = reg_of_var(iptr->dst, REG_NULL);
2169 i386_emit_ialu(I386_AND, src, iptr);
2172 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2173 /* val.i = constant */
2175 d = reg_of_var(iptr->dst, REG_NULL);
2176 i386_emit_ialuconst(I386_AND, src, iptr);
2179 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2181 d = reg_of_var(iptr->dst, REG_NULL);
2182 i386_emit_lalu(I386_AND, src, iptr);
2185 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2186 /* val.l = constant */
2188 d = reg_of_var(iptr->dst, REG_NULL);
2189 i386_emit_laluconst(I386_AND, src, iptr);
2192 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2194 d = reg_of_var(iptr->dst, REG_NULL);
2195 i386_emit_ialu(I386_OR, src, iptr);
2198 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2199 /* val.i = constant */
2201 d = reg_of_var(iptr->dst, REG_NULL);
2202 i386_emit_ialuconst(I386_OR, src, iptr);
2205 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2207 d = reg_of_var(iptr->dst, REG_NULL);
2208 i386_emit_lalu(I386_OR, src, iptr);
2211 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2212 /* val.l = constant */
2214 d = reg_of_var(iptr->dst, REG_NULL);
2215 i386_emit_laluconst(I386_OR, src, iptr);
2218 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2220 d = reg_of_var(iptr->dst, REG_NULL);
2221 i386_emit_ialu(I386_XOR, src, iptr);
2224 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2225 /* val.i = constant */
2227 d = reg_of_var(iptr->dst, REG_NULL);
2228 i386_emit_ialuconst(I386_XOR, src, iptr);
2231 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2233 d = reg_of_var(iptr->dst, REG_NULL);
2234 i386_emit_lalu(I386_XOR, src, iptr);
2237 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2238 /* val.l = constant */
2240 d = reg_of_var(iptr->dst, REG_NULL);
2241 i386_emit_laluconst(I386_XOR, src, iptr);
2244 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2245 /* op1 = variable, val.i = constant */
2247 var = &(locals[iptr->op1][TYPE_INT]);
2248 if (var->flags & INMEMORY) {
2249 if (iptr->val.i == 1) {
2250 i386_inc_membase(REG_SP, var->regoff * 8);
2252 } else if (iptr->val.i == -1) {
2253 i386_dec_membase(REG_SP, var->regoff * 8);
2256 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2260 if (iptr->val.i == 1) {
2261 i386_inc_reg(var->regoff);
2263 } else if (iptr->val.i == -1) {
2264 i386_dec_reg(var->regoff);
2267 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2273 /* floating operations ************************************************/
2275 #define ROUND_TO_SINGLE \
2276 i386_fstps_membase(REG_SP, -8); \
2277 i386_flds_membase(REG_SP, -8);
2279 #define ROUND_TO_DOUBLE \
2280 i386_fstpl_membase(REG_SP, -8); \
2281 i386_fldl_membase(REG_SP, -8);
2283 #define FPU_SET_24BIT_MODE \
2284 if (!fpu_in_24bit_mode) { \
2285 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2286 fpu_in_24bit_mode = 1; \
2289 #define FPU_SET_53BIT_MODE \
2290 if (fpu_in_24bit_mode) { \
2291 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2292 fpu_in_24bit_mode = 0; \
2295 #define ROUND_TO_SINGLE
2296 #define ROUND_TO_DOUBLE
2297 #define FPU_SET_24BIT_MODE
2298 #define FPU_SET_53BIT_MODE
2300 case ICMD_FNEG: /* ..., value ==> ..., - value */
2303 var_to_reg_flt(s1, src, REG_FTMP1);
2304 d = reg_of_var(iptr->dst, REG_FTMP3);
2306 store_reg_to_var_flt(iptr->dst, d);
2309 case ICMD_DNEG: /* ..., value ==> ..., - value */
2312 var_to_reg_flt(s1, src, REG_FTMP1);
2313 d = reg_of_var(iptr->dst, REG_FTMP3);
2315 store_reg_to_var_flt(iptr->dst, d);
2318 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2321 d = reg_of_var(iptr->dst, REG_FTMP3);
2322 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2323 var_to_reg_flt(s2, src, REG_FTMP2);
2326 store_reg_to_var_flt(iptr->dst, d);
2329 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2332 d = reg_of_var(iptr->dst, REG_FTMP3);
2333 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2334 var_to_reg_flt(s2, src, REG_FTMP2);
2337 store_reg_to_var_flt(iptr->dst, d);
2340 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2343 d = reg_of_var(iptr->dst, REG_FTMP3);
2344 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2345 var_to_reg_flt(s2, src, REG_FTMP2);
2348 store_reg_to_var_flt(iptr->dst, d);
2351 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2354 d = reg_of_var(iptr->dst, REG_FTMP3);
2355 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2356 var_to_reg_flt(s2, src, REG_FTMP2);
2359 store_reg_to_var_flt(iptr->dst, d);
2362 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2365 d = reg_of_var(iptr->dst, REG_FTMP3);
2366 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2367 var_to_reg_flt(s2, src, REG_FTMP2);
2371 store_reg_to_var_flt(iptr->dst, d);
2374 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2377 d = reg_of_var(iptr->dst, REG_FTMP3);
2378 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2380 /* i386_fldt_mem(subnormal_bias1); */
2383 var_to_reg_flt(s2, src, REG_FTMP2);
2388 /* i386_fldt_mem(subnormal_bias2); */
2391 store_reg_to_var_flt(iptr->dst, d);
2394 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2397 d = reg_of_var(iptr->dst, REG_FTMP3);
2398 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2399 var_to_reg_flt(s2, src, REG_FTMP2);
2403 store_reg_to_var_flt(iptr->dst, d);
2406 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2409 d = reg_of_var(iptr->dst, REG_FTMP3);
2410 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2412 /* i386_fldt_mem(subnormal_bias1); */
2415 var_to_reg_flt(s2, src, REG_FTMP2);
2420 /* i386_fldt_mem(subnormal_bias2); */
2423 store_reg_to_var_flt(iptr->dst, d);
2426 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2429 /* exchanged to skip fxch */
2430 var_to_reg_flt(s2, src, REG_FTMP2);
2431 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2432 d = reg_of_var(iptr->dst, REG_FTMP3);
2438 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2439 store_reg_to_var_flt(iptr->dst, d);
2445 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2448 /* exchanged to skip fxch */
2449 var_to_reg_flt(s2, src, REG_FTMP2);
2450 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2451 d = reg_of_var(iptr->dst, REG_FTMP3);
2457 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2458 store_reg_to_var_flt(iptr->dst, d);
2464 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2465 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2467 d = reg_of_var(iptr->dst, REG_FTMP1);
2468 if (src->flags & INMEMORY) {
2469 i386_fildl_membase(REG_SP, src->regoff * 8);
2474 i386_mov_imm_reg(0, REG_ITMP1);
2475 dseg_adddata(mcodeptr);
2476 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2477 i386_fildl_membase(REG_ITMP1, a);
2480 store_reg_to_var_flt(iptr->dst, d);
2483 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2484 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2486 d = reg_of_var(iptr->dst, REG_FTMP1);
2487 if (src->flags & INMEMORY) {
2488 i386_fildll_membase(REG_SP, src->regoff * 8);
2492 panic("L2F: longs have to be in memory");
2494 store_reg_to_var_flt(iptr->dst, d);
2497 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2499 var_to_reg_flt(s1, src, REG_FTMP1);
2500 d = reg_of_var(iptr->dst, REG_NULL);
2502 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2503 i386_mov_imm_reg(0, REG_ITMP1);
2504 dseg_adddata(mcodeptr);
2505 i386_fldcw_membase(REG_ITMP1, a);
2507 if (iptr->dst->flags & INMEMORY) {
2508 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2511 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2512 i386_fldcw_membase(REG_ITMP1, a);
2514 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2517 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2519 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2523 i386_fistpl_membase(REG_ITMP1, a);
2525 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2527 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2528 i386_fldcw_membase(REG_ITMP1, a);
2530 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2533 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2534 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2537 i386_jcc(I386_CC_NE, a);
2539 /* XXX: change this when we use registers */
2540 i386_flds_membase(REG_SP, src->regoff * 8);
2541 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP1);
2542 i386_call_reg(REG_ITMP1);
2544 if (iptr->dst->flags & INMEMORY) {
2545 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2548 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2552 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2554 var_to_reg_flt(s1, src, REG_FTMP1);
2555 d = reg_of_var(iptr->dst, REG_NULL);
2557 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2558 i386_mov_imm_reg(0, REG_ITMP1);
2559 dseg_adddata(mcodeptr);
2560 i386_fldcw_membase(REG_ITMP1, a);
2562 if (iptr->dst->flags & INMEMORY) {
2563 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2566 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2567 i386_fldcw_membase(REG_ITMP1, a);
2569 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2572 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2574 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2578 i386_fistpl_membase(REG_ITMP1, a);
2580 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2582 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2583 i386_fldcw_membase(REG_ITMP1, a);
2585 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2588 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2589 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2592 i386_jcc(I386_CC_NE, a);
2594 /* XXX: change this when we use registers */
2595 i386_fldl_membase(REG_SP, src->regoff * 8);
2596 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP1);
2597 i386_call_reg(REG_ITMP1);
2599 if (iptr->dst->flags & INMEMORY) {
2600 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2602 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2606 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2608 var_to_reg_flt(s1, src, REG_FTMP1);
2609 d = reg_of_var(iptr->dst, REG_NULL);
2611 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2612 i386_mov_imm_reg(0, REG_ITMP1);
2613 dseg_adddata(mcodeptr);
2614 i386_fldcw_membase(REG_ITMP1, a);
2616 if (iptr->dst->flags & INMEMORY) {
2617 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2620 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2621 i386_fldcw_membase(REG_ITMP1, a);
2623 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2626 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2628 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2631 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2633 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2635 i386_jcc(I386_CC_NE, a);
2637 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2640 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2642 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2644 i386_jcc(I386_CC_NE, a);
2646 /* XXX: change this when we use registers */
2647 i386_flds_membase(REG_SP, src->regoff * 8);
2648 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP1);
2649 i386_call_reg(REG_ITMP1);
2650 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2651 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2654 panic("F2L: longs have to be in memory");
2658 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2660 var_to_reg_flt(s1, src, REG_FTMP1);
2661 d = reg_of_var(iptr->dst, REG_NULL);
2663 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2664 i386_mov_imm_reg(0, REG_ITMP1);
2665 dseg_adddata(mcodeptr);
2666 i386_fldcw_membase(REG_ITMP1, a);
2668 if (iptr->dst->flags & INMEMORY) {
2669 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2672 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2673 i386_fldcw_membase(REG_ITMP1, a);
2675 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2678 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2680 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2683 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2685 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2687 i386_jcc(I386_CC_NE, a);
2689 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2692 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2694 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2696 i386_jcc(I386_CC_NE, a);
2698 /* XXX: change this when we use registers */
2699 i386_fldl_membase(REG_SP, src->regoff * 8);
2700 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP1);
2701 i386_call_reg(REG_ITMP1);
2702 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2703 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2706 panic("D2L: longs have to be in memory");
2710 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2712 var_to_reg_flt(s1, src, REG_FTMP1);
2713 d = reg_of_var(iptr->dst, REG_FTMP3);
2715 store_reg_to_var_flt(iptr->dst, d);
2718 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2720 var_to_reg_flt(s1, src, REG_FTMP1);
2721 d = reg_of_var(iptr->dst, REG_FTMP3);
2723 store_reg_to_var_flt(iptr->dst, d);
2726 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2729 /* exchanged to skip fxch */
2730 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2731 var_to_reg_flt(s1, src, REG_FTMP2);
2732 d = reg_of_var(iptr->dst, REG_ITMP1);
2737 i386_test_imm_reg(0x400, EAX); /* unordered treat as GT */
2738 i386_jcc(I386_CC_E, 6);
2739 i386_alu_imm_reg(I386_AND, 0x000000ff, EAX);
2741 i386_mov_imm_reg(0, d); /* does not affect flags */
2742 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2743 i386_jcc(I386_CC_B, 1 + 5);
2747 store_reg_to_var_int(iptr->dst, d);
2750 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2753 /* exchanged to skip fxch */
2754 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2755 var_to_reg_flt(s1, src, REG_FTMP2);
2756 d = reg_of_var(iptr->dst, REG_ITMP1);
2761 i386_test_imm_reg(0x400, EAX); /* unordered treat as LT */
2762 i386_jcc(I386_CC_E, 3);
2763 i386_movb_imm_reg(1, I386_AH);
2765 i386_mov_imm_reg(0, d); /* does not affect flags */
2766 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2767 i386_jcc(I386_CC_B, 1 + 5);
2771 store_reg_to_var_int(iptr->dst, d);
2775 /* memory operations **************************************************/
2777 #define gen_bound_check \
2778 if (checkbounds) { \
2779 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2780 i386_jcc(I386_CC_AE, 0); \
2781 codegen_addxboundrefs(mcodeptr); \
2784 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2786 var_to_reg_int(s1, src, REG_ITMP1);
2787 d = reg_of_var(iptr->dst, REG_ITMP1);
2788 gen_nullptr_check(s1);
2789 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2790 store_reg_to_var_int(iptr->dst, d);
2793 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2795 var_to_reg_int(s1, src->prev, REG_ITMP1);
2796 var_to_reg_int(s2, src, REG_ITMP2);
2797 d = reg_of_var(iptr->dst, REG_ITMP1);
2798 if (iptr->op1 == 0) {
2799 gen_nullptr_check(s1);
2802 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2803 store_reg_to_var_int(iptr->dst, d);
2806 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2808 var_to_reg_int(s1, src->prev, REG_ITMP1);
2809 var_to_reg_int(s2, src, REG_ITMP2);
2810 d = reg_of_var(iptr->dst, REG_ITMP3);
2811 if (iptr->op1 == 0) {
2812 gen_nullptr_check(s1);
2816 if (iptr->dst->flags & INMEMORY) {
2817 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2818 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2819 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2820 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2824 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2826 var_to_reg_int(s1, src->prev, REG_ITMP1);
2827 var_to_reg_int(s2, src, REG_ITMP2);
2828 d = reg_of_var(iptr->dst, REG_ITMP1);
2829 if (iptr->op1 == 0) {
2830 gen_nullptr_check(s1);
2833 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2834 store_reg_to_var_int(iptr->dst, d);
2837 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2839 var_to_reg_int(s1, src->prev, REG_ITMP1);
2840 var_to_reg_int(s2, src, REG_ITMP2);
2841 d = reg_of_var(iptr->dst, REG_FTMP1);
2842 if (iptr->op1 == 0) {
2843 gen_nullptr_check(s1);
2846 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2848 store_reg_to_var_flt(iptr->dst, d);
2851 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2853 var_to_reg_int(s1, src->prev, REG_ITMP1);
2854 var_to_reg_int(s2, src, REG_ITMP2);
2855 d = reg_of_var(iptr->dst, REG_FTMP3);
2856 if (iptr->op1 == 0) {
2857 gen_nullptr_check(s1);
2860 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2862 store_reg_to_var_flt(iptr->dst, d);
2865 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2867 var_to_reg_int(s1, src->prev, REG_ITMP1);
2868 var_to_reg_int(s2, src, REG_ITMP2);
2869 d = reg_of_var(iptr->dst, REG_ITMP1);
2870 if (iptr->op1 == 0) {
2871 gen_nullptr_check(s1);
2874 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2875 store_reg_to_var_int(iptr->dst, d);
2878 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2880 var_to_reg_int(s1, src->prev, REG_ITMP1);
2881 var_to_reg_int(s2, src, REG_ITMP2);
2882 d = reg_of_var(iptr->dst, REG_ITMP1);
2883 if (iptr->op1 == 0) {
2884 gen_nullptr_check(s1);
2887 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2888 store_reg_to_var_int(iptr->dst, d);
2891 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2893 var_to_reg_int(s1, src->prev, REG_ITMP1);
2894 var_to_reg_int(s2, src, REG_ITMP2);
2895 d = reg_of_var(iptr->dst, REG_ITMP1);
2896 if (iptr->op1 == 0) {
2897 gen_nullptr_check(s1);
2900 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2901 store_reg_to_var_int(iptr->dst, d);
2905 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2907 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2908 var_to_reg_int(s2, src->prev, REG_ITMP2);
2909 if (iptr->op1 == 0) {
2910 gen_nullptr_check(s1);
2913 var_to_reg_int(s3, src, REG_ITMP3);
2914 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2917 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2919 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2920 var_to_reg_int(s2, src->prev, REG_ITMP2);
2921 if (iptr->op1 == 0) {
2922 gen_nullptr_check(s1);
2926 if (src->flags & INMEMORY) {
2927 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2928 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2929 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2930 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2934 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2936 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2937 var_to_reg_int(s2, src->prev, REG_ITMP2);
2938 if (iptr->op1 == 0) {
2939 gen_nullptr_check(s1);
2942 var_to_reg_int(s3, src, REG_ITMP3);
2943 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2946 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2948 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2949 var_to_reg_int(s2, src->prev, REG_ITMP2);
2950 if (iptr->op1 == 0) {
2951 gen_nullptr_check(s1);
2954 var_to_reg_flt(s3, src, REG_FTMP1);
2955 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2959 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2961 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2962 var_to_reg_int(s2, src->prev, REG_ITMP2);
2963 if (iptr->op1 == 0) {
2964 gen_nullptr_check(s1);
2967 var_to_reg_flt(s3, src, REG_FTMP1);
2968 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2972 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2974 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2975 var_to_reg_int(s2, src->prev, REG_ITMP2);
2976 if (iptr->op1 == 0) {
2977 gen_nullptr_check(s1);
2980 var_to_reg_int(s3, src, REG_ITMP3);
2981 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2984 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2986 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2987 var_to_reg_int(s2, src->prev, REG_ITMP2);
2988 if (iptr->op1 == 0) {
2989 gen_nullptr_check(s1);
2992 var_to_reg_int(s3, src, REG_ITMP3);
2993 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2996 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2998 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2999 var_to_reg_int(s2, src->prev, REG_ITMP2);
3000 if (iptr->op1 == 0) {
3001 gen_nullptr_check(s1);
3004 var_to_reg_int(s3, src, REG_ITMP3);
3005 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
3006 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3010 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3011 /* op1 = type, val.a = field address */
3013 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3014 /* here it's slightly slower */
3015 i386_mov_imm_reg(0, REG_ITMP2);
3016 dseg_adddata(mcodeptr);
3017 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3018 switch (iptr->op1) {
3021 var_to_reg_int(s2, src, REG_ITMP1);
3022 i386_mov_reg_membase(s2, REG_ITMP2, 0);
3025 if (src->flags & INMEMORY) {
3026 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3027 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
3028 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3029 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
3031 panic("PUTSTATIC: longs have to be in memory");
3035 var_to_reg_flt(s2, src, REG_FTMP1);
3036 i386_fstps_membase(REG_ITMP2, 0);
3040 var_to_reg_flt(s2, src, REG_FTMP1);
3041 i386_fstpl_membase(REG_ITMP2, 0);
3044 default: panic ("internal error");
3048 case ICMD_GETSTATIC: /* ... ==> ..., value */
3049 /* op1 = type, val.a = field address */
3051 a = dseg_addaddress(&(((fieldinfo *)(iptr->val.a))->value));
3052 i386_mov_imm_reg(0, REG_ITMP2);
3053 dseg_adddata(mcodeptr);
3054 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3055 switch (iptr->op1) {
3058 d = reg_of_var(iptr->dst, REG_ITMP1);
3059 i386_mov_membase_reg(REG_ITMP2, 0, d);
3060 store_reg_to_var_int(iptr->dst, d);
3063 d = reg_of_var(iptr->dst, REG_NULL);
3064 if (iptr->dst->flags & INMEMORY) {
3065 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3066 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3067 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3068 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3070 panic("GETSTATIC: longs have to be in memory");
3074 d = reg_of_var(iptr->dst, REG_FTMP1);
3075 i386_flds_membase(REG_ITMP2, 0);
3077 store_reg_to_var_flt(iptr->dst, d);
3080 d = reg_of_var(iptr->dst, REG_FTMP1);
3081 i386_fldl_membase(REG_ITMP2, 0);
3083 store_reg_to_var_flt(iptr->dst, d);
3085 default: panic ("internal error");
3089 case ICMD_PUTFIELD: /* ..., value ==> ... */
3090 /* op1 = type, val.i = field offset */
3092 a = ((fieldinfo *)(iptr->val.a))->offset;
3093 switch (iptr->op1) {
3096 var_to_reg_int(s1, src->prev, REG_ITMP1);
3097 var_to_reg_int(s2, src, REG_ITMP2);
3098 gen_nullptr_check(s1);
3099 i386_mov_reg_membase(s2, s1, a);
3102 var_to_reg_int(s1, src->prev, REG_ITMP1);
3103 gen_nullptr_check(s1);
3104 if (src->flags & INMEMORY) {
3105 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3106 i386_mov_reg_membase(REG_ITMP2, s1, a);
3107 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3108 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3110 panic("PUTFIELD: longs have to be in memory");
3114 var_to_reg_int(s1, src->prev, REG_ITMP1);
3115 var_to_reg_flt(s2, src, REG_FTMP1);
3116 gen_nullptr_check(s1);
3117 i386_fstps_membase(s1, a);
3121 var_to_reg_int(s1, src->prev, REG_ITMP1);
3122 var_to_reg_flt(s2, src, REG_FTMP1);
3123 gen_nullptr_check(s1);
3124 i386_fstpl_membase(s1, a);
3127 default: panic ("internal error");
3131 case ICMD_GETFIELD: /* ... ==> ..., value */
3132 /* op1 = type, val.i = field offset */
3134 a = ((fieldinfo *)(iptr->val.a))->offset;
3135 switch (iptr->op1) {
3138 var_to_reg_int(s1, src, REG_ITMP1);
3139 d = reg_of_var(iptr->dst, REG_ITMP2);
3140 gen_nullptr_check(s1);
3141 i386_mov_membase_reg(s1, a, d);
3142 store_reg_to_var_int(iptr->dst, d);
3145 var_to_reg_int(s1, src, REG_ITMP1);
3146 d = reg_of_var(iptr->dst, REG_NULL);
3147 gen_nullptr_check(s1);
3148 i386_mov_membase_reg(s1, a, REG_ITMP2);
3149 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3150 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3151 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3154 var_to_reg_int(s1, src, REG_ITMP1);
3155 d = reg_of_var(iptr->dst, REG_FTMP1);
3156 gen_nullptr_check(s1);
3157 i386_flds_membase(s1, a);
3159 store_reg_to_var_flt(iptr->dst, d);
3162 var_to_reg_int(s1, src, REG_ITMP1);
3163 d = reg_of_var(iptr->dst, REG_FTMP1);
3164 gen_nullptr_check(s1);
3165 i386_fldl_membase(s1, a);
3167 store_reg_to_var_flt(iptr->dst, d);
3169 default: panic ("internal error");
3174 /* branch operations **************************************************/
3177 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3178 #define ALIGNCODENOP do {} while (0)
3180 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3182 var_to_reg_int(s1, src, REG_ITMP1);
3183 M_INTMOVE(s1, REG_ITMP1_XPTR);
3185 i386_call_imm(0); /* passing exception pointer */
3186 i386_pop_reg(REG_ITMP2_XPC);
3188 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
3189 i386_jmp_reg(REG_ITMP3);
3193 case ICMD_GOTO: /* ... ==> ... */
3194 /* op1 = target JavaVM pc */
3197 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3201 case ICMD_JSR: /* ... ==> ... */
3202 /* op1 = target JavaVM pc */
3205 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3208 case ICMD_RET: /* ... ==> ... */
3209 /* op1 = local variable */
3211 var = &(locals[iptr->op1][TYPE_ADR]);
3212 var_to_reg_int(s1, var, REG_ITMP1);
3216 case ICMD_IFNULL: /* ..., value ==> ... */
3217 /* op1 = target JavaVM pc */
3219 if (src->flags & INMEMORY) {
3220 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3223 i386_test_reg_reg(src->regoff, src->regoff);
3225 i386_jcc(I386_CC_E, 0);
3226 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3229 case ICMD_IFNONNULL: /* ..., value ==> ... */
3230 /* op1 = target JavaVM pc */
3232 if (src->flags & INMEMORY) {
3233 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3236 i386_test_reg_reg(src->regoff, src->regoff);
3238 i386_jcc(I386_CC_NE, 0);
3239 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3242 case ICMD_IFEQ: /* ..., value ==> ... */
3243 /* op1 = target JavaVM pc, val.i = constant */
3245 if (src->flags & INMEMORY) {
3246 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3249 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3251 i386_jcc(I386_CC_E, 0);
3252 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3255 case ICMD_IFLT: /* ..., value ==> ... */
3256 /* op1 = target JavaVM pc, val.i = constant */
3258 if (src->flags & INMEMORY) {
3259 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3262 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3264 i386_jcc(I386_CC_L, 0);
3265 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3268 case ICMD_IFLE: /* ..., value ==> ... */
3269 /* op1 = target JavaVM pc, val.i = constant */
3271 if (src->flags & INMEMORY) {
3272 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3275 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3277 i386_jcc(I386_CC_LE, 0);
3278 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3281 case ICMD_IFNE: /* ..., value ==> ... */
3282 /* op1 = target JavaVM pc, val.i = constant */
3284 if (src->flags & INMEMORY) {
3285 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3288 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3290 i386_jcc(I386_CC_NE, 0);
3291 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3294 case ICMD_IFGT: /* ..., value ==> ... */
3295 /* op1 = target JavaVM pc, val.i = constant */
3297 if (src->flags & INMEMORY) {
3298 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3301 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3303 i386_jcc(I386_CC_G, 0);
3304 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3307 case ICMD_IFGE: /* ..., value ==> ... */
3308 /* op1 = target JavaVM pc, val.i = constant */
3310 if (src->flags & INMEMORY) {
3311 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3314 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3316 i386_jcc(I386_CC_GE, 0);
3317 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3320 case ICMD_IF_LEQ: /* ..., value ==> ... */
3321 /* op1 = target JavaVM pc, val.l = constant */
3323 if (src->flags & INMEMORY) {
3324 if (iptr->val.l == 0) {
3325 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3326 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3329 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3330 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3331 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3332 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3333 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3336 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3337 i386_jcc(I386_CC_E, 0);
3338 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3341 case ICMD_IF_LLT: /* ..., value ==> ... */
3342 /* op1 = target JavaVM pc, val.l = constant */
3344 if (src->flags & INMEMORY) {
3345 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3346 i386_jcc(I386_CC_L, 0);
3347 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3350 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3351 CALCIMMEDIATEBYTES(a, iptr->val.l);
3353 i386_jcc(I386_CC_G, a);
3355 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3356 i386_jcc(I386_CC_B, 0);
3357 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3361 case ICMD_IF_LLE: /* ..., value ==> ... */
3362 /* op1 = target JavaVM pc, val.l = constant */
3364 if (src->flags & INMEMORY) {
3365 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3366 i386_jcc(I386_CC_L, 0);
3367 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3370 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3371 CALCIMMEDIATEBYTES(a, iptr->val.l);
3373 i386_jcc(I386_CC_G, a);
3375 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3376 i386_jcc(I386_CC_BE, 0);
3377 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3381 case ICMD_IF_LNE: /* ..., value ==> ... */
3382 /* op1 = target JavaVM pc, val.l = constant */
3384 if (src->flags & INMEMORY) {
3385 if (iptr->val.l == 0) {
3386 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3387 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3390 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3391 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3392 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3393 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3394 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3397 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3398 i386_jcc(I386_CC_NE, 0);
3399 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3402 case ICMD_IF_LGT: /* ..., value ==> ... */
3403 /* op1 = target JavaVM pc, val.l = constant */
3405 if (src->flags & INMEMORY) {
3406 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3407 i386_jcc(I386_CC_G, 0);
3408 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3411 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3412 CALCIMMEDIATEBYTES(a, iptr->val.l);
3414 i386_jcc(I386_CC_L, a);
3416 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3417 i386_jcc(I386_CC_A, 0);
3418 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3422 case ICMD_IF_LGE: /* ..., value ==> ... */
3423 /* op1 = target JavaVM pc, val.l = constant */
3425 if (src->flags & INMEMORY) {
3426 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3427 i386_jcc(I386_CC_G, 0);
3428 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3431 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3432 CALCIMMEDIATEBYTES(a, iptr->val.l);
3434 i386_jcc(I386_CC_L, a);
3436 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3437 i386_jcc(I386_CC_AE, 0);
3438 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3442 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3443 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3445 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3446 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3447 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3449 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3450 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3452 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3453 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3456 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3458 i386_jcc(I386_CC_E, 0);
3459 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3462 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3463 /* op1 = target JavaVM pc */
3465 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3466 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3467 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3468 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3469 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3470 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3471 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3473 i386_jcc(I386_CC_E, 0);
3474 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3477 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3478 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3480 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3481 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3482 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3484 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3485 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3487 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3488 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3491 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3493 i386_jcc(I386_CC_NE, 0);
3494 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3497 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3498 /* op1 = target JavaVM pc */
3500 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3501 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3502 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3503 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3504 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3505 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3506 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3508 i386_jcc(I386_CC_NE, 0);
3509 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3512 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3513 /* op1 = target JavaVM pc */
3515 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3516 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3517 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3519 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3520 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3522 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3523 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3526 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3528 i386_jcc(I386_CC_L, 0);
3529 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3532 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3533 /* op1 = target JavaVM pc */
3535 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3536 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3537 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3538 i386_jcc(I386_CC_L, 0);
3539 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3542 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3543 CALCOFFSETBYTES(a, REG_SP, src->regoff);
3545 i386_jcc(I386_CC_G, a);
3547 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3548 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3549 i386_jcc(I386_CC_B, 0);
3550 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3554 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3555 /* op1 = target JavaVM pc */
3557 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3558 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3559 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3561 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3562 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3564 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3565 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3568 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3570 i386_jcc(I386_CC_G, 0);
3571 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3574 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3575 /* op1 = target JavaVM pc */
3577 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3578 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3579 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3580 i386_jcc(I386_CC_G, 0);
3581 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3584 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3585 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3587 i386_jcc(I386_CC_L, a);
3589 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3590 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3591 i386_jcc(I386_CC_A, 0);
3592 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3596 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3597 /* op1 = target JavaVM pc */
3599 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3600 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3601 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3603 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3604 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3606 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3607 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3610 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3612 i386_jcc(I386_CC_LE, 0);
3613 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3616 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3617 /* op1 = target JavaVM pc */
3619 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3620 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3621 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3622 i386_jcc(I386_CC_L, 0);
3623 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3626 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3627 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3629 i386_jcc(I386_CC_G, a);
3631 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3632 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3633 i386_jcc(I386_CC_BE, 0);
3634 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3638 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3639 /* op1 = target JavaVM pc */
3641 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3642 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3643 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3645 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3646 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3648 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3649 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3652 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3654 i386_jcc(I386_CC_GE, 0);
3655 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3658 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3659 /* op1 = target JavaVM pc */
3661 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3662 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3663 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3664 i386_jcc(I386_CC_G, 0);
3665 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3668 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3669 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3671 i386_jcc(I386_CC_L, a);
3673 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3674 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3675 i386_jcc(I386_CC_AE, 0);
3676 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3680 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3682 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3685 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3686 /* val.i = constant */
3688 d = reg_of_var(iptr->dst, REG_NULL);
3689 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3692 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3693 /* val.i = constant */
3695 d = reg_of_var(iptr->dst, REG_NULL);
3696 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3699 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3700 /* val.i = constant */
3702 d = reg_of_var(iptr->dst, REG_NULL);
3703 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3706 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3707 /* val.i = constant */
3709 d = reg_of_var(iptr->dst, REG_NULL);
3710 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3713 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3714 /* val.i = constant */
3716 d = reg_of_var(iptr->dst, REG_NULL);
3717 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3720 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3721 /* val.i = constant */
3723 d = reg_of_var(iptr->dst, REG_NULL);
3724 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3728 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3732 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3733 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3734 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3735 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3736 i386_mov_imm_reg((s4) asm_builtin_monitorexit, REG_ITMP1);
3737 i386_call_reg(REG_ITMP1);
3738 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3741 var_to_reg_int(s1, src, REG_RESULT);
3742 M_INTMOVE(s1, REG_RESULT);
3743 goto nowperformreturn;
3745 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3748 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3749 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3750 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3751 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3752 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3753 i386_call_reg(REG_ITMP1);
3754 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3757 if (src->flags & INMEMORY) {
3758 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3759 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3762 panic("LRETURN: longs have to be in memory");
3764 goto nowperformreturn;
3766 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3769 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3770 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3771 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3772 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3773 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3774 i386_call_reg(REG_ITMP1);
3775 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3778 var_to_reg_flt(s1, src, REG_FRESULT);
3779 /* this may be an early return -- keep the offset correct for the remaining code */
3781 goto nowperformreturn;
3783 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3786 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3787 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3788 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3789 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3790 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3791 i386_call_reg(REG_ITMP1);
3792 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3795 var_to_reg_flt(s1, src, REG_FRESULT);
3796 /* this may be an early return -- keep the offset correct for the remaining code */
3798 goto nowperformreturn;
3800 case ICMD_RETURN: /* ... ==> ... */
3803 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3804 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3805 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3806 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3807 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3808 i386_call_reg(REG_ITMP1);
3809 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3817 p = parentargs_base;
3819 /* restore saved registers */
3820 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3822 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3824 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3826 i386_fldl_membase(REG_SP, p * 8);
3828 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3829 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3831 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3836 /* deallocate stack */
3837 if (parentargs_base) {
3838 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3841 /* call trace function */
3843 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3845 i386_mov_imm_membase((s4) method, REG_SP, 0);
3847 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3848 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3850 i386_fstl_membase(REG_SP, 4 + 8);
3851 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3853 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3854 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3855 i386_call_reg(REG_ITMP1);
3857 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3858 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3860 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3869 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3874 tptr = (void **) iptr->target;
3876 s4ptr = iptr->val.a;
3877 l = s4ptr[1]; /* low */
3878 i = s4ptr[2]; /* high */
3880 var_to_reg_int(s1, src, REG_ITMP1);
3881 M_INTMOVE(s1, REG_ITMP1);
3883 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3889 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3890 i386_jcc(I386_CC_A, 0);
3892 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3893 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3895 /* build jump table top down and use address of lowest entry */
3897 /* s4ptr += 3 + i; */
3901 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3902 dseg_addtarget((basicblock *) tptr[0]);
3906 /* length of dataseg after last dseg_addtarget is used by load */
3908 i386_mov_imm_reg(0, REG_ITMP2);
3909 dseg_adddata(mcodeptr);
3910 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3911 i386_jmp_reg(REG_ITMP1);
3917 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3919 s4 i, l, val, *s4ptr;
3922 tptr = (void **) iptr->target;
3924 s4ptr = iptr->val.a;
3925 l = s4ptr[0]; /* default */
3926 i = s4ptr[1]; /* count */
3928 MCODECHECK((i<<2)+8);
3929 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3935 i386_alu_imm_reg(I386_CMP, val, s1);
3936 i386_jcc(I386_CC_E, 0);
3937 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3938 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3942 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3944 tptr = (void **) iptr->target;
3945 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3952 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3953 /* op1 = return type, val.a = function pointer*/
3957 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3958 /* op1 = return type, val.a = function pointer*/
3962 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3963 /* op1 = return type, val.a = function pointer*/
3967 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3968 /* op1 = arg count, val.a = method pointer */
3970 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3971 /* op1 = arg count, val.a = method pointer */
3973 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3974 /* op1 = arg count, val.a = method pointer */
3976 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3977 /* op1 = arg count, val.a = method pointer */
3985 MCODECHECK((s3 << 1) + 64);
3987 /* copy arguments to registers or stack location */
3989 for (; --s3 >= 0; src = src->prev) {
3990 if (src->varkind == ARGVAR) {
3994 if (IS_INT_LNG_TYPE(src->type)) {
3995 if (s3 < intreg_argnum) {
3996 panic("No integer argument registers available!");
3999 if (!IS_2_WORD_TYPE(src->type)) {
4000 if (src->flags & INMEMORY) {
4001 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4002 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4005 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4009 if (src->flags & INMEMORY) {
4010 M_LNGMEMMOVE(src->regoff, s3);
4013 panic("copy arguments: longs have to be in memory");
4019 if (s3 < fltreg_argnum) {
4020 panic("No float argument registers available!");
4023 var_to_reg_flt(d, src, REG_FTMP1);
4024 if (src->type == TYPE_FLT) {
4025 i386_fstps_membase(REG_SP, s3 * 8);
4028 i386_fstpl_membase(REG_SP, s3 * 8);
4035 switch (iptr->opc) {
4043 i386_mov_imm_reg(a, REG_ITMP1);
4044 i386_call_reg(REG_ITMP1);
4047 case ICMD_INVOKESTATIC:
4049 a = (s4) m->stubroutine;
4052 i386_mov_imm_reg(a, REG_ITMP2);
4053 i386_call_reg(REG_ITMP2);
4056 case ICMD_INVOKESPECIAL:
4058 a = (s4) m->stubroutine;
4061 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4062 gen_nullptr_check(REG_ITMP1);
4063 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4065 i386_mov_imm_reg(a, REG_ITMP2);
4066 i386_call_reg(REG_ITMP2);
4069 case ICMD_INVOKEVIRTUAL:
4073 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4074 gen_nullptr_check(REG_ITMP1);
4075 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4076 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4078 i386_call_reg(REG_ITMP1);
4081 case ICMD_INVOKEINTERFACE:
4086 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4087 gen_nullptr_check(REG_ITMP1);
4088 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4089 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4090 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4092 i386_call_reg(REG_ITMP1);
4097 error("Unkown ICMD-Command: %d", iptr->opc);
4100 /* d contains return type */
4102 if (d != TYPE_VOID) {
4103 d = reg_of_var(iptr->dst, REG_NULL);
4105 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4106 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4107 if (iptr->dst->flags & INMEMORY) {
4108 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4109 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4112 panic("RETURN: longs have to be in memory");
4116 if (iptr->dst->flags & INMEMORY) {
4117 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4120 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4125 /* fld from called function -- has other fpu_st_offset counter */
4127 store_reg_to_var_flt(iptr->dst, d);
4134 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4136 /* op1: 0 == array, 1 == class */
4137 /* val.a: (classinfo*) superclass */
4139 /* superclass is an interface:
4141 * return (sub != NULL) &&
4142 * (sub->vftbl->interfacetablelength > super->index) &&
4143 * (sub->vftbl->interfacetable[-super->index] != NULL);
4145 * superclass is a class:
4147 * return ((sub != NULL) && (0
4148 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4149 * super->vftbl->diffvall));
4153 classinfo *super = (classinfo*) iptr->val.a;
4155 var_to_reg_int(s1, src, REG_ITMP1);
4156 d = reg_of_var(iptr->dst, REG_ITMP3);
4158 M_INTMOVE(s1, REG_ITMP1);
4161 i386_alu_reg_reg(I386_XOR, d, d);
4162 if (iptr->op1) { /* class/interface */
4163 if (super->flags & ACC_INTERFACE) { /* interface */
4164 i386_test_reg_reg(s1, s1);
4166 /* TODO: clean up this calculation */
4168 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4171 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4174 /* CALCOFFSETBYTES(a, super->index); */
4175 CALCIMMEDIATEBYTES(a, super->index);
4181 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4188 i386_jcc(I386_CC_E, a);
4190 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4191 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4192 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4194 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4196 /* TODO: clean up this calculation */
4199 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4206 i386_jcc(I386_CC_LE, a);
4207 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4209 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4210 /* i386_setcc_reg(I386_CC_A, d); */
4211 /* i386_jcc(I386_CC_BE, 5); */
4212 i386_jcc(I386_CC_E, 5);
4213 i386_mov_imm_reg(1, d);
4216 } else { /* class */
4217 i386_test_reg_reg(s1, s1);
4219 /* TODO: clean up this calculation */
4221 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4224 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4226 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4229 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4239 i386_jcc(I386_CC_E, a);
4241 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4242 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4243 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4244 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4245 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4246 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4247 i386_alu_reg_reg(I386_XOR, d, d);
4248 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4249 i386_jcc(I386_CC_A, 5);
4250 i386_mov_imm_reg(1, d);
4254 panic ("internal error: no inlined array instanceof");
4256 store_reg_to_var_int(iptr->dst, d);
4259 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4261 /* op1: 0 == array, 1 == class */
4262 /* val.a: (classinfo*) superclass */
4264 /* superclass is an interface:
4266 * OK if ((sub == NULL) ||
4267 * (sub->vftbl->interfacetablelength > super->index) &&
4268 * (sub->vftbl->interfacetable[-super->index] != NULL));
4270 * superclass is a class:
4272 * OK if ((sub == NULL) || (0
4273 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4274 * super->vftbl->diffvall));
4278 classinfo *super = (classinfo*) iptr->val.a;
4280 d = reg_of_var(iptr->dst, REG_ITMP3);
4281 var_to_reg_int(s1, src, d);
4282 if (iptr->op1) { /* class/interface */
4283 if (super->flags & ACC_INTERFACE) { /* interface */
4284 i386_test_reg_reg(s1, s1);
4286 /* TODO: clean up this calculation */
4288 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4291 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4294 /* CALCOFFSETBYTES(a, super->index); */
4295 CALCIMMEDIATEBYTES(a, super->index);
4301 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4306 i386_jcc(I386_CC_E, a);
4308 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4309 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4310 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4312 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4313 i386_jcc(I386_CC_LE, 0);
4314 codegen_addxcastrefs(mcodeptr);
4315 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4317 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4318 i386_jcc(I386_CC_E, 0);
4319 codegen_addxcastrefs(mcodeptr);
4321 } else { /* class */
4322 i386_test_reg_reg(s1, s1);
4324 /* TODO: clean up this calculation */
4326 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4331 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4333 if (d != REG_ITMP3) {
4335 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4338 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4344 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4351 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4358 i386_jcc(I386_CC_E, a);
4360 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4361 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4362 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4363 if (d != REG_ITMP3) {
4364 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4365 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4366 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4369 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4370 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4371 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4372 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4374 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4375 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4376 codegen_addxcastrefs(mcodeptr);
4380 panic ("internal error: no inlined array checkcast");
4383 store_reg_to_var_int(iptr->dst, d);
4386 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4388 if (src->flags & INMEMORY) {
4389 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4392 i386_test_reg_reg(src->regoff, src->regoff);
4394 i386_jcc(I386_CC_L, 0);
4395 codegen_addxcheckarefs(mcodeptr);
4398 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4399 /* op1 = dimension, val.a = array descriptor */
4401 /* check for negative sizes and copy sizes to stack if necessary */
4403 MCODECHECK((iptr->op1 << 1) + 64);
4405 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4406 if (src->flags & INMEMORY) {
4407 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4410 i386_test_reg_reg(src->regoff, src->regoff);
4412 i386_jcc(I386_CC_L, 0);
4413 codegen_addxcheckarefs(mcodeptr);
4416 * copy sizes to new stack location, be cause native function
4417 * builtin_nmultianewarray access them as (int *)
4419 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4420 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4422 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4424 if (src->varkind != ARGVAR) {
4425 if (src->flags & INMEMORY) {
4426 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4427 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4430 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4434 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4436 /* a0 = dimension count */
4438 /* save stack pointer */
4439 M_INTMOVE(REG_SP, REG_ITMP1);
4441 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4442 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4444 /* a1 = arraydescriptor */
4446 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4448 /* a2 = pointer to dimensions = stack pointer */
4450 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4452 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4453 i386_call_reg(REG_ITMP1);
4454 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4456 s1 = reg_of_var(iptr->dst, REG_RESULT);
4457 M_INTMOVE(REG_RESULT, s1);
4458 store_reg_to_var_int(iptr->dst, s1);
4462 default: error ("Unknown pseudo command: %d", iptr->opc);
4468 } /* for instruction */
4470 /* copy values to interface registers */
4472 src = bptr->outstack;
4473 len = bptr->outdepth;
4477 if ((src->varkind != STACKVAR)) {
4479 if (IS_FLT_DBL_TYPE(s2)) {
4480 var_to_reg_flt(s1, src, REG_FTMP1);
4481 if (!(interfaces[len][s2].flags & INMEMORY)) {
4482 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4485 panic("double store");
4486 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4490 var_to_reg_int(s1, src, REG_ITMP1);
4491 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4492 if (!(interfaces[len][s2].flags & INMEMORY)) {
4493 M_INTMOVE(s1, interfaces[len][s2].regoff);
4496 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4500 if (interfaces[len][s2].flags & INMEMORY) {
4501 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4504 panic("copy interface registers: longs have to be in memory (end)");
4511 } /* if (bptr -> flags >= BBREACHED) */
4512 } /* for basic block */
4514 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4518 /* generate bound check stubs */
4519 u1 *xcodeptr = NULL;
4521 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4522 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4523 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4524 xboundrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4529 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4530 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4534 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4535 dseg_adddata(mcodeptr);
4536 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4537 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4539 if (xcodeptr != NULL) {
4540 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4543 xcodeptr = mcodeptr;
4545 i386_mov_imm_reg((s4) proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
4546 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4547 i386_jmp_reg(REG_ITMP3);
4551 /* generate negative array size check stubs */
4554 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4555 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4556 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4557 xcheckarefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4561 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4562 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4566 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4567 dseg_adddata(mcodeptr);
4568 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4569 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4571 if (xcodeptr != NULL) {
4572 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4575 xcodeptr = mcodeptr;
4577 i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
4578 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4579 i386_jmp_reg(REG_ITMP3);
4583 /* generate cast check stubs */
4586 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4587 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4588 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4589 xcastrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4593 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4594 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4598 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4599 dseg_adddata(mcodeptr);
4600 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4601 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4603 if (xcodeptr != NULL) {
4604 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4607 xcodeptr = mcodeptr;
4609 i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
4610 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4611 i386_jmp_reg(REG_ITMP3);
4615 /* generate divide by zero check stubs */
4618 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4619 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4620 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4621 xdivrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4625 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4626 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4630 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4631 dseg_adddata(mcodeptr);
4632 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4633 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4635 if (xcodeptr != NULL) {
4636 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4639 xcodeptr = mcodeptr;
4641 i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
4642 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4643 i386_jmp_reg(REG_ITMP3);
4647 /* generate null pointer check stubs */
4650 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4651 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4652 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4653 xnullrefs->branchpos, (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4657 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4658 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4662 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4663 dseg_adddata(mcodeptr);
4664 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4665 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4667 if (xcodeptr != NULL) {
4668 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4671 xcodeptr = mcodeptr;
4673 i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
4674 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4675 i386_jmp_reg(REG_ITMP3);
4680 codegen_finish((int)((u1*) mcodeptr - mcodebase));
4684 /* function createcompilerstub *************************************************
4686 creates a stub routine which calls the compiler
4688 *******************************************************************************/
4690 #define COMPSTUBSIZE 12
4692 u1 *createcompilerstub(methodinfo *m)
4694 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4695 mcodeptr = s; /* code generation pointer */
4697 /* code for the stub */
4698 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4700 /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching */
4701 i386_mov_imm_reg((s4) asm_call_jit_compiler, REG_ITMP3); /* load address */
4702 i386_jmp_reg(REG_ITMP3); /* jump to compiler */
4705 count_cstub_len += COMPSTUBSIZE;
4712 /* function removecompilerstub *************************************************
4714 deletes a compilerstub from memory (simply by freeing it)
4716 *******************************************************************************/
4718 void removecompilerstub(u1 *stub)
4720 CFREE(stub, COMPSTUBSIZE);
4723 /* function: createnativestub **************************************************
4725 creates a stub routine which calls a native method
4727 *******************************************************************************/
4729 #define NATIVESTUBSIZE 320
4731 u1 *createnativestub(functionptr f, methodinfo *m)
4733 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4737 int stackframesize = 4; /* initial 4 bytes is space for jni env */
4738 int stackframeoffset = 4;
4742 mcodeptr = s; /* make macros work */
4744 if (m->flags & ACC_STATIC) {
4745 stackframesize += 4;
4746 stackframeoffset += 4;
4751 descriptor2types(m); /* set paramcount and paramtypes */
4754 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4756 for (p = 0; p < m->paramcount; p++) {
4757 t = m->paramtypes[p];
4758 if (IS_INT_LNG_TYPE(t)) {
4759 if (IS_2_WORD_TYPE(t)) {
4760 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4761 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4762 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4763 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4765 } else if (t == TYPE_ADR) {
4766 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4767 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4768 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4769 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4772 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
4774 i386_mov_reg_membase(EAX, REG_SP, p * 8);
4775 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
4779 if (t == TYPE_FLT) {
4780 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4781 i386_fstps_membase(REG_SP, p * 8);
4782 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4783 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4786 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4787 i386_fstpl_membase(REG_SP, p * 8);
4792 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4793 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4794 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4795 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4798 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4800 i386_mov_imm_reg((s4) asm_builtin_trace, REG_ITMP1);
4801 i386_call_reg(REG_ITMP1);
4803 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4807 * mark the whole fpu stack as free for native functions
4808 * (only for saved register count == 0)
4819 /* calculate stackframe size for native function */
4820 tptr = m->paramtypes;
4821 for (i = 0; i < m->paramcount; i++) {
4826 stackframesize += 4;
4831 stackframesize += 8;
4835 panic("unknown parameter type in native function");
4839 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4841 tptr = m->paramtypes;
4842 for (i = 0; i < m->paramcount; i++) {
4847 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4848 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4849 stackframeoffset += 4;
4854 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4855 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
4856 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4857 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
4858 stackframeoffset += 8;
4862 panic("unknown parameter type in native function");
4866 i386_mov_imm_membase((s4) &env, REG_SP, 0);
4867 if (m->flags & ACC_STATIC)
4868 i386_mov_imm_membase((s4) m->class, REG_SP,4);
4870 i386_mov_imm_reg((s4) f, REG_ITMP1);
4871 i386_call_reg(REG_ITMP1);
4872 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
4875 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4877 i386_mov_imm_membase((s4) m, REG_SP, 0);
4879 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4880 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4882 i386_fstl_membase(REG_SP, 4 + 8);
4883 i386_fsts_membase(REG_SP, 4 + 8 + 8);
4885 i386_mov_imm_reg((s4) asm_builtin_exittrace, REG_ITMP1);
4886 i386_call_reg(REG_ITMP1);
4888 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4889 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4891 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4894 /* we can't use REG_ITMP3 == REG_RESULT2 */
4895 i386_mov_imm_reg((s4) &exceptionptr, REG_ITMP2);
4896 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP2);
4897 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
4898 i386_jcc(I386_CC_NE, 1);
4902 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1_XPTR);
4903 i386_mov_imm_reg((s4) &exceptionptr, REG_ITMP2);
4904 i386_mov_imm_membase(0, REG_ITMP2, 0);
4905 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
4906 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
4908 i386_mov_imm_reg((s4) asm_handle_nat_exception, REG_ITMP3);
4909 i386_jmp_reg(REG_ITMP3);
4912 count_nstub_len += NATIVESTUBSIZE;
4918 /* function: removenativestub **************************************************
4920 removes a previously created native-stub from memory
4922 *******************************************************************************/
4924 void removenativestub(u1 *stub)
4926 CFREE(stub, NATIVESTUBSIZE);
4931 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
4933 if (iptr->dst->flags & INMEMORY) {
4934 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4935 if (src->regoff == iptr->dst->regoff) {
4936 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4937 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4939 } else if (src->prev->regoff == iptr->dst->regoff) {
4940 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4941 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4944 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4945 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
4946 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4949 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4950 if (src->regoff == iptr->dst->regoff) {
4951 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4954 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4955 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
4956 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4959 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4960 if (src->prev->regoff == iptr->dst->regoff) {
4961 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4964 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
4965 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
4966 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
4970 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
4971 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
4975 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4976 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4977 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4979 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
4980 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4981 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
4983 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
4984 M_INTMOVE(src->regoff, iptr->dst->regoff);
4985 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
4988 if (src->regoff == iptr->dst->regoff) {
4989 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
4992 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
4993 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
5001 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
5003 if (iptr->dst->flags & INMEMORY) {
5004 if (src->flags & INMEMORY) {
5005 if (src->regoff == iptr->dst->regoff) {
5006 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5009 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5010 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
5011 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5015 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5016 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5020 if (src->flags & INMEMORY) {
5021 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5022 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5025 M_INTMOVE(src->regoff, iptr->dst->regoff);
5026 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5033 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
5035 if (iptr->dst->flags & INMEMORY) {
5036 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5037 if (src->regoff == iptr->dst->regoff) {
5038 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5039 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5040 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5041 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5043 } else if (src->prev->regoff == iptr->dst->regoff) {
5044 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5045 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5046 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5047 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5050 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5051 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5052 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5053 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5054 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5055 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5063 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5065 if (iptr->dst->flags & INMEMORY) {
5066 if (src->flags & INMEMORY) {
5067 if (src->regoff == iptr->dst->regoff) {
5068 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5069 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5072 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5073 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5074 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5075 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5076 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP1);
5077 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5085 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5087 if (iptr->dst->flags & INMEMORY) {
5088 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5089 if (src->prev->regoff == iptr->dst->regoff) {
5090 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5091 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5094 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5095 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5096 i386_shift_reg(shift_op, REG_ITMP1);
5097 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5100 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5101 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5102 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5103 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5105 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5106 if (src->prev->regoff == iptr->dst->regoff) {
5107 M_INTMOVE(src->regoff, ECX);
5108 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5111 M_INTMOVE(src->regoff, ECX);
5112 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5113 i386_shift_reg(shift_op, REG_ITMP1);
5114 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5118 M_INTMOVE(src->regoff, ECX);
5119 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5120 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5124 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5125 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5126 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5127 i386_shift_reg(shift_op, iptr->dst->regoff);
5129 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5130 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5131 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5132 i386_shift_reg(shift_op, iptr->dst->regoff);
5134 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5135 M_INTMOVE(src->regoff, ECX);
5136 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5137 i386_shift_reg(shift_op, iptr->dst->regoff);
5140 M_INTMOVE(src->regoff, ECX);
5141 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5142 i386_shift_reg(shift_op, iptr->dst->regoff);
5149 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5151 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5152 if (src->regoff == iptr->dst->regoff) {
5153 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5156 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5157 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5158 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5161 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5162 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5163 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5165 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5166 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5167 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5170 M_INTMOVE(src->regoff, iptr->dst->regoff);
5171 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5177 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5179 if (iptr->dst->flags & INMEMORY) {
5182 if (src->flags & INMEMORY) {
5183 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5186 i386_test_reg_reg(src->regoff, src->regoff);
5190 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 8);
5192 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5193 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5195 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5196 i386_jmp_imm(offset);
5197 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5201 if (src->flags & INMEMORY) {
5202 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5205 i386_test_reg_reg(src->regoff, src->regoff);
5208 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5209 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5211 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5213 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5223 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5224 *(mcodeptr++) = (u1) 0x89;
5225 i386_emit_reg((reg),(dreg));
5229 void i386_mov_imm_reg(s4 imm, s4 reg) {
5230 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5231 i386_emit_imm32((imm));
5235 void i386_movb_imm_reg(s4 imm, s4 reg) {
5236 *(mcodeptr++) = (u1) 0xc6;
5237 i386_emit_reg(0,(reg));
5238 i386_emit_imm8((imm));
5242 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5243 *(mcodeptr++) = (u1) 0x8b;
5244 i386_emit_membase((basereg),(disp),(reg));
5249 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5250 * constant membase immediate length of 32bit
5252 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5253 *(mcodeptr++) = (u1) 0x8b;
5254 i386_address_byte(2, (reg), (basereg));
5255 i386_emit_imm32((disp));
5259 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5260 *(mcodeptr++) = (u1) 0x89;
5261 i386_emit_membase((basereg),(disp),(reg));
5265 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5266 *(mcodeptr++) = (u1) 0x8b;
5267 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5271 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5272 *(mcodeptr++) = (u1) 0x89;
5273 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5277 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5278 *(mcodeptr++) = (u1) 0x66;
5279 *(mcodeptr++) = (u1) 0x89;
5280 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5284 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5285 *(mcodeptr++) = (u1) 0x88;
5286 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5290 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5291 *(mcodeptr++) = (u1) 0xc7;
5292 i386_emit_membase((basereg),(disp),0);
5293 i386_emit_imm32((imm));
5297 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5298 *(mcodeptr++) = (u1) 0x0f;
5299 *(mcodeptr++) = (u1) 0xbe;
5300 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5304 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5305 *(mcodeptr++) = (u1) 0x0f;
5306 *(mcodeptr++) = (u1) 0xbf;
5307 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5311 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5312 *(mcodeptr++) = (u1) 0x0f;
5313 *(mcodeptr++) = (u1) 0xb7;
5314 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5322 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5323 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5324 i386_emit_reg((reg),(dreg));
5328 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5329 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5330 i386_emit_membase((basereg),(disp),(reg));
5334 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5335 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5336 i386_emit_membase((basereg),(disp),(reg));
5340 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5341 if (i386_is_imm8(imm)) {
5342 *(mcodeptr++) = (u1) 0x83;
5343 i386_emit_reg((opc),(dreg));
5344 i386_emit_imm8((imm));
5346 *(mcodeptr++) = (u1) 0x81;
5347 i386_emit_reg((opc),(dreg));
5348 i386_emit_imm32((imm));
5353 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5354 if (i386_is_imm8(imm)) {
5355 *(mcodeptr++) = (u1) 0x83;
5356 i386_emit_membase((basereg),(disp),(opc));
5357 i386_emit_imm8((imm));
5359 *(mcodeptr++) = (u1) 0x81;
5360 i386_emit_membase((basereg),(disp),(opc));
5361 i386_emit_imm32((imm));
5366 void i386_test_reg_reg(s4 reg, s4 dreg) {
5367 *(mcodeptr++) = (u1) 0x85;
5368 i386_emit_reg((reg),(dreg));
5372 void i386_test_imm_reg(s4 imm, s4 reg) {
5373 *(mcodeptr++) = (u1) 0xf7;
5374 i386_emit_reg(0,(reg));
5375 i386_emit_imm32((imm));
5381 * inc, dec operations
5383 void i386_inc_reg(s4 reg) {
5384 *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
5388 void i386_inc_membase(s4 basereg, s4 disp) {
5389 *(mcodeptr++) = (u1) 0xff;
5390 i386_emit_membase((basereg),(disp),0);
5394 void i386_dec_reg(s4 reg) {
5395 *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
5399 void i386_dec_membase(s4 basereg, s4 disp) {
5400 *(mcodeptr++) = (u1) 0xff;
5401 i386_emit_membase((basereg),(disp),1);
5407 *(mcodeptr++) = (u1) 0x99;
5412 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5413 *(mcodeptr++) = (u1) 0x0f;
5414 *(mcodeptr++) = (u1) 0xaf;
5415 i386_emit_reg((dreg),(reg));
5419 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5420 *(mcodeptr++) = (u1) 0x0f;
5421 *(mcodeptr++) = (u1) 0xaf;
5422 i386_emit_membase((basereg),(disp),(dreg));
5426 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5427 if (i386_is_imm8((imm))) {
5428 *(mcodeptr++) = (u1) 0x6b;
5429 i386_emit_reg(0,(dreg));
5430 i386_emit_imm8((imm));
5432 *(mcodeptr++) = (u1) 0x69;
5433 i386_emit_reg(0,(dreg));
5434 i386_emit_imm32((imm));
5439 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5440 if (i386_is_imm8((imm))) {
5441 *(mcodeptr++) = (u1) 0x6b;
5442 i386_emit_reg((dreg),(reg));
5443 i386_emit_imm8((imm));
5445 *(mcodeptr++) = (u1) 0x69;
5446 i386_emit_reg((dreg),(reg));
5447 i386_emit_imm32((imm));
5452 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5453 if (i386_is_imm8((imm))) {
5454 *(mcodeptr++) = (u1) 0x6b;
5455 i386_emit_membase((basereg),(disp),(dreg));
5456 i386_emit_imm8((imm));
5458 *(mcodeptr++) = (u1) 0x69;
5459 i386_emit_membase((basereg),(disp),(dreg));
5460 i386_emit_imm32((imm));
5465 void i386_mul_membase(s4 basereg, s4 disp) {
5466 *(mcodeptr++) = (u1) 0xf7;
5467 i386_emit_membase((basereg),(disp),4);
5471 void i386_idiv_reg(s4 reg) {
5472 *(mcodeptr++) = (u1) 0xf7;
5473 i386_emit_reg(7,(reg));
5479 *(mcodeptr++) = (u1) 0xc3;
5487 void i386_shift_reg(s4 opc, s4 reg) {
5488 *(mcodeptr++) = (u1) 0xd3;
5489 i386_emit_reg((opc),(reg));
5493 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5494 *(mcodeptr++) = (u1) 0xd3;
5495 i386_emit_membase((basereg),(disp),(opc));
5499 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5501 *(mcodeptr++) = (u1) 0xd1;
5502 i386_emit_reg((opc),(dreg));
5504 *(mcodeptr++) = (u1) 0xc1;
5505 i386_emit_reg((opc),(dreg));
5506 i386_emit_imm8((imm));
5511 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5513 *(mcodeptr++) = (u1) 0xd1;
5514 i386_emit_membase((basereg),(disp),(opc));
5516 *(mcodeptr++) = (u1) 0xc1;
5517 i386_emit_membase((basereg),(disp),(opc));
5518 i386_emit_imm8((imm));
5523 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5524 *(mcodeptr++) = (u1) 0x0f;
5525 *(mcodeptr++) = (u1) 0xa5;
5526 i386_emit_reg((reg),(dreg));
5530 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5531 *(mcodeptr++) = (u1) 0x0f;
5532 *(mcodeptr++) = (u1) 0xa4;
5533 i386_emit_reg((reg),(dreg));
5534 i386_emit_imm8((imm));
5538 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5539 *(mcodeptr++) = (u1) 0x0f;
5540 *(mcodeptr++) = (u1) 0xa5;
5541 i386_emit_membase((basereg),(disp),(reg));
5545 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5546 *(mcodeptr++) = (u1) 0x0f;
5547 *(mcodeptr++) = (u1) 0xad;
5548 i386_emit_reg((reg),(dreg));
5552 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5553 *(mcodeptr++) = (u1) 0x0f;
5554 *(mcodeptr++) = (u1) 0xac;
5555 i386_emit_reg((reg),(dreg));
5556 i386_emit_imm8((imm));
5560 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5561 *(mcodeptr++) = (u1) 0x0f;
5562 *(mcodeptr++) = (u1) 0xad;
5563 i386_emit_membase((basereg),(disp),(reg));
5571 void i386_jmp_imm(s4 imm) {
5572 *(mcodeptr++) = (u1) 0xe9;
5573 i386_emit_imm32((imm));
5577 void i386_jmp_reg(s4 reg) {
5578 *(mcodeptr++) = (u1) 0xff;
5579 i386_emit_reg(4,(reg));
5583 void i386_jcc(s4 opc, s4 imm) {
5584 *(mcodeptr++) = (u1) 0x0f;
5585 *(mcodeptr++) = (u1) (0x80 + (opc));
5586 i386_emit_imm32((imm));
5592 * conditional set operations
5594 void i386_setcc_reg(s4 opc, s4 reg) {
5595 *(mcodeptr++) = (u1) 0x0f;
5596 *(mcodeptr++) = (u1) (0x90 + (opc));
5597 i386_emit_reg(0,(reg));
5601 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5602 *(mcodeptr++) = (u1) 0x0f;
5603 *(mcodeptr++) = (u1) (0x90 + (opc));
5604 i386_emit_membase((basereg),(disp),0);
5609 void i386_neg_reg(s4 reg) {
5610 *(mcodeptr++) = (u1) 0xf7;
5611 i386_emit_reg(3,(reg));
5615 void i386_neg_membase(s4 basereg, s4 disp) {
5616 *(mcodeptr++) = (u1) 0xf7;
5617 i386_emit_membase((basereg),(disp),3);
5622 void i386_push_imm(s4 imm) {
5623 *(mcodeptr++) = (u1) 0x68;
5624 i386_emit_imm32((imm));
5628 void i386_pop_reg(s4 reg) {
5629 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5634 *(mcodeptr++) = (u1) 0x90;
5641 void i386_call_reg(s4 reg) {
5642 *(mcodeptr++) = (u1) 0xff;
5643 i386_emit_reg(2,(reg));
5647 void i386_call_imm(s4 imm) {
5648 *(mcodeptr++) = (u1) 0xe8;
5649 i386_emit_imm32((imm));
5655 * floating point instructions
5658 *(mcodeptr++) = (u1) 0xd9;
5659 *(mcodeptr++) = (u1) 0xe8;
5664 *(mcodeptr++) = (u1) 0xd9;
5665 *(mcodeptr++) = (u1) 0xee;
5669 void i386_fld_reg(s4 reg) {
5670 *(mcodeptr++) = (u1) 0xd9;
5671 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5675 void i386_flds_membase(s4 basereg, s4 disp) {
5676 *(mcodeptr++) = (u1) 0xd9;
5677 i386_emit_membase((basereg),(disp),0);
5681 void i386_fldl_membase(s4 basereg, s4 disp) {
5682 *(mcodeptr++) = (u1) 0xdd;
5683 i386_emit_membase((basereg),(disp),0);
5687 void i386_fldt_membase(s4 basereg, s4 disp) {
5688 *(mcodeptr++) = (u1) 0xdb;
5689 i386_emit_membase((basereg),(disp),5);
5693 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5694 *(mcodeptr++) = (u1) 0xd9;
5695 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5699 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5700 *(mcodeptr++) = (u1) 0xdd;
5701 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5707 void i386_fildl_membase(s4 basereg, s4 disp) {
5708 *(mcodeptr++) = (u1) 0xdb;
5709 i386_emit_membase((basereg),(disp),0);
5713 void i386_fildll_membase(s4 basereg, s4 disp) {
5714 *(mcodeptr++) = (u1) 0xdf;
5715 i386_emit_membase((basereg),(disp),5);
5721 void i386_fst_reg(s4 reg) {
5722 *(mcodeptr++) = (u1) 0xdd;
5723 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5727 void i386_fsts_membase(s4 basereg, s4 disp) {
5728 *(mcodeptr++) = (u1) 0xd9;
5729 i386_emit_membase((basereg),(disp),2);
5733 void i386_fstl_membase(s4 basereg, s4 disp) {
5734 *(mcodeptr++) = (u1) 0xdd;
5735 i386_emit_membase((basereg),(disp),2);
5739 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5740 *(mcodeptr++) = (u1) 0xd9;
5741 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5745 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5746 *(mcodeptr++) = (u1) 0xdd;
5747 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5751 void i386_fstp_reg(s4 reg) {
5752 *(mcodeptr++) = (u1) 0xdd;
5753 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5757 void i386_fstps_membase(s4 basereg, s4 disp) {
5758 *(mcodeptr++) = (u1) 0xd9;
5759 i386_emit_membase((basereg),(disp),3);
5763 void i386_fstpl_membase(s4 basereg, s4 disp) {
5764 *(mcodeptr++) = (u1) 0xdd;
5765 i386_emit_membase((basereg),(disp),3);
5769 void i386_fstpt_membase(s4 basereg, s4 disp) {
5770 *(mcodeptr++) = (u1) 0xdb;
5771 i386_emit_membase((basereg),(disp),7);
5775 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5776 *(mcodeptr++) = (u1) 0xd9;
5777 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5781 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5782 *(mcodeptr++) = (u1) 0xdd;
5783 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5787 void i386_fistl_membase(s4 basereg, s4 disp) {
5788 *(mcodeptr++) = (u1) 0xdb;
5789 i386_emit_membase((basereg),(disp),2);
5793 void i386_fistpl_membase(s4 basereg, s4 disp) {
5794 *(mcodeptr++) = (u1) 0xdb;
5795 i386_emit_membase((basereg),(disp),3);
5799 void i386_fistpll_membase(s4 basereg, s4 disp) {
5800 *(mcodeptr++) = (u1) 0xdf;
5801 i386_emit_membase((basereg),(disp),7);
5806 *(mcodeptr++) = (u1) 0xd9;
5807 *(mcodeptr++) = (u1) 0xe0;
5812 *(mcodeptr++) = (u1) 0xde;
5813 *(mcodeptr++) = (u1) 0xc1;
5817 void i386_fadd_reg_st(s4 reg) {
5818 *(mcodeptr++) = (u1) 0xd8;
5819 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5823 void i386_fadd_st_reg(s4 reg) {
5824 *(mcodeptr++) = (u1) 0xdc;
5825 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5829 void i386_faddp_st_reg(s4 reg) {
5830 *(mcodeptr++) = (u1) 0xde;
5831 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5835 void i386_fadds_membase(s4 basereg, s4 disp) {
5836 *(mcodeptr++) = (u1) 0xd8;
5837 i386_emit_membase((basereg),(disp),0);
5841 void i386_faddl_membase(s4 basereg, s4 disp) {
5842 *(mcodeptr++) = (u1) 0xdc;
5843 i386_emit_membase((basereg),(disp),0);
5847 void i386_fsub_reg_st(s4 reg) {
5848 *(mcodeptr++) = (u1) 0xd8;
5849 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5853 void i386_fsub_st_reg(s4 reg) {
5854 *(mcodeptr++) = (u1) 0xdc;
5855 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5859 void i386_fsubp_st_reg(s4 reg) {
5860 *(mcodeptr++) = (u1) 0xde;
5861 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5866 *(mcodeptr++) = (u1) 0xde;
5867 *(mcodeptr++) = (u1) 0xe9;
5871 void i386_fsubs_membase(s4 basereg, s4 disp) {
5872 *(mcodeptr++) = (u1) 0xd8;
5873 i386_emit_membase((basereg),(disp),4);
5877 void i386_fsubl_membase(s4 basereg, s4 disp) {
5878 *(mcodeptr++) = (u1) 0xdc;
5879 i386_emit_membase((basereg),(disp),4);
5883 void i386_fmul_reg_st(s4 reg) {
5884 *(mcodeptr++) = (u1) 0xd8;
5885 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5889 void i386_fmul_st_reg(s4 reg) {
5890 *(mcodeptr++) = (u1) 0xdc;
5891 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5896 *(mcodeptr++) = (u1) 0xde;
5897 *(mcodeptr++) = (u1) 0xc9;
5901 void i386_fmulp_st_reg(s4 reg) {
5902 *(mcodeptr++) = (u1) 0xde;
5903 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5907 void i386_fmuls_membase(s4 basereg, s4 disp) {
5908 *(mcodeptr++) = (u1) 0xd8;
5909 i386_emit_membase((basereg),(disp),1);
5913 void i386_fmull_membase(s4 basereg, s4 disp) {
5914 *(mcodeptr++) = (u1) 0xdc;
5915 i386_emit_membase((basereg),(disp),1);
5919 void i386_fdiv_reg_st(s4 reg) {
5920 *(mcodeptr++) = (u1) 0xd8;
5921 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
5925 void i386_fdiv_st_reg(s4 reg) {
5926 *(mcodeptr++) = (u1) 0xdc;
5927 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5932 *(mcodeptr++) = (u1) 0xde;
5933 *(mcodeptr++) = (u1) 0xf9;
5937 void i386_fdivp_st_reg(s4 reg) {
5938 *(mcodeptr++) = (u1) 0xde;
5939 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
5944 *(mcodeptr++) = (u1) 0xd9;
5945 *(mcodeptr++) = (u1) 0xc9;
5949 void i386_fxch_reg(s4 reg) {
5950 *(mcodeptr++) = (u1) 0xd9;
5951 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
5956 *(mcodeptr++) = (u1) 0xd9;
5957 *(mcodeptr++) = (u1) 0xf8;
5961 void i386_fprem1() {
5962 *(mcodeptr++) = (u1) 0xd9;
5963 *(mcodeptr++) = (u1) 0xf5;
5968 *(mcodeptr++) = (u1) 0xdd;
5969 *(mcodeptr++) = (u1) 0xe1;
5973 void i386_fucom_reg(s4 reg) {
5974 *(mcodeptr++) = (u1) 0xdd;
5975 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5979 void i386_fucomp_reg(s4 reg) {
5980 *(mcodeptr++) = (u1) 0xdd;
5981 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5985 void i386_fucompp() {
5986 *(mcodeptr++) = (u1) 0xda;
5987 *(mcodeptr++) = (u1) 0xe9;
5991 void i386_fnstsw() {
5992 *(mcodeptr++) = (u1) 0xdf;
5993 *(mcodeptr++) = (u1) 0xe0;
5998 *(mcodeptr++) = (u1) 0x9e;
6003 *(mcodeptr++) = (u1) 0x9b;
6004 *(mcodeptr++) = (u1) 0xdb;
6005 *(mcodeptr++) = (u1) 0xe3;
6009 void i386_fldcw_mem(s4 mem) {
6010 *(mcodeptr++) = (u1) 0xd9;
6011 i386_emit_mem(5,(mem));
6015 void i386_fldcw_membase(s4 basereg, s4 disp) {
6016 *(mcodeptr++) = (u1) 0xd9;
6017 i386_emit_membase((basereg),(disp),5);
6022 *(mcodeptr++) = (u1) 0x9b;
6026 void i386_ffree_reg(s4 reg) {
6027 *(mcodeptr++) = (u1) 0xdd;
6028 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
6032 void i386_fdecstp() {
6033 *(mcodeptr++) = (u1) 0xd9;
6034 *(mcodeptr++) = (u1) 0xf6;
6038 void i386_fincstp() {
6039 *(mcodeptr++) = (u1) 0xd9;
6040 *(mcodeptr++) = (u1) 0xf7;
6045 * These are local overrides for various environment variables in Emacs.
6046 * Please do not remove this and leave it at the end of the file, where
6047 * Emacs will automagically detect them.
6048 * ---------------------------------------------------------------------
6051 * indent-tabs-mode: t