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 883 2004-01-14 12:42:52Z stefan $
50 #include "methodtable.h"
52 /* include independent code generation stuff */
53 #include "codegen.inc"
57 /* register descripton - array ************************************************/
59 /* #define REG_RES 0 reserved register for OS or code generator */
60 /* #define REG_RET 1 return value register */
61 /* #define REG_EXC 2 exception value register (only old jit) */
62 /* #define REG_SAV 3 (callee) saved register */
63 /* #define REG_TMP 4 scratch temporary register (caller saved) */
64 /* #define REG_ARG 5 argument register (caller saved) */
66 /* #define REG_END -1 last entry in tables */
69 we initially try to use %edx as scratch register, it cannot be used if we
70 have one of these ICMDs:
71 LMUL, LMULCONST, IDIV, IREM, LALOAD, AASTORE, LASTORE, IASTORE, CASTORE,
72 SASTORE, BASTORE, INSTANCEOF, CHECKCAST, I2L, F2L, D2L
75 REG_RET, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_SAV, REG_SAV, REG_SAV,
80 int nregdescfloat[] = {
81 /* rounding problems with callee saved registers */
82 /* REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
83 /* REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
84 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
89 /* additional functions and macros to generate code ***************************/
91 #define BlockPtrOfPC(pc) ((basicblock *) iptr->target)
95 #define COUNT_SPILLS count_spills++
101 #define CALCOFFSETBYTES(var, reg, val) \
102 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
103 else if ((s4) (val) != 0) (var) += 1; \
104 else if ((reg) == EBP) (var) += 1;
107 #define CALCIMMEDIATEBYTES(var, val) \
108 if ((s4) (val) < -128 || (s4) (val) > 127) (var) += 4; \
112 /* gen_nullptr_check(objreg) */
114 #define gen_nullptr_check(objreg) \
116 i386_test_reg_reg((objreg), (objreg)); \
117 i386_jcc(I386_CC_E, 0); \
118 codegen_addxnullrefs(mcodeptr); \
122 /* MCODECHECK(icnt) */
124 #define MCODECHECK(icnt) \
125 if ((mcodeptr + (icnt)) > (u1*) mcodeend) mcodeptr = (u1*) codegen_increase((u1*) mcodeptr)
128 generates an integer-move from register a to b.
129 if a and b are the same int-register, no code will be generated.
132 #define M_INTMOVE(reg,dreg) if ((reg) != (dreg)) { i386_mov_reg_reg((reg),(dreg)); }
136 generates a floating-point-move from register a to b.
137 if a and b are the same float-register, no code will be generated
140 #define M_FLTMOVE(reg,dreg) panic("M_FLTMOVE");
142 #define M_LNGMEMMOVE(reg,dreg) \
144 i386_mov_membase_reg(REG_SP, (reg) * 8, REG_ITMP1); \
145 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8); \
146 i386_mov_membase_reg(REG_SP, (reg) * 8 + 4, REG_ITMP1); \
147 i386_mov_reg_membase(REG_ITMP1, REG_SP, (dreg) * 8 + 4); \
152 this function generates code to fetch data from a pseudo-register
153 into a real register.
154 If the pseudo-register has actually been assigned to a real
155 register, no code will be emitted, since following operations
156 can use this register directly.
158 v: pseudoregister to be fetched from
159 tempregnum: temporary register to be used if v is actually spilled to ram
161 return: the register number, where the operand can be found after
162 fetching (this wil be either tempregnum or the register
163 number allready given to v)
166 #define var_to_reg_int(regnr,v,tempnr) \
167 if ((v)->flags & INMEMORY) { \
169 i386_mov_membase_reg(REG_SP, (v)->regoff * 8, tempnr); \
172 regnr = (v)->regoff; \
177 #define var_to_reg_flt(regnr,v,tempnr) \
178 if ((v)->type == TYPE_FLT) { \
179 if ((v)->flags & INMEMORY) { \
181 i386_flds_membase(REG_SP, (v)->regoff * 8); \
185 i386_fld_reg((v)->regoff + fpu_st_offset); \
187 regnr = (v)->regoff; \
190 if ((v)->flags & INMEMORY) { \
192 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
196 i386_fld_reg((v)->regoff + fpu_st_offset); \
198 regnr = (v)->regoff; \
202 #define NEW_var_to_reg_flt(regnr,v,tempnr) \
203 if ((v)->type == TYPE_FLT) { \
204 if ((v)->flags & INMEMORY) { \
206 i386_flds_membase(REG_SP, (v)->regoff * 8); \
210 regnr = (v)->regoff; \
213 if ((v)->flags & INMEMORY) { \
215 i386_fldl_membase(REG_SP, (v)->regoff * 8); \
219 regnr = (v)->regoff; \
225 This function determines a register, to which the result of an operation
226 should go, when it is ultimatively intended to store the result in
228 If v is assigned to an actual register, this register will be returned.
229 Otherwise (when v is spilled) this function returns tempregnum.
230 If not already done, regoff and flags are set in the stack location.
233 static int reg_of_var(stackptr v, int tempregnum)
237 switch (v->varkind) {
239 if (!(v->flags & INMEMORY))
243 var = &(interfaces[v->varnum][v->type]);
244 v->regoff = var->regoff;
245 if (!(var->flags & INMEMORY))
249 var = &(locals[v->varnum][v->type]);
250 v->regoff = var->regoff;
251 if (!(var->flags & INMEMORY))
255 v->regoff = v->varnum;
256 if (IS_FLT_DBL_TYPE(v->type)) {
257 if (v->varnum < fltreg_argnum) {
258 v->regoff = argfltregs[v->varnum];
259 return(argfltregs[v->varnum]);
263 if (v->varnum < intreg_argnum) {
264 v->regoff = argintregs[v->varnum];
265 return(argintregs[v->varnum]);
267 v->regoff -= intreg_argnum;
270 v->flags |= INMEMORY;
275 /* store_reg_to_var_xxx:
276 This function generates the code to store the result of an operation
277 back into a spilled pseudo-variable.
278 If the pseudo-variable has not been spilled in the first place, this
279 function will generate nothing.
281 v ............ Pseudovariable
282 tempregnum ... Number of the temporary registers as returned by
286 #define store_reg_to_var_int(sptr, tempregnum) \
287 if ((sptr)->flags & INMEMORY) { \
289 i386_mov_reg_membase(tempregnum, REG_SP, (sptr)->regoff * 8); \
293 #define store_reg_to_var_flt(sptr, tempregnum) \
294 if ((sptr)->type == TYPE_FLT) { \
295 if ((sptr)->flags & INMEMORY) { \
297 i386_fstps_membase(REG_SP, (sptr)->regoff * 8); \
300 /* i386_fxch_reg((sptr)->regoff);*/ \
301 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
305 if ((sptr)->flags & INMEMORY) { \
307 i386_fstpl_membase(REG_SP, (sptr)->regoff * 8); \
310 /* i386_fxch_reg((sptr)->regoff);*/ \
311 i386_fstp_reg((sptr)->regoff + fpu_st_offset); \
317 /* NullPointerException signal handler for hardware null pointer check */
319 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 */
417 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
418 static void *castlockptr = cast_lock;
423 int len, s1, s2, s3, d;
430 int fpu_st_offset = 0;
439 /* space to save used callee saved registers */
441 savedregs_num += (savintregcnt - maxsavintreguse);
442 savedregs_num += (savfltregcnt - maxsavfltreguse);
444 parentargs_base = maxmemuse + savedregs_num;
446 #ifdef USE_THREADS /* space to save argument of monitor_enter */
448 if (checksync && (method->flags & ACC_SYNCHRONIZED))
453 /* create method header */
455 (void) dseg_addaddress(method); /* MethodPointer */
456 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
460 /* IsSync contains the offset relative to the stack pointer for the
461 argument of monitor_exit used in the exception handler. Since the
462 offset could be zero and give a wrong meaning of the flag it is
466 if (checksync && (method->flags & ACC_SYNCHRONIZED))
467 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
472 (void) dseg_adds4(0); /* IsSync */
474 (void) dseg_adds4(isleafmethod); /* IsLeaf */
475 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
476 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
477 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
479 /* create exception table */
481 for (ex = extable; ex != NULL; ex = ex->down) {
484 if (ex->start != NULL)
485 printf("adding start - %d - ", ex->start->debug_nr);
487 printf("PANIC - start is NULL");
492 dseg_addtarget(ex->start);
496 printf("adding end - %d - ", ex->end->debug_nr);
498 printf("PANIC - end is NULL");
503 dseg_addtarget(ex->end);
506 if (ex->handler != NULL)
507 printf("adding handler - %d\n", ex->handler->debug_nr);
509 printf("PANIC - handler is NULL");
514 dseg_addtarget(ex->handler);
516 (void) dseg_addaddress(ex->catchtype);
519 /* initialize mcode variables */
521 mcodeptr = (u1*) mcodebase;
522 mcodeend = (s4*) (mcodebase + mcodesize);
523 MCODECHECK(128 + mparamcount);
525 /* create stack frame (if necessary) */
527 if (parentargs_base) {
528 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
531 /* save return address and used callee saved registers */
534 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
535 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
537 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
538 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
541 /* save monitorenter argument */
544 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
545 if (method->flags & ACC_STATIC) {
546 i386_mov_imm_reg((s4) class, REG_ITMP1);
547 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
550 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
551 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
556 /* copy argument registers to stack and call trace function with pointer
557 to arguments on stack.
561 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
563 for (p = 0; p < mparamcount; p++) {
565 if (IS_INT_LNG_TYPE(t)) {
566 if (IS_2_WORD_TYPE(t)) {
567 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
568 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
569 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
570 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
572 } else if (t == TYPE_ADR) {
573 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
574 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
575 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
576 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
579 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX);
581 i386_mov_reg_membase(EAX, REG_SP, p * 8);
582 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
587 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
588 i386_fstps_membase(REG_SP, p * 8);
589 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
590 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
593 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
594 i386_fstpl_membase(REG_SP, p * 8);
599 /* fill up the remaining arguments */
600 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
601 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
602 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
603 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
606 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
608 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
609 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
610 i386_call_reg(REG_ITMP1);
612 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
615 /* take arguments out of register or stack frame */
617 for (p = 0, l = 0; p < mparamcount; p++) {
619 var = &(locals[l][t]);
621 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
626 if (IS_INT_LNG_TYPE(t)) { /* integer args */
627 if (p < intreg_argnum) { /* register arguments */
628 panic("integer register argument");
629 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
630 /* M_INTMOVE (argintregs[p], r); */
632 } else { /* reg arg -> spilled */
633 /* M_LST (argintregs[p], REG_SP, 8 * r); */
635 } else { /* stack arguments */
636 pa = p - intreg_argnum;
637 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
638 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
639 } else { /* stack arg -> spilled */
640 if (!IS_2_WORD_TYPE(t)) {
641 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
642 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
645 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
646 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
647 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
648 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
653 } else { /* floating args */
654 if (p < fltreg_argnum) { /* register arguments */
655 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
656 panic("There are no float argument registers!");
658 } else { /* reg arg -> spilled */
659 panic("There are no float argument registers!");
662 } else { /* stack arguments */
663 pa = p - fltreg_argnum;
664 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
666 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
668 i386_fstp_reg(r + fpu_st_offset);
672 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
674 i386_fstp_reg(r + fpu_st_offset);
678 } else { /* stack-arg -> spilled */
679 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
680 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
682 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
683 i386_fstps_membase(REG_SP, r * 8);
686 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
687 i386_fstpl_membase(REG_SP, r * 8);
694 /* call monitorenter function */
697 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
698 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
699 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
700 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
701 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP2);
702 i386_call_reg(REG_ITMP2);
703 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
708 /* end of header generation */
710 /* walk through all basic blocks */
711 for (bptr = block; bptr != NULL; bptr = bptr->next) {
713 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
715 if (bptr->flags >= BBREACHED) {
717 /* branch resolving */
720 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
721 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
722 brefs->branchpos, bptr->mpc);
725 /* copy interface registers to their destination */
730 while (src != NULL) {
732 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
733 if (!IS_2_WORD_TYPE(src->type)) {
734 if (bptr->type == BBTYPE_SBR) {
735 d = reg_of_var(src, REG_ITMP1);
737 store_reg_to_var_int(src, d);
739 } else if (bptr->type == BBTYPE_EXH) {
740 d = reg_of_var(src, REG_ITMP1);
741 M_INTMOVE(REG_ITMP1, d);
742 store_reg_to_var_int(src, d);
746 panic("copy interface registers: longs have to me in memory (begin 1)");
750 d = reg_of_var(src, REG_ITMP1);
751 if ((src->varkind != STACKVAR)) {
753 if (IS_FLT_DBL_TYPE(s2)) {
754 s1 = interfaces[len][s2].regoff;
755 if (!(interfaces[len][s2].flags & INMEMORY)) {
759 if (s2 == TYPE_FLT) {
760 i386_flds_membase(REG_SP, s1 * 8);
763 i386_fldl_membase(REG_SP, s1 * 8);
766 store_reg_to_var_flt(src, d);
769 s1 = interfaces[len][s2].regoff;
770 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
771 if (!(interfaces[len][s2].flags & INMEMORY)) {
775 i386_mov_membase_reg(REG_SP, s1 * 8, d);
777 store_reg_to_var_int(src, d);
780 if (interfaces[len][s2].flags & INMEMORY) {
781 M_LNGMEMMOVE(s1, src->regoff);
784 panic("copy interface registers: longs have to be in memory (begin 2)");
793 /* walk through all instructions */
797 for (iptr = bptr->iinstr;
799 src = iptr->dst, len--, iptr++) {
801 MCODECHECK(64); /* an instruction usually needs < 64 words */
804 case ICMD_NOP: /* ... ==> ... */
807 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
808 if (src->flags & INMEMORY) {
809 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
812 i386_test_reg_reg(src->regoff, src->regoff);
814 i386_jcc(I386_CC_E, 0);
815 codegen_addxnullrefs(mcodeptr);
818 /* constant operations ************************************************/
820 case ICMD_ICONST: /* ... ==> ..., constant */
821 /* op1 = 0, val.i = constant */
823 d = reg_of_var(iptr->dst, REG_ITMP1);
824 if (iptr->dst->flags & INMEMORY) {
825 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
828 if (iptr->val.i == 0) {
829 i386_alu_reg_reg(I386_XOR, d, d);
832 i386_mov_imm_reg(iptr->val.i, d);
837 case ICMD_LCONST: /* ... ==> ..., constant */
838 /* op1 = 0, val.l = constant */
840 d = reg_of_var(iptr->dst, REG_ITMP1);
841 if (iptr->dst->flags & INMEMORY) {
842 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
843 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
846 panic("LCONST: longs have to be in memory");
850 case ICMD_FCONST: /* ... ==> ..., constant */
851 /* op1 = 0, val.f = constant */
853 d = reg_of_var(iptr->dst, REG_FTMP1);
854 if (iptr->val.f == 0.0) {
859 if (iptr->val.i == 0x80000000) {
863 } else if (iptr->val.f == 1.0) {
867 } else if (iptr->val.f == 2.0) {
874 a = dseg_addfloat(iptr->val.f);
875 i386_mov_imm_reg(0, REG_ITMP1);
876 dseg_adddata(mcodeptr);
877 i386_flds_membase(REG_ITMP1, a);
880 store_reg_to_var_flt(iptr->dst, d);
883 case ICMD_DCONST: /* ... ==> ..., constant */
884 /* op1 = 0, val.d = constant */
886 d = reg_of_var(iptr->dst, REG_FTMP1);
887 if (iptr->val.d == 0.0) {
892 if (iptr->val.l == 0x8000000000000000LL) {
896 } else if (iptr->val.d == 1.0) {
900 } else if (iptr->val.d == 2.0) {
907 a = dseg_adddouble(iptr->val.d);
908 i386_mov_imm_reg(0, REG_ITMP1);
909 dseg_adddata(mcodeptr);
910 i386_fldl_membase(REG_ITMP1, a);
913 store_reg_to_var_flt(iptr->dst, d);
916 case ICMD_ACONST: /* ... ==> ..., constant */
917 /* op1 = 0, val.a = constant */
919 d = reg_of_var(iptr->dst, REG_ITMP1);
920 if (iptr->dst->flags & INMEMORY) {
921 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
924 if ((s4) iptr->val.a == 0) {
925 i386_alu_reg_reg(I386_XOR, d, d);
928 i386_mov_imm_reg((s4) iptr->val.a, d);
934 /* load/store operations **********************************************/
936 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
937 case ICMD_ALOAD: /* op1 = local variable */
939 d = reg_of_var(iptr->dst, REG_ITMP1);
940 if ((iptr->dst->varkind == LOCALVAR) &&
941 (iptr->dst->varnum == iptr->op1)) {
944 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
945 if (iptr->dst->flags & INMEMORY) {
946 if (var->flags & INMEMORY) {
947 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
948 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
951 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
955 if (var->flags & INMEMORY) {
956 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
959 M_INTMOVE(var->regoff, iptr->dst->regoff);
964 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
965 /* op1 = local variable */
967 d = reg_of_var(iptr->dst, REG_ITMP1);
968 if ((iptr->dst->varkind == LOCALVAR) &&
969 (iptr->dst->varnum == iptr->op1)) {
972 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
973 if (iptr->dst->flags & INMEMORY) {
974 if (var->flags & INMEMORY) {
975 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
978 panic("LLOAD: longs have to be in memory");
982 panic("LLOAD: longs have to be in memory");
986 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
987 /* op1 = local variable */
989 d = reg_of_var(iptr->dst, REG_FTMP1);
990 if ((iptr->dst->varkind == LOCALVAR) &&
991 (iptr->dst->varnum == iptr->op1)) {
994 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
995 if (var->flags & INMEMORY) {
996 i386_flds_membase(REG_SP, var->regoff * 8);
999 i386_fld_reg(var->regoff + fpu_st_offset);
1002 store_reg_to_var_flt(iptr->dst, d);
1005 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
1006 /* op1 = local variable */
1008 d = reg_of_var(iptr->dst, REG_FTMP1);
1009 if ((iptr->dst->varkind == LOCALVAR) &&
1010 (iptr->dst->varnum == iptr->op1)) {
1013 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
1014 if (var->flags & INMEMORY) {
1015 i386_fldl_membase(REG_SP, var->regoff * 8);
1018 i386_fld_reg(var->regoff + fpu_st_offset);
1021 store_reg_to_var_flt(iptr->dst, d);
1024 case ICMD_ISTORE: /* ..., value ==> ... */
1025 case ICMD_ASTORE: /* op1 = local variable */
1027 if ((src->varkind == LOCALVAR) &&
1028 (src->varnum == iptr->op1)) {
1031 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1032 if (var->flags & INMEMORY) {
1033 if (src->flags & INMEMORY) {
1034 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1035 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
1038 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
1042 var_to_reg_int(s1, src, var->regoff);
1043 M_INTMOVE(s1, var->regoff);
1047 case ICMD_LSTORE: /* ..., value ==> ... */
1048 /* op1 = local variable */
1050 if ((src->varkind == LOCALVAR) &&
1051 (src->varnum == iptr->op1)) {
1054 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1055 if (var->flags & INMEMORY) {
1056 if (src->flags & INMEMORY) {
1057 M_LNGMEMMOVE(src->regoff, var->regoff);
1060 panic("LSTORE: longs have to be in memory");
1064 panic("LSTORE: longs have to be in memory");
1068 case ICMD_FSTORE: /* ..., value ==> ... */
1069 /* op1 = local variable */
1071 if ((src->varkind == LOCALVAR) &&
1072 (src->varnum == iptr->op1)) {
1075 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1076 if (var->flags & INMEMORY) {
1077 var_to_reg_flt(s1, src, REG_FTMP1);
1078 i386_fstps_membase(REG_SP, var->regoff * 8);
1081 var_to_reg_flt(s1, src, var->regoff);
1082 /* M_FLTMOVE(s1, var->regoff); */
1083 i386_fstp_reg(var->regoff + fpu_st_offset);
1088 case ICMD_DSTORE: /* ..., value ==> ... */
1089 /* op1 = local variable */
1091 if ((src->varkind == LOCALVAR) &&
1092 (src->varnum == iptr->op1)) {
1095 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1096 if (var->flags & INMEMORY) {
1097 var_to_reg_flt(s1, src, REG_FTMP1);
1098 i386_fstpl_membase(REG_SP, var->regoff * 8);
1101 var_to_reg_flt(s1, src, var->regoff);
1102 /* M_FLTMOVE(s1, var->regoff); */
1103 i386_fstp_reg(var->regoff + fpu_st_offset);
1109 /* pop/dup/swap operations ********************************************/
1111 /* attention: double and longs are only one entry in CACAO ICMDs */
1113 case ICMD_POP: /* ..., value ==> ... */
1114 case ICMD_POP2: /* ..., value, value ==> ... */
1117 #define M_COPY(from,to) \
1118 d = reg_of_var(to, REG_ITMP1); \
1119 if ((from->regoff != to->regoff) || \
1120 ((from->flags ^ to->flags) & INMEMORY)) { \
1121 if (IS_FLT_DBL_TYPE(from->type)) { \
1122 var_to_reg_flt(s1, from, d); \
1123 /* M_FLTMOVE(s1, d);*/ \
1124 store_reg_to_var_flt(to, d); \
1126 if (!IS_2_WORD_TYPE(from->type)) { \
1127 if (to->flags & INMEMORY) { \
1128 if (from->flags & INMEMORY) { \
1129 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1130 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1132 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1135 if (from->flags & INMEMORY) { \
1136 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1138 i386_mov_reg_reg(from->regoff, to->regoff); \
1142 M_LNGMEMMOVE(from->regoff, to->regoff); \
1147 case ICMD_DUP: /* ..., a ==> ..., a, a */
1148 M_COPY(src, iptr->dst);
1151 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1153 M_COPY(src, iptr->dst->prev->prev);
1155 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1157 M_COPY(src, iptr->dst);
1158 M_COPY(src->prev, iptr->dst->prev);
1161 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1163 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1165 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1167 M_COPY(src, iptr->dst);
1168 M_COPY(src->prev, iptr->dst->prev);
1169 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1170 M_COPY(src, iptr->dst->prev->prev->prev);
1173 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1175 M_COPY(src, iptr->dst);
1176 M_COPY(src->prev, iptr->dst->prev);
1177 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1178 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1179 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1180 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1183 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1185 M_COPY(src, iptr->dst->prev);
1186 M_COPY(src->prev, iptr->dst);
1190 /* integer operations *************************************************/
1192 case ICMD_INEG: /* ..., value ==> ..., - value */
1194 d = reg_of_var(iptr->dst, REG_NULL);
1195 if (iptr->dst->flags & INMEMORY) {
1196 if (src->flags & INMEMORY) {
1197 if (src->regoff == iptr->dst->regoff) {
1198 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1201 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1202 i386_neg_reg(REG_ITMP1);
1203 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1207 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1208 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1212 if (src->flags & INMEMORY) {
1213 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1214 i386_neg_reg(iptr->dst->regoff);
1217 M_INTMOVE(src->regoff, iptr->dst->regoff);
1218 i386_neg_reg(iptr->dst->regoff);
1223 case ICMD_LNEG: /* ..., value ==> ..., - value */
1225 d = reg_of_var(iptr->dst, REG_NULL);
1226 if (iptr->dst->flags & INMEMORY) {
1227 if (src->flags & INMEMORY) {
1228 if (src->regoff == iptr->dst->regoff) {
1229 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1230 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1231 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1234 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1235 i386_neg_reg(REG_ITMP1);
1236 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1237 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1238 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP1);
1239 i386_neg_reg(REG_ITMP1);
1240 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1246 case ICMD_I2L: /* ..., value ==> ..., value */
1248 d = reg_of_var(iptr->dst, REG_NULL);
1249 if (iptr->dst->flags & INMEMORY) {
1250 if (src->flags & INMEMORY) {
1251 i386_mov_membase_reg(REG_SP, src->regoff * 8, EAX);
1253 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1254 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1257 M_INTMOVE(src->regoff, EAX);
1259 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1260 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1265 case ICMD_L2I: /* ..., value ==> ..., value */
1267 d = reg_of_var(iptr->dst, REG_NULL);
1268 if (iptr->dst->flags & INMEMORY) {
1269 if (src->flags & INMEMORY) {
1270 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1271 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1275 if (src->flags & INMEMORY) {
1276 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1281 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1283 d = reg_of_var(iptr->dst, REG_NULL);
1284 if (iptr->dst->flags & INMEMORY) {
1285 if (src->flags & INMEMORY) {
1286 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1287 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1288 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1289 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1292 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1293 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1294 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1298 if (src->flags & INMEMORY) {
1299 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1300 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1301 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1304 M_INTMOVE(src->regoff, iptr->dst->regoff);
1305 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1306 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1311 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1313 d = reg_of_var(iptr->dst, REG_NULL);
1314 if (iptr->dst->flags & INMEMORY) {
1315 if (src->flags & INMEMORY) {
1316 if (src->regoff == iptr->dst->regoff) {
1317 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1320 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1321 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1322 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1326 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1327 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1331 if (src->flags & INMEMORY) {
1332 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1333 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1336 M_INTMOVE(src->regoff, iptr->dst->regoff);
1337 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1342 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1344 d = reg_of_var(iptr->dst, REG_NULL);
1345 if (iptr->dst->flags & INMEMORY) {
1346 if (src->flags & INMEMORY) {
1347 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1348 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1349 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1350 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1353 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1354 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1355 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1359 if (src->flags & INMEMORY) {
1360 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1361 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1362 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1365 M_INTMOVE(src->regoff, iptr->dst->regoff);
1366 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1367 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1373 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1375 d = reg_of_var(iptr->dst, REG_NULL);
1376 i386_emit_ialu(I386_ADD, src, iptr);
1379 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1380 /* val.i = constant */
1382 d = reg_of_var(iptr->dst, REG_NULL);
1383 /* should we use a inc optimization for smaller code size? */
1384 i386_emit_ialuconst(I386_ADD, src, iptr);
1387 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1389 d = reg_of_var(iptr->dst, REG_NULL);
1390 if (iptr->dst->flags & INMEMORY) {
1391 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1392 if (src->regoff == iptr->dst->regoff) {
1393 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1394 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1395 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1396 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1398 } else if (src->prev->regoff == iptr->dst->regoff) {
1399 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1400 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1401 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1402 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1405 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1406 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1407 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1408 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1409 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1410 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1417 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1418 /* val.l = constant */
1420 d = reg_of_var(iptr->dst, REG_NULL);
1421 if (iptr->dst->flags & INMEMORY) {
1422 if (src->flags & INMEMORY) {
1423 if (src->regoff == iptr->dst->regoff) {
1424 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1425 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1428 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1429 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1430 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1431 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1432 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1433 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1439 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1441 d = reg_of_var(iptr->dst, REG_NULL);
1442 if (iptr->dst->flags & INMEMORY) {
1443 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1444 if (src->prev->regoff == iptr->dst->regoff) {
1445 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1446 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1449 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1450 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1451 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1454 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1455 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1456 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1457 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1459 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1460 if (src->prev->regoff == iptr->dst->regoff) {
1461 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1464 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1465 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1466 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1470 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1471 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1475 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1476 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, 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 M_INTMOVE(src->prev->regoff, d);
1481 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1483 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1484 /* workaround for reg alloc */
1485 if (src->regoff == iptr->dst->regoff) {
1486 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1487 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1488 M_INTMOVE(REG_ITMP1, d);
1491 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1492 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1496 /* workaround for reg alloc */
1497 if (src->regoff == iptr->dst->regoff) {
1498 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1499 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1500 M_INTMOVE(REG_ITMP1, d);
1503 M_INTMOVE(src->prev->regoff, d);
1504 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1510 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1511 /* val.i = constant */
1513 d = reg_of_var(iptr->dst, REG_NULL);
1514 i386_emit_ialuconst(I386_SUB, src, iptr);
1517 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1519 d = reg_of_var(iptr->dst, REG_NULL);
1520 if (iptr->dst->flags & INMEMORY) {
1521 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1522 if (src->prev->regoff == iptr->dst->regoff) {
1523 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1524 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1525 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1526 i386_alu_reg_membase(I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1529 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1530 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1531 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1532 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1533 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1534 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1540 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1541 /* val.l = constant */
1543 d = reg_of_var(iptr->dst, REG_NULL);
1544 if (iptr->dst->flags & INMEMORY) {
1545 if (src->flags & INMEMORY) {
1546 if (src->regoff == iptr->dst->regoff) {
1547 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1548 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1551 /* TODO: could be size optimized with lea -- see gcc output */
1552 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1553 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1554 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1555 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1556 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1557 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1563 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1565 d = reg_of_var(iptr->dst, REG_NULL);
1566 if (iptr->dst->flags & INMEMORY) {
1567 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1568 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1569 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1570 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1572 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1573 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1574 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1575 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1577 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1578 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1579 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1580 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1583 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1584 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1585 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1589 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1590 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, 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->prev->regoff, iptr->dst->regoff);
1595 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1597 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1598 M_INTMOVE(src->regoff, iptr->dst->regoff);
1599 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1602 if (src->regoff == iptr->dst->regoff) {
1603 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1606 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1607 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1613 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1614 /* val.i = constant */
1616 d = reg_of_var(iptr->dst, REG_NULL);
1617 if (iptr->dst->flags & INMEMORY) {
1618 if (src->flags & INMEMORY) {
1619 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1620 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1623 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1624 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1628 if (src->flags & INMEMORY) {
1629 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1632 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1637 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1639 d = reg_of_var(iptr->dst, REG_NULL);
1640 if (iptr->dst->flags & INMEMORY) {
1641 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1642 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX); /* mem -> EAX */
1643 /* optimize move EAX -> REG_ITMP3 is slower??? */
1644 /* i386_mov_reg_reg(EAX, REG_ITMP3); */
1645 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1647 /* TODO: optimize move EAX -> REG_ITMP3 */
1648 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem -> ITMP3 */
1649 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1650 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1652 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP2); /* mem -> ITMP3 */
1653 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1655 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1656 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1657 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1662 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1663 /* val.l = constant */
1665 d = reg_of_var(iptr->dst, REG_NULL);
1666 if (iptr->dst->flags & INMEMORY) {
1667 if (src->flags & INMEMORY) {
1668 i386_mov_imm_reg(iptr->val.l, EAX); /* imm -> EAX */
1669 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1670 /* TODO: optimize move EAX -> REG_ITMP3 */
1671 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2); /* imm -> ITMP3 */
1672 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1674 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1675 i386_mov_imm_reg(iptr->val.l, REG_ITMP2); /* imm -> ITMP3 */
1676 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1678 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1679 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1680 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1685 #define gen_div_check(v) \
1687 if ((v)->flags & INMEMORY) { \
1688 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1690 i386_test_reg_reg(src->regoff, src->regoff); \
1692 i386_jcc(I386_CC_E, 0); \
1693 codegen_addxdivrefs(mcodeptr); \
1696 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1698 d = reg_of_var(iptr->dst, REG_NULL);
1699 var_to_reg_int(s1, src, REG_ITMP2);
1701 if (src->prev->flags & INMEMORY) {
1702 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1705 M_INTMOVE(src->prev->regoff, EAX);
1708 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1709 i386_jcc(I386_CC_NE, 3 + 6);
1710 i386_alu_imm_reg(I386_CMP, -1, s1);
1711 i386_jcc(I386_CC_E, 1 + 2);
1716 if (iptr->dst->flags & INMEMORY) {
1717 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1720 M_INTMOVE(EAX, iptr->dst->regoff);
1724 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1726 d = reg_of_var(iptr->dst, REG_NULL);
1727 var_to_reg_int(s1, src, REG_ITMP2);
1729 if (src->prev->flags & INMEMORY) {
1730 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1733 M_INTMOVE(src->prev->regoff, EAX);
1736 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1737 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1738 i386_alu_reg_reg(I386_XOR, EDX, EDX);
1739 i386_alu_imm_reg(I386_CMP, -1, s1);
1740 i386_jcc(I386_CC_E, 1 + 2);
1745 if (iptr->dst->flags & INMEMORY) {
1746 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8);
1749 M_INTMOVE(EDX, iptr->dst->regoff);
1753 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1754 /* val.i = constant */
1756 /* TODO: optimize for `/ 2' */
1757 var_to_reg_int(s1, src, REG_ITMP1);
1758 d = reg_of_var(iptr->dst, REG_ITMP1);
1761 i386_test_reg_reg(d, d);
1763 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1764 i386_jcc(I386_CC_NS, a);
1765 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1767 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1768 store_reg_to_var_int(iptr->dst, d);
1771 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1772 /* val.i = constant */
1774 d = reg_of_var(iptr->dst, REG_NULL);
1775 if (iptr->dst->flags & INMEMORY) {
1776 if (src->flags & INMEMORY) {
1778 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1780 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1781 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1783 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1784 i386_jcc(I386_CC_NS, a);
1785 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1786 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1787 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1788 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1790 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1791 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1796 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1797 /* val.i = constant */
1799 var_to_reg_int(s1, src, REG_ITMP1);
1800 d = reg_of_var(iptr->dst, REG_ITMP2);
1802 M_INTMOVE(s1, REG_ITMP1);
1809 CALCIMMEDIATEBYTES(a, iptr->val.i);
1812 /* TODO: optimize */
1814 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1815 i386_test_reg_reg(s1, s1);
1816 i386_jcc(I386_CC_GE, a);
1817 i386_mov_reg_reg(s1, d);
1819 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1822 /* M_INTMOVE(s1, EAX); */
1824 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1825 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1826 /* i386_alu_reg_reg(I386_AND, iptr->val.i, EAX); */
1827 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1828 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1829 /* M_INTMOVE(EAX, d); */
1831 /* i386_alu_reg_reg(I386_XOR, d, d); */
1832 /* i386_mov_imm_reg(iptr->val.i, ECX); */
1833 /* i386_shrd_reg_reg(s1, d); */
1834 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1836 store_reg_to_var_int(iptr->dst, d);
1839 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1840 /* val.l = constant */
1842 d = reg_of_var(iptr->dst, REG_NULL);
1843 if (iptr->dst->flags & INMEMORY) {
1844 if (src->flags & INMEMORY) {
1845 /* Intel algorithm -- does not work, because constant is wrong */
1846 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1847 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1849 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1850 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1851 /* i386_jcc(I386_CC_NS, offset); */
1852 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1853 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1855 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1856 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1857 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1859 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1861 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1862 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1863 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1865 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1866 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1868 /* Alpha algorithm */
1870 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1872 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1878 /* TODO: hmm, don't know if this is always correct */
1880 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1882 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1888 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1889 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1891 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1892 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1893 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1894 i386_jcc(I386_CC_GE, a);
1896 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1897 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1899 i386_neg_reg(REG_ITMP1);
1900 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1901 i386_neg_reg(REG_ITMP2);
1903 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1904 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1906 i386_neg_reg(REG_ITMP1);
1907 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1908 i386_neg_reg(REG_ITMP2);
1910 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1911 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1916 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1918 d = reg_of_var(iptr->dst, REG_NULL);
1919 i386_emit_ishift(I386_SHL, src, iptr);
1922 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1923 /* val.i = constant */
1925 d = reg_of_var(iptr->dst, REG_NULL);
1926 i386_emit_ishiftconst(I386_SHL, src, iptr);
1929 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1931 d = reg_of_var(iptr->dst, REG_NULL);
1932 i386_emit_ishift(I386_SAR, src, iptr);
1935 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1936 /* val.i = constant */
1938 d = reg_of_var(iptr->dst, REG_NULL);
1939 i386_emit_ishiftconst(I386_SAR, src, iptr);
1942 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1944 d = reg_of_var(iptr->dst, REG_NULL);
1945 i386_emit_ishift(I386_SHR, src, iptr);
1948 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1949 /* val.i = constant */
1951 d = reg_of_var(iptr->dst, REG_NULL);
1952 i386_emit_ishiftconst(I386_SHR, src, iptr);
1955 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1957 d = reg_of_var(iptr->dst, REG_NULL);
1958 if (iptr->dst->flags & INMEMORY ){
1959 if (src->prev->flags & INMEMORY) {
1960 /* if (src->prev->regoff == iptr->dst->regoff) { */
1961 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1963 /* if (src->flags & INMEMORY) { */
1964 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
1966 /* M_INTMOVE(src->regoff, ECX); */
1969 /* i386_test_imm_reg(32, ECX); */
1970 /* i386_jcc(I386_CC_E, 2 + 2); */
1971 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1972 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1974 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1975 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1978 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1979 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1981 if (src->flags & INMEMORY) {
1982 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
1984 M_INTMOVE(src->regoff, ECX);
1987 i386_test_imm_reg(32, ECX);
1988 i386_jcc(I386_CC_E, 2 + 2);
1989 i386_mov_reg_reg(REG_ITMP1, REG_ITMP3);
1990 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1992 i386_shld_reg_reg(REG_ITMP1, REG_ITMP3);
1993 i386_shift_reg(I386_SHL, REG_ITMP1);
1994 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1995 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2001 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
2002 /* val.i = constant */
2004 d = reg_of_var(iptr->dst, REG_NULL);
2005 if (iptr->dst->flags & INMEMORY ) {
2006 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2007 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2009 if (iptr->val.i & 0x20) {
2010 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2011 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2012 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2015 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2016 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2019 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2020 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2024 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2026 d = reg_of_var(iptr->dst, REG_NULL);
2027 if (iptr->dst->flags & INMEMORY ){
2028 if (src->prev->flags & INMEMORY) {
2029 /* if (src->prev->regoff == iptr->dst->regoff) { */
2030 /* TODO: optimize */
2031 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2032 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2034 /* if (src->flags & INMEMORY) { */
2035 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2037 /* M_INTMOVE(src->regoff, ECX); */
2040 /* i386_test_imm_reg(32, ECX); */
2041 /* i386_jcc(I386_CC_E, 2 + 3); */
2042 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2043 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2045 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2046 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2047 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2048 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2051 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2052 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2054 if (src->flags & INMEMORY) {
2055 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2057 M_INTMOVE(src->regoff, ECX);
2060 i386_test_imm_reg(32, ECX);
2061 i386_jcc(I386_CC_E, 2 + 3);
2062 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2063 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP3);
2065 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2066 i386_shift_reg(I386_SAR, REG_ITMP3);
2067 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2068 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2074 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2075 /* val.i = constant */
2077 d = reg_of_var(iptr->dst, REG_NULL);
2078 if (iptr->dst->flags & INMEMORY ) {
2079 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2080 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2082 if (iptr->val.i & 0x20) {
2083 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2084 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2085 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2088 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2089 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2092 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2093 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2097 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2099 d = reg_of_var(iptr->dst, REG_NULL);
2100 if (iptr->dst->flags & INMEMORY ){
2101 if (src->prev->flags & INMEMORY) {
2102 /* if (src->prev->regoff == iptr->dst->regoff) { */
2103 /* TODO: optimize */
2104 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2105 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2107 /* if (src->flags & INMEMORY) { */
2108 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2110 /* M_INTMOVE(src->regoff, ECX); */
2113 /* i386_test_imm_reg(32, ECX); */
2114 /* i386_jcc(I386_CC_E, 2 + 2); */
2115 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2116 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2118 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2119 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2120 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2121 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2124 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2125 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2127 if (src->flags & INMEMORY) {
2128 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2130 M_INTMOVE(src->regoff, ECX);
2133 i386_test_imm_reg(32, ECX);
2134 i386_jcc(I386_CC_E, 2 + 2);
2135 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2136 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2138 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2139 i386_shift_reg(I386_SHR, REG_ITMP3);
2140 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2141 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2147 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2148 /* val.l = constant */
2150 d = reg_of_var(iptr->dst, REG_NULL);
2151 if (iptr->dst->flags & INMEMORY ) {
2152 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2153 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2155 if (iptr->val.i & 0x20) {
2156 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2157 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2158 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2161 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2162 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2165 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2166 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2170 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2172 d = reg_of_var(iptr->dst, REG_NULL);
2173 i386_emit_ialu(I386_AND, src, iptr);
2176 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2177 /* val.i = constant */
2179 d = reg_of_var(iptr->dst, REG_NULL);
2180 i386_emit_ialuconst(I386_AND, src, iptr);
2183 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2185 d = reg_of_var(iptr->dst, REG_NULL);
2186 i386_emit_lalu(I386_AND, src, iptr);
2189 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2190 /* val.l = constant */
2192 d = reg_of_var(iptr->dst, REG_NULL);
2193 i386_emit_laluconst(I386_AND, src, iptr);
2196 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2198 d = reg_of_var(iptr->dst, REG_NULL);
2199 i386_emit_ialu(I386_OR, src, iptr);
2202 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2203 /* val.i = constant */
2205 d = reg_of_var(iptr->dst, REG_NULL);
2206 i386_emit_ialuconst(I386_OR, src, iptr);
2209 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2211 d = reg_of_var(iptr->dst, REG_NULL);
2212 i386_emit_lalu(I386_OR, src, iptr);
2215 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2216 /* val.l = constant */
2218 d = reg_of_var(iptr->dst, REG_NULL);
2219 i386_emit_laluconst(I386_OR, src, iptr);
2222 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2224 d = reg_of_var(iptr->dst, REG_NULL);
2225 i386_emit_ialu(I386_XOR, src, iptr);
2228 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2229 /* val.i = constant */
2231 d = reg_of_var(iptr->dst, REG_NULL);
2232 i386_emit_ialuconst(I386_XOR, src, iptr);
2235 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2237 d = reg_of_var(iptr->dst, REG_NULL);
2238 i386_emit_lalu(I386_XOR, src, iptr);
2241 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2242 /* val.l = constant */
2244 d = reg_of_var(iptr->dst, REG_NULL);
2245 i386_emit_laluconst(I386_XOR, src, iptr);
2248 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2249 /* op1 = variable, val.i = constant */
2251 var = &(locals[iptr->op1][TYPE_INT]);
2252 if (var->flags & INMEMORY) {
2253 if (iptr->val.i == 1) {
2254 i386_inc_membase(REG_SP, var->regoff * 8);
2256 } else if (iptr->val.i == -1) {
2257 i386_dec_membase(REG_SP, var->regoff * 8);
2260 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2264 if (iptr->val.i == 1) {
2265 i386_inc_reg(var->regoff);
2267 } else if (iptr->val.i == -1) {
2268 i386_dec_reg(var->regoff);
2271 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2277 /* floating operations ************************************************/
2279 #define ROUND_TO_SINGLE \
2280 i386_fstps_membase(REG_SP, -8); \
2281 i386_flds_membase(REG_SP, -8);
2283 #define ROUND_TO_DOUBLE \
2284 i386_fstpl_membase(REG_SP, -8); \
2285 i386_fldl_membase(REG_SP, -8);
2287 #define FPU_SET_24BIT_MODE \
2288 if (!fpu_in_24bit_mode) { \
2289 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2290 fpu_in_24bit_mode = 1; \
2293 #define FPU_SET_53BIT_MODE \
2294 if (fpu_in_24bit_mode) { \
2295 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2296 fpu_in_24bit_mode = 0; \
2299 #define ROUND_TO_SINGLE
2300 #define ROUND_TO_DOUBLE
2301 #define FPU_SET_24BIT_MODE
2302 #define FPU_SET_53BIT_MODE
2304 case ICMD_FNEG: /* ..., value ==> ..., - value */
2307 var_to_reg_flt(s1, src, REG_FTMP1);
2308 d = reg_of_var(iptr->dst, REG_FTMP3);
2310 store_reg_to_var_flt(iptr->dst, d);
2313 case ICMD_DNEG: /* ..., value ==> ..., - value */
2316 var_to_reg_flt(s1, src, REG_FTMP1);
2317 d = reg_of_var(iptr->dst, REG_FTMP3);
2319 store_reg_to_var_flt(iptr->dst, d);
2322 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2325 d = reg_of_var(iptr->dst, REG_FTMP3);
2326 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2327 var_to_reg_flt(s2, src, REG_FTMP2);
2330 store_reg_to_var_flt(iptr->dst, d);
2333 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2336 d = reg_of_var(iptr->dst, REG_FTMP3);
2337 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2338 var_to_reg_flt(s2, src, REG_FTMP2);
2341 store_reg_to_var_flt(iptr->dst, d);
2344 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2347 d = reg_of_var(iptr->dst, REG_FTMP3);
2348 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2349 var_to_reg_flt(s2, src, REG_FTMP2);
2352 store_reg_to_var_flt(iptr->dst, d);
2355 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2358 d = reg_of_var(iptr->dst, REG_FTMP3);
2359 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2360 var_to_reg_flt(s2, src, REG_FTMP2);
2363 store_reg_to_var_flt(iptr->dst, d);
2366 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2369 d = reg_of_var(iptr->dst, REG_FTMP3);
2370 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2371 var_to_reg_flt(s2, src, REG_FTMP2);
2375 store_reg_to_var_flt(iptr->dst, d);
2378 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2381 d = reg_of_var(iptr->dst, REG_FTMP3);
2382 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2384 /* i386_fldt_mem(subnormal_bias1); */
2387 var_to_reg_flt(s2, src, REG_FTMP2);
2392 /* i386_fldt_mem(subnormal_bias2); */
2395 store_reg_to_var_flt(iptr->dst, d);
2398 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2401 d = reg_of_var(iptr->dst, REG_FTMP3);
2402 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2403 var_to_reg_flt(s2, src, REG_FTMP2);
2407 store_reg_to_var_flt(iptr->dst, d);
2410 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2413 d = reg_of_var(iptr->dst, REG_FTMP3);
2414 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2416 /* i386_fldt_mem(subnormal_bias1); */
2419 var_to_reg_flt(s2, src, REG_FTMP2);
2424 /* i386_fldt_mem(subnormal_bias2); */
2427 store_reg_to_var_flt(iptr->dst, d);
2430 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2433 /* exchanged to skip fxch */
2434 var_to_reg_flt(s2, src, REG_FTMP2);
2435 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2436 d = reg_of_var(iptr->dst, REG_FTMP3);
2442 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2443 store_reg_to_var_flt(iptr->dst, d);
2449 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2452 /* exchanged to skip fxch */
2453 var_to_reg_flt(s2, src, REG_FTMP2);
2454 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2455 d = reg_of_var(iptr->dst, REG_FTMP3);
2461 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2462 store_reg_to_var_flt(iptr->dst, d);
2468 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2469 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2471 d = reg_of_var(iptr->dst, REG_FTMP1);
2472 if (src->flags & INMEMORY) {
2473 i386_fildl_membase(REG_SP, src->regoff * 8);
2478 i386_mov_imm_reg(0, REG_ITMP1);
2479 dseg_adddata(mcodeptr);
2480 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2481 i386_fildl_membase(REG_ITMP1, a);
2484 store_reg_to_var_flt(iptr->dst, d);
2487 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2488 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2490 d = reg_of_var(iptr->dst, REG_FTMP1);
2491 if (src->flags & INMEMORY) {
2492 i386_fildll_membase(REG_SP, src->regoff * 8);
2496 panic("L2F: longs have to be in memory");
2498 store_reg_to_var_flt(iptr->dst, d);
2501 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2503 var_to_reg_flt(s1, src, REG_FTMP1);
2504 d = reg_of_var(iptr->dst, REG_NULL);
2506 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2507 i386_mov_imm_reg(0, REG_ITMP1);
2508 dseg_adddata(mcodeptr);
2509 i386_fldcw_membase(REG_ITMP1, a);
2511 if (iptr->dst->flags & INMEMORY) {
2512 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2515 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2516 i386_fldcw_membase(REG_ITMP1, a);
2518 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2521 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2523 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2527 i386_fistpl_membase(REG_ITMP1, a);
2529 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2531 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2532 i386_fldcw_membase(REG_ITMP1, a);
2534 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2537 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2538 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2541 i386_jcc(I386_CC_NE, a);
2543 /* XXX: change this when we use registers */
2544 i386_flds_membase(REG_SP, src->regoff * 8);
2545 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP1);
2546 i386_call_reg(REG_ITMP1);
2548 if (iptr->dst->flags & INMEMORY) {
2549 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2552 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2556 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2558 var_to_reg_flt(s1, src, REG_FTMP1);
2559 d = reg_of_var(iptr->dst, REG_NULL);
2561 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2562 i386_mov_imm_reg(0, REG_ITMP1);
2563 dseg_adddata(mcodeptr);
2564 i386_fldcw_membase(REG_ITMP1, a);
2566 if (iptr->dst->flags & INMEMORY) {
2567 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2570 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2571 i386_fldcw_membase(REG_ITMP1, a);
2573 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2576 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2578 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2582 i386_fistpl_membase(REG_ITMP1, a);
2584 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2586 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2587 i386_fldcw_membase(REG_ITMP1, a);
2589 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2592 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2593 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2596 i386_jcc(I386_CC_NE, a);
2598 /* XXX: change this when we use registers */
2599 i386_fldl_membase(REG_SP, src->regoff * 8);
2600 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP1);
2601 i386_call_reg(REG_ITMP1);
2603 if (iptr->dst->flags & INMEMORY) {
2604 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2606 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2610 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2612 var_to_reg_flt(s1, src, REG_FTMP1);
2613 d = reg_of_var(iptr->dst, REG_NULL);
2615 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2616 i386_mov_imm_reg(0, REG_ITMP1);
2617 dseg_adddata(mcodeptr);
2618 i386_fldcw_membase(REG_ITMP1, a);
2620 if (iptr->dst->flags & INMEMORY) {
2621 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2624 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2625 i386_fldcw_membase(REG_ITMP1, a);
2627 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2630 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2632 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2635 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2637 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2639 i386_jcc(I386_CC_NE, a);
2641 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2644 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2646 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2648 i386_jcc(I386_CC_NE, a);
2650 /* XXX: change this when we use registers */
2651 i386_flds_membase(REG_SP, src->regoff * 8);
2652 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP1);
2653 i386_call_reg(REG_ITMP1);
2654 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2655 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2658 panic("F2L: longs have to be in memory");
2662 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2664 var_to_reg_flt(s1, src, REG_FTMP1);
2665 d = reg_of_var(iptr->dst, REG_NULL);
2667 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2668 i386_mov_imm_reg(0, REG_ITMP1);
2669 dseg_adddata(mcodeptr);
2670 i386_fldcw_membase(REG_ITMP1, a);
2672 if (iptr->dst->flags & INMEMORY) {
2673 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2676 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2677 i386_fldcw_membase(REG_ITMP1, a);
2679 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2682 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2684 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2687 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2689 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2691 i386_jcc(I386_CC_NE, a);
2693 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2696 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2698 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2700 i386_jcc(I386_CC_NE, a);
2702 /* XXX: change this when we use registers */
2703 i386_fldl_membase(REG_SP, src->regoff * 8);
2704 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP1);
2705 i386_call_reg(REG_ITMP1);
2706 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2707 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2710 panic("D2L: longs have to be in memory");
2714 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2716 var_to_reg_flt(s1, src, REG_FTMP1);
2717 d = reg_of_var(iptr->dst, REG_FTMP3);
2719 store_reg_to_var_flt(iptr->dst, d);
2722 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2724 var_to_reg_flt(s1, src, REG_FTMP1);
2725 d = reg_of_var(iptr->dst, REG_FTMP3);
2727 store_reg_to_var_flt(iptr->dst, d);
2730 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2733 /* exchanged to skip fxch */
2734 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2735 var_to_reg_flt(s1, src, REG_FTMP2);
2736 d = reg_of_var(iptr->dst, REG_ITMP1);
2741 i386_test_imm_reg(0x400, EAX); /* unordered treat as GT */
2742 i386_jcc(I386_CC_E, 6);
2743 i386_alu_imm_reg(I386_AND, 0x000000ff, EAX);
2745 i386_mov_imm_reg(0, d); /* does not affect flags */
2746 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2747 i386_jcc(I386_CC_B, 1 + 5);
2751 store_reg_to_var_int(iptr->dst, d);
2754 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2757 /* exchanged to skip fxch */
2758 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2759 var_to_reg_flt(s1, src, REG_FTMP2);
2760 d = reg_of_var(iptr->dst, REG_ITMP1);
2765 i386_test_imm_reg(0x400, EAX); /* unordered treat as LT */
2766 i386_jcc(I386_CC_E, 3);
2767 i386_movb_imm_reg(1, I386_AH);
2769 i386_mov_imm_reg(0, d); /* does not affect flags */
2770 i386_jcc(I386_CC_E, 6 + 1 + 5 + 1);
2771 i386_jcc(I386_CC_B, 1 + 5);
2775 store_reg_to_var_int(iptr->dst, d);
2779 /* memory operations **************************************************/
2781 #define gen_bound_check \
2782 if (checkbounds) { \
2783 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2784 i386_jcc(I386_CC_AE, 0); \
2785 codegen_addxboundrefs(mcodeptr); \
2788 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2790 var_to_reg_int(s1, src, REG_ITMP1);
2791 d = reg_of_var(iptr->dst, REG_ITMP1);
2792 gen_nullptr_check(s1);
2793 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2794 store_reg_to_var_int(iptr->dst, d);
2797 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2799 var_to_reg_int(s1, src->prev, REG_ITMP1);
2800 var_to_reg_int(s2, src, REG_ITMP2);
2801 d = reg_of_var(iptr->dst, REG_ITMP1);
2802 if (iptr->op1 == 0) {
2803 gen_nullptr_check(s1);
2806 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2807 store_reg_to_var_int(iptr->dst, d);
2810 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2812 var_to_reg_int(s1, src->prev, REG_ITMP1);
2813 var_to_reg_int(s2, src, REG_ITMP2);
2814 d = reg_of_var(iptr->dst, REG_ITMP3);
2815 if (iptr->op1 == 0) {
2816 gen_nullptr_check(s1);
2820 if (iptr->dst->flags & INMEMORY) {
2821 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2822 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2823 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2824 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2828 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2830 var_to_reg_int(s1, src->prev, REG_ITMP1);
2831 var_to_reg_int(s2, src, REG_ITMP2);
2832 d = reg_of_var(iptr->dst, REG_ITMP1);
2833 if (iptr->op1 == 0) {
2834 gen_nullptr_check(s1);
2837 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2838 store_reg_to_var_int(iptr->dst, d);
2841 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2843 var_to_reg_int(s1, src->prev, REG_ITMP1);
2844 var_to_reg_int(s2, src, REG_ITMP2);
2845 d = reg_of_var(iptr->dst, REG_FTMP1);
2846 if (iptr->op1 == 0) {
2847 gen_nullptr_check(s1);
2850 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2852 store_reg_to_var_flt(iptr->dst, d);
2855 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2857 var_to_reg_int(s1, src->prev, REG_ITMP1);
2858 var_to_reg_int(s2, src, REG_ITMP2);
2859 d = reg_of_var(iptr->dst, REG_FTMP3);
2860 if (iptr->op1 == 0) {
2861 gen_nullptr_check(s1);
2864 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2866 store_reg_to_var_flt(iptr->dst, d);
2869 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2871 var_to_reg_int(s1, src->prev, REG_ITMP1);
2872 var_to_reg_int(s2, src, REG_ITMP2);
2873 d = reg_of_var(iptr->dst, REG_ITMP1);
2874 if (iptr->op1 == 0) {
2875 gen_nullptr_check(s1);
2878 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2879 store_reg_to_var_int(iptr->dst, d);
2882 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2884 var_to_reg_int(s1, src->prev, REG_ITMP1);
2885 var_to_reg_int(s2, src, REG_ITMP2);
2886 d = reg_of_var(iptr->dst, REG_ITMP1);
2887 if (iptr->op1 == 0) {
2888 gen_nullptr_check(s1);
2891 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2892 store_reg_to_var_int(iptr->dst, d);
2895 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2897 var_to_reg_int(s1, src->prev, REG_ITMP1);
2898 var_to_reg_int(s2, src, REG_ITMP2);
2899 d = reg_of_var(iptr->dst, REG_ITMP1);
2900 if (iptr->op1 == 0) {
2901 gen_nullptr_check(s1);
2904 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2905 store_reg_to_var_int(iptr->dst, d);
2909 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2911 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2912 var_to_reg_int(s2, src->prev, REG_ITMP2);
2913 if (iptr->op1 == 0) {
2914 gen_nullptr_check(s1);
2917 var_to_reg_int(s3, src, REG_ITMP3);
2918 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2921 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2923 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2924 var_to_reg_int(s2, src->prev, REG_ITMP2);
2925 if (iptr->op1 == 0) {
2926 gen_nullptr_check(s1);
2930 if (src->flags & INMEMORY) {
2931 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2932 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2933 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2934 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2938 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2940 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2941 var_to_reg_int(s2, src->prev, REG_ITMP2);
2942 if (iptr->op1 == 0) {
2943 gen_nullptr_check(s1);
2946 var_to_reg_int(s3, src, REG_ITMP3);
2947 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2950 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2952 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2953 var_to_reg_int(s2, src->prev, REG_ITMP2);
2954 if (iptr->op1 == 0) {
2955 gen_nullptr_check(s1);
2958 var_to_reg_flt(s3, src, REG_FTMP1);
2959 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2963 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2965 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2966 var_to_reg_int(s2, src->prev, REG_ITMP2);
2967 if (iptr->op1 == 0) {
2968 gen_nullptr_check(s1);
2971 var_to_reg_flt(s3, src, REG_FTMP1);
2972 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2976 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2978 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2979 var_to_reg_int(s2, src->prev, REG_ITMP2);
2980 if (iptr->op1 == 0) {
2981 gen_nullptr_check(s1);
2984 var_to_reg_int(s3, src, REG_ITMP3);
2985 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2988 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2990 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2991 var_to_reg_int(s2, src->prev, REG_ITMP2);
2992 if (iptr->op1 == 0) {
2993 gen_nullptr_check(s1);
2996 var_to_reg_int(s3, src, REG_ITMP3);
2997 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
3000 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
3002 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
3003 var_to_reg_int(s2, src->prev, REG_ITMP2);
3004 if (iptr->op1 == 0) {
3005 gen_nullptr_check(s1);
3008 var_to_reg_int(s3, src, REG_ITMP3);
3009 M_INTMOVE(s3, REG_ITMP3); /* because EBP, ESI, EDI have no xH and xL bytes */
3010 i386_movb_reg_memindex(REG_ITMP3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3014 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3015 /* op1 = type, val.a = field address */
3017 /* if class isn't yet initialized, do it */
3018 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
3019 /* call helper function which patches this code */
3020 i386_mov_imm_reg((s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
3021 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
3022 i386_call_reg(REG_ITMP2);
3025 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
3026 /* here it's slightly slower */
3027 i386_mov_imm_reg(0, REG_ITMP2);
3028 dseg_adddata(mcodeptr);
3029 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3030 switch (iptr->op1) {
3033 var_to_reg_int(s2, src, REG_ITMP1);
3034 i386_mov_reg_membase(s2, REG_ITMP2, 0);
3037 if (src->flags & INMEMORY) {
3038 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3039 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
3040 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3041 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
3043 panic("PUTSTATIC: longs have to be in memory");
3047 var_to_reg_flt(s2, src, REG_FTMP1);
3048 i386_fstps_membase(REG_ITMP2, 0);
3052 var_to_reg_flt(s2, src, REG_FTMP1);
3053 i386_fstpl_membase(REG_ITMP2, 0);
3056 default: panic ("internal error");
3060 case ICMD_GETSTATIC: /* ... ==> ..., value */
3061 /* op1 = type, val.a = field address */
3063 /* if class isn't yet initialized, do it */
3064 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
3065 /* call helper function which patches this code */
3066 i386_mov_imm_reg((s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
3067 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
3068 i386_call_reg(REG_ITMP2);
3071 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
3072 i386_mov_imm_reg(0, REG_ITMP2);
3073 dseg_adddata(mcodeptr);
3074 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3075 switch (iptr->op1) {
3078 d = reg_of_var(iptr->dst, REG_ITMP1);
3079 i386_mov_membase_reg(REG_ITMP2, 0, d);
3080 store_reg_to_var_int(iptr->dst, d);
3083 d = reg_of_var(iptr->dst, REG_NULL);
3084 if (iptr->dst->flags & INMEMORY) {
3085 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3086 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3087 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3088 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3090 panic("GETSTATIC: longs have to be in memory");
3094 d = reg_of_var(iptr->dst, REG_FTMP1);
3095 i386_flds_membase(REG_ITMP2, 0);
3097 store_reg_to_var_flt(iptr->dst, d);
3100 d = reg_of_var(iptr->dst, REG_FTMP1);
3101 i386_fldl_membase(REG_ITMP2, 0);
3103 store_reg_to_var_flt(iptr->dst, d);
3105 default: panic ("internal error");
3109 case ICMD_PUTFIELD: /* ..., value ==> ... */
3110 /* op1 = type, val.i = field offset */
3112 a = ((fieldinfo *)(iptr->val.a))->offset;
3113 switch (iptr->op1) {
3116 var_to_reg_int(s1, src->prev, REG_ITMP1);
3117 var_to_reg_int(s2, src, REG_ITMP2);
3118 gen_nullptr_check(s1);
3119 i386_mov_reg_membase(s2, s1, a);
3122 var_to_reg_int(s1, src->prev, REG_ITMP1);
3123 gen_nullptr_check(s1);
3124 if (src->flags & INMEMORY) {
3125 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3126 i386_mov_reg_membase(REG_ITMP2, s1, a);
3127 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3128 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3130 panic("PUTFIELD: longs have to be in memory");
3134 var_to_reg_int(s1, src->prev, REG_ITMP1);
3135 var_to_reg_flt(s2, src, REG_FTMP1);
3136 gen_nullptr_check(s1);
3137 i386_fstps_membase(s1, a);
3141 var_to_reg_int(s1, src->prev, REG_ITMP1);
3142 var_to_reg_flt(s2, src, REG_FTMP1);
3143 gen_nullptr_check(s1);
3144 i386_fstpl_membase(s1, a);
3147 default: panic ("internal error");
3151 case ICMD_GETFIELD: /* ... ==> ..., value */
3152 /* op1 = type, val.i = field offset */
3154 a = ((fieldinfo *)(iptr->val.a))->offset;
3155 switch (iptr->op1) {
3158 var_to_reg_int(s1, src, REG_ITMP1);
3159 d = reg_of_var(iptr->dst, REG_ITMP2);
3160 gen_nullptr_check(s1);
3161 i386_mov_membase_reg(s1, a, d);
3162 store_reg_to_var_int(iptr->dst, d);
3165 var_to_reg_int(s1, src, REG_ITMP1);
3166 d = reg_of_var(iptr->dst, REG_NULL);
3167 gen_nullptr_check(s1);
3168 i386_mov_membase_reg(s1, a, REG_ITMP2);
3169 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3170 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3171 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3174 var_to_reg_int(s1, src, REG_ITMP1);
3175 d = reg_of_var(iptr->dst, REG_FTMP1);
3176 gen_nullptr_check(s1);
3177 i386_flds_membase(s1, a);
3179 store_reg_to_var_flt(iptr->dst, d);
3182 var_to_reg_int(s1, src, REG_ITMP1);
3183 d = reg_of_var(iptr->dst, REG_FTMP1);
3184 gen_nullptr_check(s1);
3185 i386_fldl_membase(s1, a);
3187 store_reg_to_var_flt(iptr->dst, d);
3189 default: panic ("internal error");
3194 /* branch operations **************************************************/
3197 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3198 #define ALIGNCODENOP do {} while (0)
3200 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3202 var_to_reg_int(s1, src, REG_ITMP1);
3203 M_INTMOVE(s1, REG_ITMP1_XPTR);
3205 i386_call_imm(0); /* passing exception pointer */
3206 i386_pop_reg(REG_ITMP2_XPC);
3208 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
3209 i386_jmp_reg(REG_ITMP3);
3213 case ICMD_GOTO: /* ... ==> ... */
3214 /* op1 = target JavaVM pc */
3217 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3221 case ICMD_JSR: /* ... ==> ... */
3222 /* op1 = target JavaVM pc */
3225 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3228 case ICMD_RET: /* ... ==> ... */
3229 /* op1 = local variable */
3231 var = &(locals[iptr->op1][TYPE_ADR]);
3232 var_to_reg_int(s1, var, REG_ITMP1);
3236 case ICMD_IFNULL: /* ..., value ==> ... */
3237 /* op1 = target JavaVM pc */
3239 if (src->flags & INMEMORY) {
3240 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3243 i386_test_reg_reg(src->regoff, src->regoff);
3245 i386_jcc(I386_CC_E, 0);
3246 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3249 case ICMD_IFNONNULL: /* ..., value ==> ... */
3250 /* op1 = target JavaVM pc */
3252 if (src->flags & INMEMORY) {
3253 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3256 i386_test_reg_reg(src->regoff, src->regoff);
3258 i386_jcc(I386_CC_NE, 0);
3259 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3262 case ICMD_IFEQ: /* ..., value ==> ... */
3263 /* op1 = target JavaVM pc, val.i = constant */
3265 if (src->flags & INMEMORY) {
3266 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3269 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3271 i386_jcc(I386_CC_E, 0);
3272 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3275 case ICMD_IFLT: /* ..., value ==> ... */
3276 /* op1 = target JavaVM pc, val.i = constant */
3278 if (src->flags & INMEMORY) {
3279 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3282 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3284 i386_jcc(I386_CC_L, 0);
3285 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3288 case ICMD_IFLE: /* ..., value ==> ... */
3289 /* op1 = target JavaVM pc, val.i = constant */
3291 if (src->flags & INMEMORY) {
3292 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3295 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3297 i386_jcc(I386_CC_LE, 0);
3298 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3301 case ICMD_IFNE: /* ..., value ==> ... */
3302 /* op1 = target JavaVM pc, val.i = constant */
3304 if (src->flags & INMEMORY) {
3305 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3308 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3310 i386_jcc(I386_CC_NE, 0);
3311 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3314 case ICMD_IFGT: /* ..., value ==> ... */
3315 /* op1 = target JavaVM pc, val.i = constant */
3317 if (src->flags & INMEMORY) {
3318 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3321 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3323 i386_jcc(I386_CC_G, 0);
3324 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3327 case ICMD_IFGE: /* ..., value ==> ... */
3328 /* op1 = target JavaVM pc, val.i = constant */
3330 if (src->flags & INMEMORY) {
3331 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3334 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3336 i386_jcc(I386_CC_GE, 0);
3337 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3340 case ICMD_IF_LEQ: /* ..., value ==> ... */
3341 /* op1 = target JavaVM pc, val.l = constant */
3343 if (src->flags & INMEMORY) {
3344 if (iptr->val.l == 0) {
3345 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3346 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3349 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3350 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3351 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3352 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3353 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3356 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3357 i386_jcc(I386_CC_E, 0);
3358 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3361 case ICMD_IF_LLT: /* ..., 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_B, 0);
3377 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3381 case ICMD_IF_LLE: /* ..., value ==> ... */
3382 /* op1 = target JavaVM pc, val.l = constant */
3384 if (src->flags & INMEMORY) {
3385 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3386 i386_jcc(I386_CC_L, 0);
3387 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3390 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3391 CALCIMMEDIATEBYTES(a, iptr->val.l);
3393 i386_jcc(I386_CC_G, a);
3395 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3396 i386_jcc(I386_CC_BE, 0);
3397 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3401 case ICMD_IF_LNE: /* ..., value ==> ... */
3402 /* op1 = target JavaVM pc, val.l = constant */
3404 if (src->flags & INMEMORY) {
3405 if (iptr->val.l == 0) {
3406 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3407 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3410 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3411 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3412 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3413 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3414 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3417 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3418 i386_jcc(I386_CC_NE, 0);
3419 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3422 case ICMD_IF_LGT: /* ..., 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_A, 0);
3438 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3442 case ICMD_IF_LGE: /* ..., value ==> ... */
3443 /* op1 = target JavaVM pc, val.l = constant */
3445 if (src->flags & INMEMORY) {
3446 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3447 i386_jcc(I386_CC_G, 0);
3448 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3451 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3452 CALCIMMEDIATEBYTES(a, iptr->val.l);
3454 i386_jcc(I386_CC_L, a);
3456 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3457 i386_jcc(I386_CC_AE, 0);
3458 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3462 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3463 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3465 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3466 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3467 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3469 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3470 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3472 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3473 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3476 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3478 i386_jcc(I386_CC_E, 0);
3479 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3482 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3483 /* op1 = target JavaVM pc */
3485 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3486 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3487 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3488 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3489 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3490 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3491 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3493 i386_jcc(I386_CC_E, 0);
3494 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3497 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3498 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3500 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3501 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3502 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3504 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3505 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3507 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3508 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3511 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3513 i386_jcc(I386_CC_NE, 0);
3514 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3517 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3518 /* op1 = target JavaVM pc */
3520 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3521 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3522 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3523 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3524 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3525 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3526 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3528 i386_jcc(I386_CC_NE, 0);
3529 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3532 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3533 /* op1 = target JavaVM pc */
3535 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3536 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3537 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3539 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3540 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3542 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3543 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3546 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3548 i386_jcc(I386_CC_L, 0);
3549 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3552 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3553 /* op1 = target JavaVM pc */
3555 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3556 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3557 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3558 i386_jcc(I386_CC_L, 0);
3559 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3562 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3563 CALCOFFSETBYTES(a, REG_SP, src->regoff);
3565 i386_jcc(I386_CC_G, a);
3567 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3568 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3569 i386_jcc(I386_CC_B, 0);
3570 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3574 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3575 /* op1 = target JavaVM pc */
3577 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3578 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3579 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3581 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3582 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3584 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3585 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3588 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3590 i386_jcc(I386_CC_G, 0);
3591 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3594 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3595 /* op1 = target JavaVM pc */
3597 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3598 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3599 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3600 i386_jcc(I386_CC_G, 0);
3601 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3604 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3605 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3607 i386_jcc(I386_CC_L, a);
3609 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3610 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3611 i386_jcc(I386_CC_A, 0);
3612 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3616 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3617 /* op1 = target JavaVM pc */
3619 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3620 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3621 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3623 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3624 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3626 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3627 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3630 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3632 i386_jcc(I386_CC_LE, 0);
3633 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3636 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3637 /* op1 = target JavaVM pc */
3639 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3640 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3641 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3642 i386_jcc(I386_CC_L, 0);
3643 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3646 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3647 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3649 i386_jcc(I386_CC_G, a);
3651 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3652 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3653 i386_jcc(I386_CC_BE, 0);
3654 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3658 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3659 /* op1 = target JavaVM pc */
3661 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3662 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3663 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3665 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3666 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3668 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3669 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3672 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3674 i386_jcc(I386_CC_GE, 0);
3675 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3678 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3679 /* op1 = target JavaVM pc */
3681 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3682 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3683 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3684 i386_jcc(I386_CC_G, 0);
3685 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3688 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3689 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3691 i386_jcc(I386_CC_L, a);
3693 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3694 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3695 i386_jcc(I386_CC_AE, 0);
3696 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3700 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3702 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3705 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3706 /* val.i = constant */
3708 d = reg_of_var(iptr->dst, REG_NULL);
3709 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3712 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3713 /* val.i = constant */
3715 d = reg_of_var(iptr->dst, REG_NULL);
3716 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3719 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3720 /* val.i = constant */
3722 d = reg_of_var(iptr->dst, REG_NULL);
3723 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3726 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3727 /* val.i = constant */
3729 d = reg_of_var(iptr->dst, REG_NULL);
3730 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3733 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3734 /* val.i = constant */
3736 d = reg_of_var(iptr->dst, REG_NULL);
3737 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3740 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3741 /* val.i = constant */
3743 d = reg_of_var(iptr->dst, REG_NULL);
3744 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3748 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3752 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3753 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3754 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3755 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3756 i386_mov_imm_reg((s4) asm_builtin_monitorexit, REG_ITMP1);
3757 i386_call_reg(REG_ITMP1);
3758 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3761 var_to_reg_int(s1, src, REG_RESULT);
3762 M_INTMOVE(s1, REG_RESULT);
3763 goto nowperformreturn;
3765 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3768 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3769 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3770 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3771 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3772 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3773 i386_call_reg(REG_ITMP1);
3774 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3777 if (src->flags & INMEMORY) {
3778 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3779 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3782 panic("LRETURN: longs have to be in memory");
3784 goto nowperformreturn;
3786 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3789 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3790 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3791 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3792 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3793 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3794 i386_call_reg(REG_ITMP1);
3795 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3798 var_to_reg_flt(s1, src, REG_FRESULT);
3799 /* this may be an early return -- keep the offset correct for the remaining code */
3801 goto nowperformreturn;
3803 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3806 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3807 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3808 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3809 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3810 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3811 i386_call_reg(REG_ITMP1);
3812 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3815 var_to_reg_flt(s1, src, REG_FRESULT);
3816 /* this may be an early return -- keep the offset correct for the remaining code */
3818 goto nowperformreturn;
3820 case ICMD_RETURN: /* ... ==> ... */
3823 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3824 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3825 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3826 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3827 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3828 i386_call_reg(REG_ITMP1);
3829 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3837 p = parentargs_base;
3839 /* restore saved registers */
3840 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3842 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3844 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3846 i386_fldl_membase(REG_SP, p * 8);
3848 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3849 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3851 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3856 /* deallocate stack */
3857 if (parentargs_base) {
3858 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3861 /* call trace function */
3863 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3865 i386_mov_imm_membase((s4) method, REG_SP, 0);
3867 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3868 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3870 i386_fstl_membase(REG_SP, 4 + 8);
3871 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3873 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3874 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3875 i386_call_reg(REG_ITMP1);
3877 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3878 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3880 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3889 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3894 tptr = (void **) iptr->target;
3896 s4ptr = iptr->val.a;
3897 l = s4ptr[1]; /* low */
3898 i = s4ptr[2]; /* high */
3900 var_to_reg_int(s1, src, REG_ITMP1);
3901 M_INTMOVE(s1, REG_ITMP1);
3903 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3909 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3910 i386_jcc(I386_CC_A, 0);
3912 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3913 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3915 /* build jump table top down and use address of lowest entry */
3917 /* s4ptr += 3 + i; */
3921 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3922 dseg_addtarget((basicblock *) tptr[0]);
3926 /* length of dataseg after last dseg_addtarget is used by load */
3928 i386_mov_imm_reg(0, REG_ITMP2);
3929 dseg_adddata(mcodeptr);
3930 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3931 i386_jmp_reg(REG_ITMP1);
3937 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3939 s4 i, l, val, *s4ptr;
3942 tptr = (void **) iptr->target;
3944 s4ptr = iptr->val.a;
3945 l = s4ptr[0]; /* default */
3946 i = s4ptr[1]; /* count */
3948 MCODECHECK((i<<2)+8);
3949 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3955 i386_alu_imm_reg(I386_CMP, val, s1);
3956 i386_jcc(I386_CC_E, 0);
3957 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3958 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3962 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3964 tptr = (void **) iptr->target;
3965 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3972 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3973 /* op1 = return type, val.a = function pointer*/
3977 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3978 /* op1 = return type, val.a = function pointer*/
3982 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3983 /* op1 = return type, val.a = function pointer*/
3987 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3988 /* op1 = arg count, val.a = method pointer */
3990 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3991 /* op1 = arg count, val.a = method pointer */
3993 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3994 /* op1 = arg count, val.a = method pointer */
3996 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3997 /* op1 = arg count, val.a = method pointer */
4005 MCODECHECK((s3 << 1) + 64);
4007 /* copy arguments to registers or stack location */
4009 for (; --s3 >= 0; src = src->prev) {
4010 if (src->varkind == ARGVAR) {
4014 if (IS_INT_LNG_TYPE(src->type)) {
4015 if (s3 < intreg_argnum) {
4016 panic("No integer argument registers available!");
4019 if (!IS_2_WORD_TYPE(src->type)) {
4020 if (src->flags & INMEMORY) {
4021 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4022 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4025 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4029 if (src->flags & INMEMORY) {
4030 M_LNGMEMMOVE(src->regoff, s3);
4033 panic("copy arguments: longs have to be in memory");
4039 if (s3 < fltreg_argnum) {
4040 panic("No float argument registers available!");
4043 var_to_reg_flt(d, src, REG_FTMP1);
4044 if (src->type == TYPE_FLT) {
4045 i386_fstps_membase(REG_SP, s3 * 8);
4048 i386_fstpl_membase(REG_SP, s3 * 8);
4055 switch (iptr->opc) {
4063 i386_mov_imm_reg(a, REG_ITMP1);
4064 i386_call_reg(REG_ITMP1);
4067 case ICMD_INVOKESTATIC:
4069 a = (s4) m->stubroutine;
4072 i386_mov_imm_reg(a, REG_ITMP2);
4073 i386_call_reg(REG_ITMP2);
4076 case ICMD_INVOKESPECIAL:
4078 a = (s4) m->stubroutine;
4081 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4082 gen_nullptr_check(REG_ITMP1);
4083 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4085 i386_mov_imm_reg(a, REG_ITMP2);
4086 i386_call_reg(REG_ITMP2);
4089 case ICMD_INVOKEVIRTUAL:
4093 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4094 gen_nullptr_check(REG_ITMP1);
4095 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4096 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4098 i386_call_reg(REG_ITMP1);
4101 case ICMD_INVOKEINTERFACE:
4106 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4107 gen_nullptr_check(REG_ITMP1);
4108 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4109 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4110 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4112 i386_call_reg(REG_ITMP1);
4117 error("Unkown ICMD-Command: %d", iptr->opc);
4120 /* d contains return type */
4122 if (d != TYPE_VOID) {
4123 d = reg_of_var(iptr->dst, REG_NULL);
4125 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4126 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4127 if (iptr->dst->flags & INMEMORY) {
4128 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4129 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4132 panic("RETURN: longs have to be in memory");
4136 if (iptr->dst->flags & INMEMORY) {
4137 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4140 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4145 /* fld from called function -- has other fpu_st_offset counter */
4147 store_reg_to_var_flt(iptr->dst, d);
4154 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4156 /* op1: 0 == array, 1 == class */
4157 /* val.a: (classinfo*) superclass */
4159 /* superclass is an interface:
4161 * return (sub != NULL) &&
4162 * (sub->vftbl->interfacetablelength > super->index) &&
4163 * (sub->vftbl->interfacetable[-super->index] != NULL);
4165 * superclass is a class:
4167 * return ((sub != NULL) && (0
4168 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4169 * super->vftbl->diffvall));
4173 classinfo *super = (classinfo*) iptr->val.a;
4175 var_to_reg_int(s1, src, REG_ITMP1);
4176 d = reg_of_var(iptr->dst, REG_ITMP3);
4178 M_INTMOVE(s1, REG_ITMP1);
4181 i386_alu_reg_reg(I386_XOR, d, d);
4182 if (iptr->op1) { /* class/interface */
4183 if (super->flags & ACC_INTERFACE) { /* interface */
4184 i386_test_reg_reg(s1, s1);
4186 /* TODO: clean up this calculation */
4188 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4191 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4194 /* CALCOFFSETBYTES(a, super->index); */
4195 CALCIMMEDIATEBYTES(a, super->index);
4201 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4208 i386_jcc(I386_CC_E, a);
4210 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4211 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4212 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4214 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4216 /* TODO: clean up this calculation */
4219 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4226 i386_jcc(I386_CC_LE, a);
4227 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4229 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4230 /* i386_setcc_reg(I386_CC_A, d); */
4231 /* i386_jcc(I386_CC_BE, 5); */
4232 i386_jcc(I386_CC_E, 5);
4233 i386_mov_imm_reg(1, d);
4236 } else { /* class */
4237 i386_test_reg_reg(s1, s1);
4239 /* TODO: clean up this calculation */
4241 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4244 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4246 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4249 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4259 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4260 a += 32 + (s1==REG_ITMP1)*2 + (d==REG_ITMP3)*2;
4263 i386_jcc(I386_CC_E, a);
4265 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4266 i386_mov_imm_reg(1, REG_ITMP2);
4268 i386_xadd_reg_mem(REG_ITMP2, (u4) &cast_counter);
4269 i386_jcc(I386_CC_E, 6 + (s1==REG_ITMP1)*2 + (d==REG_ITMP3)*2);
4270 if (s1 == REG_ITMP1)
4271 i386_push_reg(REG_ITMP1);
4272 i386_call_mem((s4) &castlockptr);
4273 if (s1 == REG_ITMP1)
4274 i386_pop_reg(REG_ITMP1);
4276 i386_alu_reg_reg(I386_XOR, d, d);
4279 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4280 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4281 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4282 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4283 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4284 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4285 i386_alu_reg_reg(I386_XOR, d, d);
4287 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4289 i386_dec_mem((s4) &cast_counter);
4292 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4293 i386_jcc(I386_CC_A, 5);
4294 i386_mov_imm_reg(1, d);
4298 panic ("internal error: no inlined array instanceof");
4300 store_reg_to_var_int(iptr->dst, d);
4303 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4305 /* op1: 0 == array, 1 == class */
4306 /* val.a: (classinfo*) superclass */
4308 /* superclass is an interface:
4310 * OK if ((sub == NULL) ||
4311 * (sub->vftbl->interfacetablelength > super->index) &&
4312 * (sub->vftbl->interfacetable[-super->index] != NULL));
4314 * superclass is a class:
4316 * OK if ((sub == NULL) || (0
4317 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4318 * super->vftbl->diffvall));
4322 classinfo *super = (classinfo*) iptr->val.a;
4324 d = reg_of_var(iptr->dst, REG_ITMP3);
4325 var_to_reg_int(s1, src, d);
4326 if (iptr->op1) { /* class/interface */
4327 if (super->flags & ACC_INTERFACE) { /* interface */
4328 i386_test_reg_reg(s1, s1);
4330 /* TODO: clean up this calculation */
4332 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4335 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4338 /* CALCOFFSETBYTES(a, super->index); */
4339 CALCIMMEDIATEBYTES(a, super->index);
4345 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4350 i386_jcc(I386_CC_E, a);
4352 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4353 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4354 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4356 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4357 i386_jcc(I386_CC_LE, 0);
4358 codegen_addxcastrefs(mcodeptr);
4359 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4361 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4362 i386_jcc(I386_CC_E, 0);
4363 codegen_addxcastrefs(mcodeptr);
4365 } else { /* class */
4366 i386_test_reg_reg(s1, s1);
4368 /* TODO: clean up this calculation */
4370 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4375 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4377 if (d != REG_ITMP3) {
4379 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4382 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4388 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4395 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4402 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4403 a += 32 + (s1==REG_ITMP3)*2;
4406 i386_jcc(I386_CC_E, a);
4409 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4410 i386_mov_imm_reg(1, REG_ITMP2);
4412 i386_xadd_reg_mem(REG_ITMP2, (u4) &cast_counter);
4413 i386_jcc(I386_CC_E, 6 + (s1==REG_ITMP3)*2);
4414 if (s1 == REG_ITMP3)
4415 i386_push_reg(REG_ITMP3);
4416 i386_call_mem((s4) &castlockptr);
4417 if (s1 == REG_ITMP3)
4418 i386_pop_reg(REG_ITMP3);
4422 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4423 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4424 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4425 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4426 codegen_threadcritstart(mcodeptr - mcodebase);
4428 if (d != REG_ITMP3) {
4429 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4430 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4431 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4432 codegen_threadcritstop(mcodeptr - mcodebase);
4434 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4437 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4438 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4439 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4440 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4441 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4442 codegen_threadcritstop(mcodeptr - mcodebase);
4446 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4448 i386_dec_mem((s4) &cast_counter);
4451 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4452 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4453 codegen_addxcastrefs(mcodeptr);
4457 panic ("internal error: no inlined array checkcast");
4460 store_reg_to_var_int(iptr->dst, d);
4463 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4465 if (src->flags & INMEMORY) {
4466 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4469 i386_test_reg_reg(src->regoff, src->regoff);
4471 i386_jcc(I386_CC_L, 0);
4472 codegen_addxcheckarefs(mcodeptr);
4475 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4476 /* op1 = dimension, val.a = array descriptor */
4478 /* check for negative sizes and copy sizes to stack if necessary */
4480 MCODECHECK((iptr->op1 << 1) + 64);
4482 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4483 if (src->flags & INMEMORY) {
4484 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4487 i386_test_reg_reg(src->regoff, src->regoff);
4489 i386_jcc(I386_CC_L, 0);
4490 codegen_addxcheckarefs(mcodeptr);
4493 * copy sizes to new stack location, be cause native function
4494 * builtin_nmultianewarray access them as (int *)
4496 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4497 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4499 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4501 if (src->varkind != ARGVAR) {
4502 if (src->flags & INMEMORY) {
4503 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4504 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4507 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4511 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4513 /* a0 = dimension count */
4515 /* save stack pointer */
4516 M_INTMOVE(REG_SP, REG_ITMP1);
4518 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4519 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4521 /* a1 = arraydescriptor */
4523 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4525 /* a2 = pointer to dimensions = stack pointer */
4527 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4529 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4530 i386_call_reg(REG_ITMP1);
4531 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4533 s1 = reg_of_var(iptr->dst, REG_RESULT);
4534 M_INTMOVE(REG_RESULT, s1);
4535 store_reg_to_var_int(iptr->dst, s1);
4539 error ("Unknown pseudo command: %d", iptr->opc);
4542 } /* for instruction */
4544 /* copy values to interface registers */
4546 src = bptr->outstack;
4547 len = bptr->outdepth;
4551 if ((src->varkind != STACKVAR)) {
4553 if (IS_FLT_DBL_TYPE(s2)) {
4554 var_to_reg_flt(s1, src, REG_FTMP1);
4555 if (!(interfaces[len][s2].flags & INMEMORY)) {
4556 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4559 panic("double store");
4560 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4564 var_to_reg_int(s1, src, REG_ITMP1);
4565 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4566 if (!(interfaces[len][s2].flags & INMEMORY)) {
4567 M_INTMOVE(s1, interfaces[len][s2].regoff);
4570 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4574 if (interfaces[len][s2].flags & INMEMORY) {
4575 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4578 panic("copy interface registers: longs have to be in memory (end)");
4585 } /* if (bptr -> flags >= BBREACHED) */
4586 } /* for basic block */
4588 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4592 /* generate bound check stubs */
4593 u1 *xcodeptr = NULL;
4595 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4596 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4597 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4598 xboundrefs->branchpos,
4599 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4604 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4605 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4609 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4610 dseg_adddata(mcodeptr);
4611 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4612 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4614 if (xcodeptr != NULL) {
4615 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4618 xcodeptr = mcodeptr;
4620 i386_mov_imm_reg((s4) proto_java_lang_ArrayIndexOutOfBoundsException, REG_ITMP1_XPTR);
4621 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4622 i386_jmp_reg(REG_ITMP3);
4626 /* generate negative array size check stubs */
4629 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4630 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4631 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4632 xcheckarefs->branchpos,
4633 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4637 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4638 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4642 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4643 dseg_adddata(mcodeptr);
4644 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4645 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4647 if (xcodeptr != NULL) {
4648 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4651 xcodeptr = mcodeptr;
4653 i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR);
4654 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4655 i386_jmp_reg(REG_ITMP3);
4659 /* generate cast check stubs */
4662 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4663 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4664 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4665 xcastrefs->branchpos,
4666 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4670 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4671 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4675 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4676 dseg_adddata(mcodeptr);
4677 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4678 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4680 if (xcodeptr != NULL) {
4681 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4684 xcodeptr = mcodeptr;
4686 i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR);
4687 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4688 i386_jmp_reg(REG_ITMP3);
4692 /* generate divide by zero check stubs */
4695 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4696 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4697 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4698 xdivrefs->branchpos,
4699 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4703 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4704 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4708 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4709 dseg_adddata(mcodeptr);
4710 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4711 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4713 if (xcodeptr != NULL) {
4714 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4717 xcodeptr = mcodeptr;
4719 i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR);
4720 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4721 i386_jmp_reg(REG_ITMP3);
4725 /* generate null pointer check stubs */
4728 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4729 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4730 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4731 xnullrefs->branchpos,
4732 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4736 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4737 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4741 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4742 dseg_adddata(mcodeptr);
4743 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4744 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4746 if (xcodeptr != NULL) {
4747 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4750 xcodeptr = mcodeptr;
4752 i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR);
4753 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4754 i386_jmp_reg(REG_ITMP3);
4759 codegen_finish((int)((u1*) mcodeptr - mcodebase));
4763 /* function createcompilerstub *************************************************
4765 creates a stub routine which calls the compiler
4767 *******************************************************************************/
4769 #define COMPSTUBSIZE 12
4771 u1 *createcompilerstub(methodinfo *m)
4773 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4774 mcodeptr = s; /* code generation pointer */
4776 /* code for the stub */
4777 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4779 /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching */
4780 i386_mov_imm_reg((s4) asm_call_jit_compiler, REG_ITMP3); /* load address */
4781 i386_jmp_reg(REG_ITMP3); /* jump to compiler */
4784 count_cstub_len += COMPSTUBSIZE;
4791 /* function removecompilerstub *************************************************
4793 deletes a compilerstub from memory (simply by freeing it)
4795 *******************************************************************************/
4797 void removecompilerstub(u1 *stub)
4799 CFREE(stub, COMPSTUBSIZE);
4802 /* function: createnativestub **************************************************
4804 creates a stub routine which calls a native method
4806 *******************************************************************************/
4808 #define NATIVESTUBSIZE 340
4810 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4811 static java_objectheader *(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
4812 static void (*callresetexceptionptr)() = builtin_reset_exceptionptr;
4815 u1 *createnativestub(functionptr f, methodinfo *m)
4817 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4821 int stackframesize = 4; /* initial 4 bytes is space for jni env */
4822 int stackframeoffset = 4;
4826 mcodeptr = s; /* make macros work */
4828 if (m->flags & ACC_STATIC) {
4829 stackframesize += 4;
4830 stackframeoffset += 4;
4834 descriptor2types(m); /* set paramcount and paramtypes */
4837 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4839 for (p = 0; p < m->paramcount; p++) {
4840 t = m->paramtypes[p];
4841 if (IS_INT_LNG_TYPE(t)) {
4842 if (IS_2_WORD_TYPE(t)) {
4843 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4844 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4845 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4846 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4848 } else if (t == TYPE_ADR) {
4849 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4850 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4851 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4852 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4855 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
4857 i386_mov_reg_membase(EAX, REG_SP, p * 8);
4858 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
4862 if (t == TYPE_FLT) {
4863 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4864 i386_fstps_membase(REG_SP, p * 8);
4865 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4866 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4869 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4870 i386_fstpl_membase(REG_SP, p * 8);
4875 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4876 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4877 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4878 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4881 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4883 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
4884 i386_call_reg(REG_ITMP1);
4886 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4890 * mark the whole fpu stack as free for native functions
4891 * (only for saved register count == 0)
4902 /* calculate stackframe size for native function */
4903 tptr = m->paramtypes;
4904 for (i = 0; i < m->paramcount; i++) {
4909 stackframesize += 4;
4914 stackframesize += 8;
4918 panic("unknown parameter type in native function");
4922 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4924 tptr = m->paramtypes;
4925 for (i = 0; i < m->paramcount; i++) {
4930 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4931 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4932 stackframeoffset += 4;
4937 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
4938 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
4939 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
4940 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
4941 stackframeoffset += 8;
4945 panic("unknown parameter type in native function");
4949 if (m->flags & ACC_STATIC) {
4950 i386_mov_imm_membase((s4) m->class, REG_SP, 4);
4953 i386_mov_imm_membase((s4) &env, REG_SP, 0);
4955 i386_mov_imm_reg((s4) f, REG_ITMP1);
4956 i386_call_reg(REG_ITMP1);
4957 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
4960 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
4962 i386_mov_imm_membase((s4) m, REG_SP, 0);
4964 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
4965 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
4967 i386_fstl_membase(REG_SP, 4 + 8);
4968 i386_fsts_membase(REG_SP, 4 + 8 + 8);
4970 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
4971 i386_call_reg(REG_ITMP1);
4973 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
4974 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
4976 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
4979 /* we can't use REG_ITMP3 == REG_RESULT2 */
4980 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4981 i386_push_reg(REG_RESULT);
4982 i386_push_reg(REG_RESULT2);
4983 i386_call_mem(&callgetexceptionptrptr);
4984 i386_mov_membase_reg(REG_RESULT, 0, REG_ITMP2);
4985 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
4986 i386_pop_reg(REG_RESULT2);
4987 i386_pop_reg(REG_RESULT);
4989 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP2);
4990 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP2);
4991 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
4993 i386_jcc(I386_CC_NE, 1);
4997 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4998 i386_push_reg(REG_ITMP2);
4999 i386_call_mem(&callresetexceptionptr);
5000 i386_pop_reg(REG_ITMP1_XPTR);
5002 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1_XPTR);
5003 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP2);
5004 i386_mov_imm_membase(0, REG_ITMP2, 0);
5006 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
5007 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
5009 i386_mov_imm_reg((s4) asm_handle_nat_exception, REG_ITMP3);
5010 i386_jmp_reg(REG_ITMP3);
5013 count_nstub_len += NATIVESTUBSIZE;
5019 /* function: removenativestub **************************************************
5021 removes a previously created native-stub from memory
5023 *******************************************************************************/
5025 void removenativestub(u1 *stub)
5027 CFREE(stub, NATIVESTUBSIZE);
5032 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
5034 if (iptr->dst->flags & INMEMORY) {
5035 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5036 if (src->regoff == iptr->dst->regoff) {
5037 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5038 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5040 } else if (src->prev->regoff == iptr->dst->regoff) {
5041 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5042 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5045 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5046 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5047 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5050 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5051 if (src->regoff == iptr->dst->regoff) {
5052 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5055 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5056 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
5057 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5060 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5061 if (src->prev->regoff == iptr->dst->regoff) {
5062 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
5065 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5066 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
5067 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5071 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5072 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
5076 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5077 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5078 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
5080 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5081 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5082 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
5084 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5085 M_INTMOVE(src->regoff, iptr->dst->regoff);
5086 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5089 if (src->regoff == iptr->dst->regoff) {
5090 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
5093 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5094 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
5102 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
5104 if (iptr->dst->flags & INMEMORY) {
5105 if (src->flags & INMEMORY) {
5106 if (src->regoff == iptr->dst->regoff) {
5107 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5110 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5111 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
5112 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5116 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5117 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5121 if (src->flags & INMEMORY) {
5122 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5123 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5126 M_INTMOVE(src->regoff, iptr->dst->regoff);
5127 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5134 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
5136 if (iptr->dst->flags & INMEMORY) {
5137 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5138 if (src->regoff == iptr->dst->regoff) {
5139 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5140 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5141 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5142 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5144 } else if (src->prev->regoff == iptr->dst->regoff) {
5145 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5146 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5147 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5148 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5151 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5152 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5153 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5154 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5155 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5156 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5164 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5166 if (iptr->dst->flags & INMEMORY) {
5167 if (src->flags & INMEMORY) {
5168 if (src->regoff == iptr->dst->regoff) {
5169 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5170 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5173 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5174 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5175 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5176 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5177 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP1);
5178 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5186 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5188 if (iptr->dst->flags & INMEMORY) {
5189 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5190 if (src->prev->regoff == iptr->dst->regoff) {
5191 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5192 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5195 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5196 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5197 i386_shift_reg(shift_op, REG_ITMP1);
5198 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5201 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5202 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5203 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5204 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5206 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5207 if (src->prev->regoff == iptr->dst->regoff) {
5208 M_INTMOVE(src->regoff, ECX);
5209 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5212 M_INTMOVE(src->regoff, ECX);
5213 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5214 i386_shift_reg(shift_op, REG_ITMP1);
5215 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5219 M_INTMOVE(src->regoff, ECX);
5220 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5221 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5225 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5226 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5227 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5228 i386_shift_reg(shift_op, iptr->dst->regoff);
5230 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5231 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5232 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5233 i386_shift_reg(shift_op, iptr->dst->regoff);
5235 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5236 M_INTMOVE(src->regoff, ECX);
5237 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5238 i386_shift_reg(shift_op, iptr->dst->regoff);
5241 M_INTMOVE(src->regoff, ECX);
5242 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5243 i386_shift_reg(shift_op, iptr->dst->regoff);
5250 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5252 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5253 if (src->regoff == iptr->dst->regoff) {
5254 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5257 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5258 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5259 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5262 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5263 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5264 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5266 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5267 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5268 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5271 M_INTMOVE(src->regoff, iptr->dst->regoff);
5272 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5278 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5280 if (iptr->dst->flags & INMEMORY) {
5283 if (src->flags & INMEMORY) {
5284 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5287 i386_test_reg_reg(src->regoff, src->regoff);
5291 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 8);
5293 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5294 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5296 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5297 i386_jmp_imm(offset);
5298 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5302 if (src->flags & INMEMORY) {
5303 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5306 i386_test_reg_reg(src->regoff, src->regoff);
5309 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5310 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5312 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5314 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5324 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5325 *(mcodeptr++) = (u1) 0x89;
5326 i386_emit_reg((reg),(dreg));
5330 void i386_mov_imm_reg(s4 imm, s4 reg) {
5331 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5332 i386_emit_imm32((imm));
5336 void i386_movb_imm_reg(s4 imm, s4 reg) {
5337 *(mcodeptr++) = (u1) 0xc6;
5338 i386_emit_reg(0,(reg));
5339 i386_emit_imm8((imm));
5343 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5344 *(mcodeptr++) = (u1) 0x8b;
5345 i386_emit_membase((basereg),(disp),(reg));
5350 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5351 * constant membase immediate length of 32bit
5353 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5354 *(mcodeptr++) = (u1) 0x8b;
5355 i386_address_byte(2, (reg), (basereg));
5356 i386_emit_imm32((disp));
5360 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5361 *(mcodeptr++) = (u1) 0x89;
5362 i386_emit_membase((basereg),(disp),(reg));
5366 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5367 *(mcodeptr++) = (u1) 0x8b;
5368 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5372 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5373 *(mcodeptr++) = (u1) 0x89;
5374 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5378 void i386_mov_mem_reg(s4 mem, s4 dreg) {
5379 *(mcodeptr++) = (u1) 0x8b;
5380 i386_emit_mem((dreg),(mem));
5384 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5385 *(mcodeptr++) = (u1) 0x66;
5386 *(mcodeptr++) = (u1) 0x89;
5387 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5391 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5392 *(mcodeptr++) = (u1) 0x88;
5393 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5397 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5398 *(mcodeptr++) = (u1) 0xc7;
5399 i386_emit_membase((basereg),(disp),0);
5400 i386_emit_imm32((imm));
5404 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5405 *(mcodeptr++) = (u1) 0x0f;
5406 *(mcodeptr++) = (u1) 0xbe;
5407 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5411 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5412 *(mcodeptr++) = (u1) 0x0f;
5413 *(mcodeptr++) = (u1) 0xbf;
5414 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5418 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5419 *(mcodeptr++) = (u1) 0x0f;
5420 *(mcodeptr++) = (u1) 0xb7;
5421 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5429 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5430 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5431 i386_emit_reg((reg),(dreg));
5435 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5436 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5437 i386_emit_membase((basereg),(disp),(reg));
5441 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5442 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5443 i386_emit_membase((basereg),(disp),(reg));
5447 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5448 if (i386_is_imm8(imm)) {
5449 *(mcodeptr++) = (u1) 0x83;
5450 i386_emit_reg((opc),(dreg));
5451 i386_emit_imm8((imm));
5453 *(mcodeptr++) = (u1) 0x81;
5454 i386_emit_reg((opc),(dreg));
5455 i386_emit_imm32((imm));
5460 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5461 if (i386_is_imm8(imm)) {
5462 *(mcodeptr++) = (u1) 0x83;
5463 i386_emit_membase((basereg),(disp),(opc));
5464 i386_emit_imm8((imm));
5466 *(mcodeptr++) = (u1) 0x81;
5467 i386_emit_membase((basereg),(disp),(opc));
5468 i386_emit_imm32((imm));
5473 void i386_test_reg_reg(s4 reg, s4 dreg) {
5474 *(mcodeptr++) = (u1) 0x85;
5475 i386_emit_reg((reg),(dreg));
5479 void i386_test_imm_reg(s4 imm, s4 reg) {
5480 *(mcodeptr++) = (u1) 0xf7;
5481 i386_emit_reg(0,(reg));
5482 i386_emit_imm32((imm));
5488 * inc, dec operations
5490 void i386_inc_reg(s4 reg) {
5491 *(mcodeptr++) = (u1) 0x40 + ((reg) & 0x07);
5495 void i386_inc_membase(s4 basereg, s4 disp) {
5496 *(mcodeptr++) = (u1) 0xff;
5497 i386_emit_membase((basereg),(disp),0);
5501 void i386_dec_reg(s4 reg) {
5502 *(mcodeptr++) = (u1) 0x48 + ((reg) & 0x07);
5506 void i386_dec_membase(s4 basereg, s4 disp) {
5507 *(mcodeptr++) = (u1) 0xff;
5508 i386_emit_membase((basereg),(disp),1);
5512 void i386_dec_mem(s4 mem) {
5513 *(mcodeptr++) = (u1) 0xff;
5514 i386_emit_mem(1,(mem));
5520 *(mcodeptr++) = (u1) 0x99;
5525 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5526 *(mcodeptr++) = (u1) 0x0f;
5527 *(mcodeptr++) = (u1) 0xaf;
5528 i386_emit_reg((dreg),(reg));
5532 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5533 *(mcodeptr++) = (u1) 0x0f;
5534 *(mcodeptr++) = (u1) 0xaf;
5535 i386_emit_membase((basereg),(disp),(dreg));
5539 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5540 if (i386_is_imm8((imm))) {
5541 *(mcodeptr++) = (u1) 0x6b;
5542 i386_emit_reg(0,(dreg));
5543 i386_emit_imm8((imm));
5545 *(mcodeptr++) = (u1) 0x69;
5546 i386_emit_reg(0,(dreg));
5547 i386_emit_imm32((imm));
5552 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5553 if (i386_is_imm8((imm))) {
5554 *(mcodeptr++) = (u1) 0x6b;
5555 i386_emit_reg((dreg),(reg));
5556 i386_emit_imm8((imm));
5558 *(mcodeptr++) = (u1) 0x69;
5559 i386_emit_reg((dreg),(reg));
5560 i386_emit_imm32((imm));
5565 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5566 if (i386_is_imm8((imm))) {
5567 *(mcodeptr++) = (u1) 0x6b;
5568 i386_emit_membase((basereg),(disp),(dreg));
5569 i386_emit_imm8((imm));
5571 *(mcodeptr++) = (u1) 0x69;
5572 i386_emit_membase((basereg),(disp),(dreg));
5573 i386_emit_imm32((imm));
5578 void i386_mul_membase(s4 basereg, s4 disp) {
5579 *(mcodeptr++) = (u1) 0xf7;
5580 i386_emit_membase((basereg),(disp),4);
5584 void i386_idiv_reg(s4 reg) {
5585 *(mcodeptr++) = (u1) 0xf7;
5586 i386_emit_reg(7,(reg));
5592 *(mcodeptr++) = (u1) 0xc3;
5600 void i386_shift_reg(s4 opc, s4 reg) {
5601 *(mcodeptr++) = (u1) 0xd3;
5602 i386_emit_reg((opc),(reg));
5606 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5607 *(mcodeptr++) = (u1) 0xd3;
5608 i386_emit_membase((basereg),(disp),(opc));
5612 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5614 *(mcodeptr++) = (u1) 0xd1;
5615 i386_emit_reg((opc),(dreg));
5617 *(mcodeptr++) = (u1) 0xc1;
5618 i386_emit_reg((opc),(dreg));
5619 i386_emit_imm8((imm));
5624 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5626 *(mcodeptr++) = (u1) 0xd1;
5627 i386_emit_membase((basereg),(disp),(opc));
5629 *(mcodeptr++) = (u1) 0xc1;
5630 i386_emit_membase((basereg),(disp),(opc));
5631 i386_emit_imm8((imm));
5636 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5637 *(mcodeptr++) = (u1) 0x0f;
5638 *(mcodeptr++) = (u1) 0xa5;
5639 i386_emit_reg((reg),(dreg));
5643 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5644 *(mcodeptr++) = (u1) 0x0f;
5645 *(mcodeptr++) = (u1) 0xa4;
5646 i386_emit_reg((reg),(dreg));
5647 i386_emit_imm8((imm));
5651 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5652 *(mcodeptr++) = (u1) 0x0f;
5653 *(mcodeptr++) = (u1) 0xa5;
5654 i386_emit_membase((basereg),(disp),(reg));
5658 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5659 *(mcodeptr++) = (u1) 0x0f;
5660 *(mcodeptr++) = (u1) 0xad;
5661 i386_emit_reg((reg),(dreg));
5665 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5666 *(mcodeptr++) = (u1) 0x0f;
5667 *(mcodeptr++) = (u1) 0xac;
5668 i386_emit_reg((reg),(dreg));
5669 i386_emit_imm8((imm));
5673 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5674 *(mcodeptr++) = (u1) 0x0f;
5675 *(mcodeptr++) = (u1) 0xad;
5676 i386_emit_membase((basereg),(disp),(reg));
5684 void i386_jmp_imm(s4 imm) {
5685 *(mcodeptr++) = (u1) 0xe9;
5686 i386_emit_imm32((imm));
5690 void i386_jmp_reg(s4 reg) {
5691 *(mcodeptr++) = (u1) 0xff;
5692 i386_emit_reg(4,(reg));
5696 void i386_jcc(s4 opc, s4 imm) {
5697 *(mcodeptr++) = (u1) 0x0f;
5698 *(mcodeptr++) = (u1) (0x80 + (opc));
5699 i386_emit_imm32((imm));
5705 * conditional set operations
5707 void i386_setcc_reg(s4 opc, s4 reg) {
5708 *(mcodeptr++) = (u1) 0x0f;
5709 *(mcodeptr++) = (u1) (0x90 + (opc));
5710 i386_emit_reg(0,(reg));
5714 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5715 *(mcodeptr++) = (u1) 0x0f;
5716 *(mcodeptr++) = (u1) (0x90 + (opc));
5717 i386_emit_membase((basereg),(disp),0);
5721 void i386_xadd_reg_mem(s4 reg, s4 mem) {
5722 *(mcodeptr++) = (u1) 0x0f;
5723 *(mcodeptr++) = (u1) 0xc1;
5724 i386_emit_mem((reg),(mem));
5728 void i386_neg_reg(s4 reg) {
5729 *(mcodeptr++) = (u1) 0xf7;
5730 i386_emit_reg(3,(reg));
5734 void i386_neg_membase(s4 basereg, s4 disp) {
5735 *(mcodeptr++) = (u1) 0xf7;
5736 i386_emit_membase((basereg),(disp),3);
5741 void i386_push_imm(s4 imm) {
5742 *(mcodeptr++) = (u1) 0x68;
5743 i386_emit_imm32((imm));
5747 void i386_pop_reg(s4 reg) {
5748 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5752 void i386_push_reg(s4 reg) {
5753 *(mcodeptr++) = (u1) 0x50 + (0x07 & (reg));
5758 *(mcodeptr++) = (u1) 0x90;
5763 *(mcodeptr++) = (u1) 0xf0;
5770 void i386_call_reg(s4 reg) {
5771 *(mcodeptr++) = (u1) 0xff;
5772 i386_emit_reg(2,(reg));
5776 void i386_call_imm(s4 imm) {
5777 *(mcodeptr++) = (u1) 0xe8;
5778 i386_emit_imm32((imm));
5782 void i386_call_mem(s4 mem) {
5783 *(mcodeptr++) = (u1) 0xff;
5784 i386_emit_mem(2, (mem));
5790 * floating point instructions
5793 *(mcodeptr++) = (u1) 0xd9;
5794 *(mcodeptr++) = (u1) 0xe8;
5799 *(mcodeptr++) = (u1) 0xd9;
5800 *(mcodeptr++) = (u1) 0xee;
5804 void i386_fld_reg(s4 reg) {
5805 *(mcodeptr++) = (u1) 0xd9;
5806 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5810 void i386_flds_membase(s4 basereg, s4 disp) {
5811 *(mcodeptr++) = (u1) 0xd9;
5812 i386_emit_membase((basereg),(disp),0);
5816 void i386_fldl_membase(s4 basereg, s4 disp) {
5817 *(mcodeptr++) = (u1) 0xdd;
5818 i386_emit_membase((basereg),(disp),0);
5822 void i386_fldt_membase(s4 basereg, s4 disp) {
5823 *(mcodeptr++) = (u1) 0xdb;
5824 i386_emit_membase((basereg),(disp),5);
5828 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5829 *(mcodeptr++) = (u1) 0xd9;
5830 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5834 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5835 *(mcodeptr++) = (u1) 0xdd;
5836 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5842 void i386_fildl_membase(s4 basereg, s4 disp) {
5843 *(mcodeptr++) = (u1) 0xdb;
5844 i386_emit_membase((basereg),(disp),0);
5848 void i386_fildll_membase(s4 basereg, s4 disp) {
5849 *(mcodeptr++) = (u1) 0xdf;
5850 i386_emit_membase((basereg),(disp),5);
5856 void i386_fst_reg(s4 reg) {
5857 *(mcodeptr++) = (u1) 0xdd;
5858 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5862 void i386_fsts_membase(s4 basereg, s4 disp) {
5863 *(mcodeptr++) = (u1) 0xd9;
5864 i386_emit_membase((basereg),(disp),2);
5868 void i386_fstl_membase(s4 basereg, s4 disp) {
5869 *(mcodeptr++) = (u1) 0xdd;
5870 i386_emit_membase((basereg),(disp),2);
5874 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5875 *(mcodeptr++) = (u1) 0xd9;
5876 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5880 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5881 *(mcodeptr++) = (u1) 0xdd;
5882 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5886 void i386_fstp_reg(s4 reg) {
5887 *(mcodeptr++) = (u1) 0xdd;
5888 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5892 void i386_fstps_membase(s4 basereg, s4 disp) {
5893 *(mcodeptr++) = (u1) 0xd9;
5894 i386_emit_membase((basereg),(disp),3);
5898 void i386_fstpl_membase(s4 basereg, s4 disp) {
5899 *(mcodeptr++) = (u1) 0xdd;
5900 i386_emit_membase((basereg),(disp),3);
5904 void i386_fstpt_membase(s4 basereg, s4 disp) {
5905 *(mcodeptr++) = (u1) 0xdb;
5906 i386_emit_membase((basereg),(disp),7);
5910 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5911 *(mcodeptr++) = (u1) 0xd9;
5912 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5916 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5917 *(mcodeptr++) = (u1) 0xdd;
5918 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5922 void i386_fistl_membase(s4 basereg, s4 disp) {
5923 *(mcodeptr++) = (u1) 0xdb;
5924 i386_emit_membase((basereg),(disp),2);
5928 void i386_fistpl_membase(s4 basereg, s4 disp) {
5929 *(mcodeptr++) = (u1) 0xdb;
5930 i386_emit_membase((basereg),(disp),3);
5934 void i386_fistpll_membase(s4 basereg, s4 disp) {
5935 *(mcodeptr++) = (u1) 0xdf;
5936 i386_emit_membase((basereg),(disp),7);
5941 *(mcodeptr++) = (u1) 0xd9;
5942 *(mcodeptr++) = (u1) 0xe0;
5947 *(mcodeptr++) = (u1) 0xde;
5948 *(mcodeptr++) = (u1) 0xc1;
5952 void i386_fadd_reg_st(s4 reg) {
5953 *(mcodeptr++) = (u1) 0xd8;
5954 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5958 void i386_fadd_st_reg(s4 reg) {
5959 *(mcodeptr++) = (u1) 0xdc;
5960 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5964 void i386_faddp_st_reg(s4 reg) {
5965 *(mcodeptr++) = (u1) 0xde;
5966 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
5970 void i386_fadds_membase(s4 basereg, s4 disp) {
5971 *(mcodeptr++) = (u1) 0xd8;
5972 i386_emit_membase((basereg),(disp),0);
5976 void i386_faddl_membase(s4 basereg, s4 disp) {
5977 *(mcodeptr++) = (u1) 0xdc;
5978 i386_emit_membase((basereg),(disp),0);
5982 void i386_fsub_reg_st(s4 reg) {
5983 *(mcodeptr++) = (u1) 0xd8;
5984 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
5988 void i386_fsub_st_reg(s4 reg) {
5989 *(mcodeptr++) = (u1) 0xdc;
5990 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
5994 void i386_fsubp_st_reg(s4 reg) {
5995 *(mcodeptr++) = (u1) 0xde;
5996 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6001 *(mcodeptr++) = (u1) 0xde;
6002 *(mcodeptr++) = (u1) 0xe9;
6006 void i386_fsubs_membase(s4 basereg, s4 disp) {
6007 *(mcodeptr++) = (u1) 0xd8;
6008 i386_emit_membase((basereg),(disp),4);
6012 void i386_fsubl_membase(s4 basereg, s4 disp) {
6013 *(mcodeptr++) = (u1) 0xdc;
6014 i386_emit_membase((basereg),(disp),4);
6018 void i386_fmul_reg_st(s4 reg) {
6019 *(mcodeptr++) = (u1) 0xd8;
6020 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6024 void i386_fmul_st_reg(s4 reg) {
6025 *(mcodeptr++) = (u1) 0xdc;
6026 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6031 *(mcodeptr++) = (u1) 0xde;
6032 *(mcodeptr++) = (u1) 0xc9;
6036 void i386_fmulp_st_reg(s4 reg) {
6037 *(mcodeptr++) = (u1) 0xde;
6038 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6042 void i386_fmuls_membase(s4 basereg, s4 disp) {
6043 *(mcodeptr++) = (u1) 0xd8;
6044 i386_emit_membase((basereg),(disp),1);
6048 void i386_fmull_membase(s4 basereg, s4 disp) {
6049 *(mcodeptr++) = (u1) 0xdc;
6050 i386_emit_membase((basereg),(disp),1);
6054 void i386_fdiv_reg_st(s4 reg) {
6055 *(mcodeptr++) = (u1) 0xd8;
6056 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
6060 void i386_fdiv_st_reg(s4 reg) {
6061 *(mcodeptr++) = (u1) 0xdc;
6062 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
6067 *(mcodeptr++) = (u1) 0xde;
6068 *(mcodeptr++) = (u1) 0xf9;
6072 void i386_fdivp_st_reg(s4 reg) {
6073 *(mcodeptr++) = (u1) 0xde;
6074 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
6079 *(mcodeptr++) = (u1) 0xd9;
6080 *(mcodeptr++) = (u1) 0xc9;
6084 void i386_fxch_reg(s4 reg) {
6085 *(mcodeptr++) = (u1) 0xd9;
6086 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6091 *(mcodeptr++) = (u1) 0xd9;
6092 *(mcodeptr++) = (u1) 0xf8;
6096 void i386_fprem1() {
6097 *(mcodeptr++) = (u1) 0xd9;
6098 *(mcodeptr++) = (u1) 0xf5;
6103 *(mcodeptr++) = (u1) 0xdd;
6104 *(mcodeptr++) = (u1) 0xe1;
6108 void i386_fucom_reg(s4 reg) {
6109 *(mcodeptr++) = (u1) 0xdd;
6110 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
6114 void i386_fucomp_reg(s4 reg) {
6115 *(mcodeptr++) = (u1) 0xdd;
6116 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6120 void i386_fucompp() {
6121 *(mcodeptr++) = (u1) 0xda;
6122 *(mcodeptr++) = (u1) 0xe9;
6126 void i386_fnstsw() {
6127 *(mcodeptr++) = (u1) 0xdf;
6128 *(mcodeptr++) = (u1) 0xe0;
6133 *(mcodeptr++) = (u1) 0x9e;
6138 *(mcodeptr++) = (u1) 0x9b;
6139 *(mcodeptr++) = (u1) 0xdb;
6140 *(mcodeptr++) = (u1) 0xe3;
6144 void i386_fldcw_mem(s4 mem) {
6145 *(mcodeptr++) = (u1) 0xd9;
6146 i386_emit_mem(5,(mem));
6150 void i386_fldcw_membase(s4 basereg, s4 disp) {
6151 *(mcodeptr++) = (u1) 0xd9;
6152 i386_emit_membase((basereg),(disp),5);
6157 *(mcodeptr++) = (u1) 0x9b;
6161 void i386_ffree_reg(s4 reg) {
6162 *(mcodeptr++) = (u1) 0xdd;
6163 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
6167 void i386_fdecstp() {
6168 *(mcodeptr++) = (u1) 0xd9;
6169 *(mcodeptr++) = (u1) 0xf6;
6173 void i386_fincstp() {
6174 *(mcodeptr++) = (u1) 0xd9;
6175 *(mcodeptr++) = (u1) 0xf7;
6180 * These are local overrides for various environment variables in Emacs.
6181 * Please do not remove this and leave it at the end of the file, where
6182 * Emacs will automagically detect them.
6183 * ---------------------------------------------------------------------
6186 * indent-tabs-mode: t