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 1020 2004-04-20 21:12:57Z stefan $
49 #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 */
340 /* is exception initialized? */
341 if (!proto_java_lang_NullPointerException) {
342 proto_java_lang_NullPointerException =
343 new_exception(string_java_lang_NullPointerException);
346 sigctx->eax = (s4) proto_java_lang_NullPointerException; /* REG_ITMP1_XPTR */
347 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
348 sigctx->eip = (s4) asm_handle_exception;
353 /* faultaddr += (long) ((instr << 16) >> 16); */
354 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
355 /* panic("Stack overflow"); */
360 /* ArithmeticException signal handler for hardware divide by zero check */
362 void catch_ArithmeticException(int sig)
366 void **_p = (void **) &sig;
367 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
368 java_objectheader *xptr;
370 /* Reset signal handler - necessary for SysV, does no harm for BSD */
372 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
374 sigaddset(&nsig, sig);
375 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
377 xptr = new_exception_message(string_java_lang_ArithmeticException,
378 string_java_lang_ArithmeticException_message);
380 sigctx->eax = (s4) xptr; /* REG_ITMP1_XPTR */
381 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
382 sigctx->eip = (s4) asm_handle_exception;
388 void init_exceptions(void)
390 /* install signal handlers we need to convert to exceptions */
394 signal(SIGSEGV, (void *) catch_NullPointerException);
398 signal(SIGBUS, (void *) catch_NullPointerException);
402 signal(SIGFPE, (void *) catch_ArithmeticException);
406 /* function gen_mcode **********************************************************
408 generates machine code
410 *******************************************************************************/
412 /* global code generation pointer */
417 int len, s1, s2, s3, d;
424 int fpu_st_offset = 0;
433 /* space to save used callee saved registers */
435 savedregs_num += (savintregcnt - maxsavintreguse);
436 savedregs_num += (savfltregcnt - maxsavfltreguse);
438 parentargs_base = maxmemuse + savedregs_num;
440 #ifdef USE_THREADS /* space to save argument of monitor_enter */
442 if (checksync && (method->flags & ACC_SYNCHRONIZED))
447 /* create method header */
449 (void) dseg_addaddress(method); /* MethodPointer */
450 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
454 /* IsSync contains the offset relative to the stack pointer for the
455 argument of monitor_exit used in the exception handler. Since the
456 offset could be zero and give a wrong meaning of the flag it is
460 if (checksync && (method->flags & ACC_SYNCHRONIZED))
461 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
466 (void) dseg_adds4(0); /* IsSync */
468 (void) dseg_adds4(isleafmethod); /* IsLeaf */
469 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
470 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
471 (void) dseg_addlinenumbertablesize(); /* adds a reference for the length of the line number counter
472 We don't know the size yet, since we evaluate the information
473 during code generation, to save one additional iteration over
474 the whole instructions. During code optimization the position
475 could have changed to the information gotten from the class file*/
476 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
478 /* create exception table */
480 for (ex = extable; ex != NULL; ex = ex->down) {
483 if (ex->start != NULL)
484 printf("adding start - %d - ", ex->start->debug_nr);
486 printf("PANIC - start is NULL");
491 dseg_addtarget(ex->start);
495 printf("adding end - %d - ", ex->end->debug_nr);
497 printf("PANIC - end is NULL");
502 dseg_addtarget(ex->end);
505 if (ex->handler != NULL)
506 printf("adding handler - %d\n", ex->handler->debug_nr);
508 printf("PANIC - handler is NULL");
513 dseg_addtarget(ex->handler);
515 (void) dseg_addaddress(ex->catchtype);
520 /* initialize mcode variables */
522 mcodeptr = (u1*) mcodebase;
523 mcodeend = (s4*) (mcodebase + mcodesize);
524 MCODECHECK(128 + mparamcount);
526 /* create stack frame (if necessary) */
528 if (parentargs_base) {
529 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
532 /* save return address and used callee saved registers */
535 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
536 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
538 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
539 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
542 /* save monitorenter argument */
545 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
546 if (method->flags & ACC_STATIC) {
547 i386_mov_imm_reg((s4) class, REG_ITMP1);
548 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
551 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
552 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
557 /* copy argument registers to stack and call trace function with pointer
558 to arguments on stack.
562 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
564 for (p = 0; p < mparamcount; p++) {
566 if (IS_INT_LNG_TYPE(t)) {
567 if (IS_2_WORD_TYPE(t)) {
568 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
569 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
570 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
571 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
573 } else if (t == TYPE_ADR) {
574 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
575 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
576 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
577 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
580 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX);
582 i386_mov_reg_membase(EAX, REG_SP, p * 8);
583 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
588 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
589 i386_fstps_membase(REG_SP, p * 8);
590 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
591 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
594 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
595 i386_fstpl_membase(REG_SP, p * 8);
600 /* fill up the remaining arguments */
601 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
602 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
603 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
604 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
607 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
609 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
610 /* i386_mov_imm_reg(asm_builtin_trace, REG_ITMP1); */
611 i386_call_reg(REG_ITMP1);
613 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
616 /* take arguments out of register or stack frame */
618 for (p = 0, l = 0; p < mparamcount; p++) {
620 var = &(locals[l][t]);
622 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
627 if (IS_INT_LNG_TYPE(t)) { /* integer args */
628 if (p < intreg_argnum) { /* register arguments */
629 panic("integer register argument");
630 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
631 /* M_INTMOVE (argintregs[p], r); */
633 } else { /* reg arg -> spilled */
634 /* M_LST (argintregs[p], REG_SP, 8 * r); */
636 } else { /* stack arguments */
637 pa = p - intreg_argnum;
638 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
639 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
640 } else { /* stack arg -> spilled */
641 if (!IS_2_WORD_TYPE(t)) {
642 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
643 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
646 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
647 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP2); /* + 4 for return address */
648 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
649 i386_mov_reg_membase(REG_ITMP2, REG_SP, r * 8 + 4);
654 } else { /* floating args */
655 if (p < fltreg_argnum) { /* register arguments */
656 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
657 panic("There are no float argument registers!");
659 } else { /* reg arg -> spilled */
660 panic("There are no float argument registers!");
663 } else { /* stack arguments */
664 pa = p - fltreg_argnum;
665 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
667 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
669 i386_fstp_reg(r + fpu_st_offset);
673 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
675 i386_fstp_reg(r + fpu_st_offset);
679 } else { /* stack-arg -> spilled */
680 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
681 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
683 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
684 i386_fstps_membase(REG_SP, r * 8);
687 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
688 i386_fstpl_membase(REG_SP, r * 8);
695 /* call monitorenter function */
698 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
699 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
700 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
701 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
702 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP2);
703 i386_call_reg(REG_ITMP2);
704 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
709 /* end of header generation */
711 /* walk through all basic blocks */
712 for (bptr = block; bptr != NULL; bptr = bptr->next) {
714 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
716 if (bptr->flags >= BBREACHED) {
718 /* branch resolving */
721 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
722 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
723 brefs->branchpos, bptr->mpc);
726 /* copy interface registers to their destination */
731 while (src != NULL) {
733 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
734 if (!IS_2_WORD_TYPE(src->type)) {
735 if (bptr->type == BBTYPE_SBR) {
736 d = reg_of_var(src, REG_ITMP1);
738 store_reg_to_var_int(src, d);
740 } else if (bptr->type == BBTYPE_EXH) {
741 d = reg_of_var(src, REG_ITMP1);
742 M_INTMOVE(REG_ITMP1, d);
743 store_reg_to_var_int(src, d);
747 panic("copy interface registers: longs have to me in memory (begin 1)");
751 d = reg_of_var(src, REG_ITMP1);
752 if ((src->varkind != STACKVAR)) {
754 if (IS_FLT_DBL_TYPE(s2)) {
755 s1 = interfaces[len][s2].regoff;
756 if (!(interfaces[len][s2].flags & INMEMORY)) {
760 if (s2 == TYPE_FLT) {
761 i386_flds_membase(REG_SP, s1 * 8);
764 i386_fldl_membase(REG_SP, s1 * 8);
767 store_reg_to_var_flt(src, d);
770 s1 = interfaces[len][s2].regoff;
771 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
772 if (!(interfaces[len][s2].flags & INMEMORY)) {
776 i386_mov_membase_reg(REG_SP, s1 * 8, d);
778 store_reg_to_var_int(src, d);
781 if (interfaces[len][s2].flags & INMEMORY) {
782 M_LNGMEMMOVE(s1, src->regoff);
785 panic("copy interface registers: longs have to be in memory (begin 2)");
794 /* walk through all instructions */
798 for (iptr = bptr->iinstr;
800 src = iptr->dst, len--, iptr++) {
802 if (iptr->line!=currentline) {
803 dseg_addlinenumber(iptr->line,mcodeptr);
804 currentline=iptr->line;
806 MCODECHECK(64); /* an instruction usually needs < 64 words */
809 case ICMD_NOP: /* ... ==> ... */
812 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
813 if (src->flags & INMEMORY) {
814 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
817 i386_test_reg_reg(src->regoff, src->regoff);
819 i386_jcc(I386_CC_E, 0);
820 codegen_addxnullrefs(mcodeptr);
823 /* constant operations ************************************************/
825 case ICMD_ICONST: /* ... ==> ..., constant */
826 /* op1 = 0, val.i = constant */
828 d = reg_of_var(iptr->dst, REG_ITMP1);
829 if (iptr->dst->flags & INMEMORY) {
830 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
833 if (iptr->val.i == 0) {
834 i386_alu_reg_reg(I386_XOR, d, d);
837 i386_mov_imm_reg(iptr->val.i, d);
842 case ICMD_LCONST: /* ... ==> ..., constant */
843 /* op1 = 0, val.l = constant */
845 d = reg_of_var(iptr->dst, REG_ITMP1);
846 if (iptr->dst->flags & INMEMORY) {
847 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
848 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
851 panic("LCONST: longs have to be in memory");
855 case ICMD_FCONST: /* ... ==> ..., constant */
856 /* op1 = 0, val.f = constant */
858 d = reg_of_var(iptr->dst, REG_FTMP1);
859 if (iptr->val.f == 0.0) {
864 if (iptr->val.i == 0x80000000) {
868 } else if (iptr->val.f == 1.0) {
872 } else if (iptr->val.f == 2.0) {
879 a = dseg_addfloat(iptr->val.f);
880 i386_mov_imm_reg(0, REG_ITMP1);
881 dseg_adddata(mcodeptr);
882 i386_flds_membase(REG_ITMP1, a);
885 store_reg_to_var_flt(iptr->dst, d);
888 case ICMD_DCONST: /* ... ==> ..., constant */
889 /* op1 = 0, val.d = constant */
891 d = reg_of_var(iptr->dst, REG_FTMP1);
892 if (iptr->val.d == 0.0) {
897 if (iptr->val.l == 0x8000000000000000LL) {
901 } else if (iptr->val.d == 1.0) {
905 } else if (iptr->val.d == 2.0) {
912 a = dseg_adddouble(iptr->val.d);
913 i386_mov_imm_reg(0, REG_ITMP1);
914 dseg_adddata(mcodeptr);
915 i386_fldl_membase(REG_ITMP1, a);
918 store_reg_to_var_flt(iptr->dst, d);
921 case ICMD_ACONST: /* ... ==> ..., constant */
922 /* op1 = 0, val.a = constant */
924 d = reg_of_var(iptr->dst, REG_ITMP1);
925 if (iptr->dst->flags & INMEMORY) {
926 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
929 if ((s4) iptr->val.a == 0) {
930 i386_alu_reg_reg(I386_XOR, d, d);
933 i386_mov_imm_reg((s4) iptr->val.a, d);
939 /* load/store operations **********************************************/
941 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
942 case ICMD_ALOAD: /* op1 = local variable */
944 d = reg_of_var(iptr->dst, REG_ITMP1);
945 if ((iptr->dst->varkind == LOCALVAR) &&
946 (iptr->dst->varnum == iptr->op1)) {
949 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
950 if (iptr->dst->flags & INMEMORY) {
951 if (var->flags & INMEMORY) {
952 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
953 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
956 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
960 if (var->flags & INMEMORY) {
961 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
964 M_INTMOVE(var->regoff, iptr->dst->regoff);
969 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
970 /* op1 = local variable */
972 d = reg_of_var(iptr->dst, REG_ITMP1);
973 if ((iptr->dst->varkind == LOCALVAR) &&
974 (iptr->dst->varnum == iptr->op1)) {
977 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
978 if (iptr->dst->flags & INMEMORY) {
979 if (var->flags & INMEMORY) {
980 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
983 panic("LLOAD: longs have to be in memory");
987 panic("LLOAD: longs have to be in memory");
991 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
992 /* op1 = local variable */
994 d = reg_of_var(iptr->dst, REG_FTMP1);
995 if ((iptr->dst->varkind == LOCALVAR) &&
996 (iptr->dst->varnum == iptr->op1)) {
999 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
1000 if (var->flags & INMEMORY) {
1001 i386_flds_membase(REG_SP, var->regoff * 8);
1004 i386_fld_reg(var->regoff + fpu_st_offset);
1007 store_reg_to_var_flt(iptr->dst, d);
1010 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
1011 /* op1 = local variable */
1013 d = reg_of_var(iptr->dst, REG_FTMP1);
1014 if ((iptr->dst->varkind == LOCALVAR) &&
1015 (iptr->dst->varnum == iptr->op1)) {
1018 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
1019 if (var->flags & INMEMORY) {
1020 i386_fldl_membase(REG_SP, var->regoff * 8);
1023 i386_fld_reg(var->regoff + fpu_st_offset);
1026 store_reg_to_var_flt(iptr->dst, d);
1029 case ICMD_ISTORE: /* ..., value ==> ... */
1030 case ICMD_ASTORE: /* op1 = local variable */
1032 if ((src->varkind == LOCALVAR) &&
1033 (src->varnum == iptr->op1)) {
1036 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1037 if (var->flags & INMEMORY) {
1038 if (src->flags & INMEMORY) {
1039 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1040 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
1043 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
1047 var_to_reg_int(s1, src, var->regoff);
1048 M_INTMOVE(s1, var->regoff);
1052 case ICMD_LSTORE: /* ..., value ==> ... */
1053 /* op1 = local variable */
1055 if ((src->varkind == LOCALVAR) &&
1056 (src->varnum == iptr->op1)) {
1059 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1060 if (var->flags & INMEMORY) {
1061 if (src->flags & INMEMORY) {
1062 M_LNGMEMMOVE(src->regoff, var->regoff);
1065 panic("LSTORE: longs have to be in memory");
1069 panic("LSTORE: longs have to be in memory");
1073 case ICMD_FSTORE: /* ..., value ==> ... */
1074 /* op1 = local variable */
1076 if ((src->varkind == LOCALVAR) &&
1077 (src->varnum == iptr->op1)) {
1080 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1081 if (var->flags & INMEMORY) {
1082 var_to_reg_flt(s1, src, REG_FTMP1);
1083 i386_fstps_membase(REG_SP, var->regoff * 8);
1086 var_to_reg_flt(s1, src, var->regoff);
1087 /* M_FLTMOVE(s1, var->regoff); */
1088 i386_fstp_reg(var->regoff + fpu_st_offset);
1093 case ICMD_DSTORE: /* ..., value ==> ... */
1094 /* op1 = local variable */
1096 if ((src->varkind == LOCALVAR) &&
1097 (src->varnum == iptr->op1)) {
1100 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1101 if (var->flags & INMEMORY) {
1102 var_to_reg_flt(s1, src, REG_FTMP1);
1103 i386_fstpl_membase(REG_SP, var->regoff * 8);
1106 var_to_reg_flt(s1, src, var->regoff);
1107 /* M_FLTMOVE(s1, var->regoff); */
1108 i386_fstp_reg(var->regoff + fpu_st_offset);
1114 /* pop/dup/swap operations ********************************************/
1116 /* attention: double and longs are only one entry in CACAO ICMDs */
1118 case ICMD_POP: /* ..., value ==> ... */
1119 case ICMD_POP2: /* ..., value, value ==> ... */
1122 #define M_COPY(from,to) \
1123 d = reg_of_var(to, REG_ITMP1); \
1124 if ((from->regoff != to->regoff) || \
1125 ((from->flags ^ to->flags) & INMEMORY)) { \
1126 if (IS_FLT_DBL_TYPE(from->type)) { \
1127 var_to_reg_flt(s1, from, d); \
1128 /* M_FLTMOVE(s1, d);*/ \
1129 store_reg_to_var_flt(to, d); \
1131 if (!IS_2_WORD_TYPE(from->type)) { \
1132 if (to->flags & INMEMORY) { \
1133 if (from->flags & INMEMORY) { \
1134 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1135 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1137 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1140 if (from->flags & INMEMORY) { \
1141 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1143 i386_mov_reg_reg(from->regoff, to->regoff); \
1147 M_LNGMEMMOVE(from->regoff, to->regoff); \
1152 case ICMD_DUP: /* ..., a ==> ..., a, a */
1153 M_COPY(src, iptr->dst);
1156 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1158 M_COPY(src, iptr->dst->prev->prev);
1160 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1162 M_COPY(src, iptr->dst);
1163 M_COPY(src->prev, iptr->dst->prev);
1166 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1168 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1170 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1172 M_COPY(src, iptr->dst);
1173 M_COPY(src->prev, iptr->dst->prev);
1174 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1175 M_COPY(src, iptr->dst->prev->prev->prev);
1178 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1180 M_COPY(src, iptr->dst);
1181 M_COPY(src->prev, iptr->dst->prev);
1182 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1183 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1184 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1185 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1188 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1190 M_COPY(src, iptr->dst->prev);
1191 M_COPY(src->prev, iptr->dst);
1195 /* integer operations *************************************************/
1197 case ICMD_INEG: /* ..., value ==> ..., - value */
1199 d = reg_of_var(iptr->dst, REG_NULL);
1200 if (iptr->dst->flags & INMEMORY) {
1201 if (src->flags & INMEMORY) {
1202 if (src->regoff == iptr->dst->regoff) {
1203 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1206 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1207 i386_neg_reg(REG_ITMP1);
1208 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1212 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1213 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1217 if (src->flags & INMEMORY) {
1218 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1219 i386_neg_reg(iptr->dst->regoff);
1222 M_INTMOVE(src->regoff, iptr->dst->regoff);
1223 i386_neg_reg(iptr->dst->regoff);
1228 case ICMD_LNEG: /* ..., value ==> ..., - value */
1230 d = reg_of_var(iptr->dst, REG_NULL);
1231 if (iptr->dst->flags & INMEMORY) {
1232 if (src->flags & INMEMORY) {
1233 if (src->regoff == iptr->dst->regoff) {
1234 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1235 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1236 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1239 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1240 i386_neg_reg(REG_ITMP1);
1241 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1242 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1243 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP1);
1244 i386_neg_reg(REG_ITMP1);
1245 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1251 case ICMD_I2L: /* ..., value ==> ..., value */
1253 d = reg_of_var(iptr->dst, REG_NULL);
1254 if (iptr->dst->flags & INMEMORY) {
1255 if (src->flags & INMEMORY) {
1256 i386_mov_membase_reg(REG_SP, src->regoff * 8, EAX);
1258 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1259 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1262 M_INTMOVE(src->regoff, EAX);
1264 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1265 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1270 case ICMD_L2I: /* ..., value ==> ..., value */
1272 d = reg_of_var(iptr->dst, REG_NULL);
1273 if (iptr->dst->flags & INMEMORY) {
1274 if (src->flags & INMEMORY) {
1275 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1276 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1280 if (src->flags & INMEMORY) {
1281 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1286 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1288 d = reg_of_var(iptr->dst, REG_NULL);
1289 if (iptr->dst->flags & INMEMORY) {
1290 if (src->flags & INMEMORY) {
1291 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1292 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1293 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1294 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1297 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1298 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1299 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1303 if (src->flags & INMEMORY) {
1304 i386_mov_membase_reg(REG_SP, src->regoff * 8, 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);
1309 M_INTMOVE(src->regoff, iptr->dst->regoff);
1310 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1311 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1316 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1318 d = reg_of_var(iptr->dst, REG_NULL);
1319 if (iptr->dst->flags & INMEMORY) {
1320 if (src->flags & INMEMORY) {
1321 if (src->regoff == iptr->dst->regoff) {
1322 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1325 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1326 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1327 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1331 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1332 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1336 if (src->flags & INMEMORY) {
1337 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1338 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1341 M_INTMOVE(src->regoff, iptr->dst->regoff);
1342 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1347 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1349 d = reg_of_var(iptr->dst, REG_NULL);
1350 if (iptr->dst->flags & INMEMORY) {
1351 if (src->flags & INMEMORY) {
1352 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1353 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1354 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1355 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1358 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1359 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1360 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1364 if (src->flags & INMEMORY) {
1365 i386_mov_membase_reg(REG_SP, src->regoff * 8, 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);
1370 M_INTMOVE(src->regoff, iptr->dst->regoff);
1371 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1372 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1378 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1380 d = reg_of_var(iptr->dst, REG_NULL);
1381 i386_emit_ialu(I386_ADD, src, iptr);
1384 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1385 /* val.i = constant */
1387 d = reg_of_var(iptr->dst, REG_NULL);
1388 /* should we use a inc optimization for smaller code size? */
1389 i386_emit_ialuconst(I386_ADD, src, iptr);
1392 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1394 d = reg_of_var(iptr->dst, REG_NULL);
1395 if (iptr->dst->flags & INMEMORY) {
1396 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1397 if (src->regoff == iptr->dst->regoff) {
1398 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1399 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1400 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1401 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1403 } else if (src->prev->regoff == iptr->dst->regoff) {
1404 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1405 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1406 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1407 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1410 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1411 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1412 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1413 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1414 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1415 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1422 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1423 /* val.l = constant */
1425 d = reg_of_var(iptr->dst, REG_NULL);
1426 if (iptr->dst->flags & INMEMORY) {
1427 if (src->flags & INMEMORY) {
1428 if (src->regoff == iptr->dst->regoff) {
1429 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1430 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1433 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1434 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1435 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1436 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1437 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1438 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1444 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1446 d = reg_of_var(iptr->dst, REG_NULL);
1447 if (iptr->dst->flags & INMEMORY) {
1448 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1449 if (src->prev->regoff == iptr->dst->regoff) {
1450 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1451 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1454 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1455 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1456 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1459 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1460 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1461 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1462 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1464 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1465 if (src->prev->regoff == iptr->dst->regoff) {
1466 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1469 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1470 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1471 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1475 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1476 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1480 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1481 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1482 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1484 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1485 M_INTMOVE(src->prev->regoff, d);
1486 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1488 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1489 /* workaround for reg alloc */
1490 if (src->regoff == iptr->dst->regoff) {
1491 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1492 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1493 M_INTMOVE(REG_ITMP1, d);
1496 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1497 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1501 /* workaround for reg alloc */
1502 if (src->regoff == iptr->dst->regoff) {
1503 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1504 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1505 M_INTMOVE(REG_ITMP1, d);
1508 M_INTMOVE(src->prev->regoff, d);
1509 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1515 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1516 /* val.i = constant */
1518 d = reg_of_var(iptr->dst, REG_NULL);
1519 i386_emit_ialuconst(I386_SUB, src, iptr);
1522 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1524 d = reg_of_var(iptr->dst, REG_NULL);
1525 if (iptr->dst->flags & INMEMORY) {
1526 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1527 if (src->prev->regoff == iptr->dst->regoff) {
1528 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1529 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1530 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1531 i386_alu_reg_membase(I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1534 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1535 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1536 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1537 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1538 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1539 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1545 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1546 /* val.l = constant */
1548 d = reg_of_var(iptr->dst, REG_NULL);
1549 if (iptr->dst->flags & INMEMORY) {
1550 if (src->flags & INMEMORY) {
1551 if (src->regoff == iptr->dst->regoff) {
1552 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1553 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1556 /* TODO: could be size optimized with lea -- see gcc output */
1557 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1558 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1559 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1560 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1561 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1562 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1568 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1570 d = reg_of_var(iptr->dst, REG_NULL);
1571 if (iptr->dst->flags & INMEMORY) {
1572 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1573 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1574 i386_imul_membase_reg(REG_SP, src->regoff * 8, 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->regoff * 8, REG_ITMP1);
1579 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1580 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1582 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1583 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1584 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1585 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1588 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1589 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1590 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1594 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1595 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1596 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1598 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1599 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1600 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1602 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1603 M_INTMOVE(src->regoff, iptr->dst->regoff);
1604 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1607 if (src->regoff == iptr->dst->regoff) {
1608 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1611 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1612 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1618 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1619 /* val.i = constant */
1621 d = reg_of_var(iptr->dst, REG_NULL);
1622 if (iptr->dst->flags & INMEMORY) {
1623 if (src->flags & INMEMORY) {
1624 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1625 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1628 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1629 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1633 if (src->flags & INMEMORY) {
1634 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1637 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1642 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1644 d = reg_of_var(iptr->dst, REG_NULL);
1645 if (iptr->dst->flags & INMEMORY) {
1646 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1647 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX); /* mem -> EAX */
1648 /* optimize move EAX -> REG_ITMP3 is slower??? */
1649 /* i386_mov_reg_reg(EAX, REG_ITMP3); */
1650 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1652 /* TODO: optimize move EAX -> REG_ITMP3 */
1653 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem -> ITMP3 */
1654 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1655 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1657 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP2); /* mem -> ITMP3 */
1658 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1660 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1661 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1662 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1667 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1668 /* val.l = constant */
1670 d = reg_of_var(iptr->dst, REG_NULL);
1671 if (iptr->dst->flags & INMEMORY) {
1672 if (src->flags & INMEMORY) {
1673 i386_mov_imm_reg(iptr->val.l, EAX); /* imm -> EAX */
1674 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1675 /* TODO: optimize move EAX -> REG_ITMP3 */
1676 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2); /* imm -> ITMP3 */
1677 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1679 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1680 i386_mov_imm_reg(iptr->val.l, REG_ITMP2); /* imm -> ITMP3 */
1681 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1683 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1684 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1685 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1690 #define gen_div_check(v) \
1692 if ((v)->flags & INMEMORY) { \
1693 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1695 i386_test_reg_reg(src->regoff, src->regoff); \
1697 i386_jcc(I386_CC_E, 0); \
1698 codegen_addxdivrefs(mcodeptr); \
1701 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1703 d = reg_of_var(iptr->dst, REG_NULL);
1704 var_to_reg_int(s1, src, REG_ITMP2);
1706 if (src->prev->flags & INMEMORY) {
1707 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1710 M_INTMOVE(src->prev->regoff, EAX);
1713 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1714 i386_jcc(I386_CC_NE, 3 + 6);
1715 i386_alu_imm_reg(I386_CMP, -1, s1);
1716 i386_jcc(I386_CC_E, 1 + 2);
1721 if (iptr->dst->flags & INMEMORY) {
1722 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1725 M_INTMOVE(EAX, iptr->dst->regoff);
1729 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1731 d = reg_of_var(iptr->dst, REG_NULL);
1732 var_to_reg_int(s1, src, REG_ITMP2);
1734 if (src->prev->flags & INMEMORY) {
1735 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1738 M_INTMOVE(src->prev->regoff, EAX);
1741 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1742 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1743 i386_alu_reg_reg(I386_XOR, EDX, EDX);
1744 i386_alu_imm_reg(I386_CMP, -1, s1);
1745 i386_jcc(I386_CC_E, 1 + 2);
1750 if (iptr->dst->flags & INMEMORY) {
1751 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8);
1754 M_INTMOVE(EDX, iptr->dst->regoff);
1758 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1759 /* val.i = constant */
1761 /* TODO: optimize for `/ 2' */
1762 var_to_reg_int(s1, src, REG_ITMP1);
1763 d = reg_of_var(iptr->dst, REG_ITMP1);
1766 i386_test_reg_reg(d, d);
1768 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1769 i386_jcc(I386_CC_NS, a);
1770 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1772 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1773 store_reg_to_var_int(iptr->dst, d);
1776 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1777 /* val.i = constant */
1779 d = reg_of_var(iptr->dst, REG_NULL);
1780 if (iptr->dst->flags & INMEMORY) {
1781 if (src->flags & INMEMORY) {
1783 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1785 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1786 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1788 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1789 i386_jcc(I386_CC_NS, a);
1790 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1791 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1792 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1793 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1795 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1796 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1801 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1802 /* val.i = constant */
1804 var_to_reg_int(s1, src, REG_ITMP1);
1805 d = reg_of_var(iptr->dst, REG_ITMP2);
1807 M_INTMOVE(s1, REG_ITMP1);
1814 CALCIMMEDIATEBYTES(a, iptr->val.i);
1817 /* TODO: optimize */
1819 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1820 i386_test_reg_reg(s1, s1);
1821 i386_jcc(I386_CC_GE, a);
1822 i386_mov_reg_reg(s1, d);
1824 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1827 /* M_INTMOVE(s1, EAX); */
1829 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1830 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1831 /* i386_alu_reg_reg(I386_AND, iptr->val.i, EAX); */
1832 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1833 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1834 /* M_INTMOVE(EAX, d); */
1836 /* i386_alu_reg_reg(I386_XOR, d, d); */
1837 /* i386_mov_imm_reg(iptr->val.i, ECX); */
1838 /* i386_shrd_reg_reg(s1, d); */
1839 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1841 store_reg_to_var_int(iptr->dst, d);
1844 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1845 /* val.l = constant */
1847 d = reg_of_var(iptr->dst, REG_NULL);
1848 if (iptr->dst->flags & INMEMORY) {
1849 if (src->flags & INMEMORY) {
1850 /* Intel algorithm -- does not work, because constant is wrong */
1851 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1852 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1854 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1855 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1856 /* i386_jcc(I386_CC_NS, offset); */
1857 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1858 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1860 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1861 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1862 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1864 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1866 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1867 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1868 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1870 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1871 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1873 /* Alpha algorithm */
1875 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1877 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1883 /* TODO: hmm, don't know if this is always correct */
1885 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1887 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1893 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1894 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1896 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1897 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1898 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1899 i386_jcc(I386_CC_GE, a);
1901 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1902 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1904 i386_neg_reg(REG_ITMP1);
1905 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1906 i386_neg_reg(REG_ITMP2);
1908 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1909 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1911 i386_neg_reg(REG_ITMP1);
1912 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1913 i386_neg_reg(REG_ITMP2);
1915 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1916 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1921 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1923 d = reg_of_var(iptr->dst, REG_NULL);
1924 i386_emit_ishift(I386_SHL, src, iptr);
1927 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1928 /* val.i = constant */
1930 d = reg_of_var(iptr->dst, REG_NULL);
1931 i386_emit_ishiftconst(I386_SHL, src, iptr);
1934 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1936 d = reg_of_var(iptr->dst, REG_NULL);
1937 i386_emit_ishift(I386_SAR, src, iptr);
1940 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1941 /* val.i = constant */
1943 d = reg_of_var(iptr->dst, REG_NULL);
1944 i386_emit_ishiftconst(I386_SAR, src, iptr);
1947 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1949 d = reg_of_var(iptr->dst, REG_NULL);
1950 i386_emit_ishift(I386_SHR, src, iptr);
1953 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1954 /* val.i = constant */
1956 d = reg_of_var(iptr->dst, REG_NULL);
1957 i386_emit_ishiftconst(I386_SHR, src, iptr);
1960 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1962 d = reg_of_var(iptr->dst, REG_NULL);
1963 if (iptr->dst->flags & INMEMORY ){
1964 if (src->prev->flags & INMEMORY) {
1965 /* if (src->prev->regoff == iptr->dst->regoff) { */
1966 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1968 /* if (src->flags & INMEMORY) { */
1969 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
1971 /* M_INTMOVE(src->regoff, ECX); */
1974 /* i386_test_imm_reg(32, ECX); */
1975 /* i386_jcc(I386_CC_E, 2 + 2); */
1976 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1977 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1979 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1980 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1983 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1984 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1986 if (src->flags & INMEMORY) {
1987 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
1989 M_INTMOVE(src->regoff, ECX);
1992 i386_test_imm_reg(32, ECX);
1993 i386_jcc(I386_CC_E, 2 + 2);
1994 i386_mov_reg_reg(REG_ITMP1, REG_ITMP3);
1995 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1997 i386_shld_reg_reg(REG_ITMP1, REG_ITMP3);
1998 i386_shift_reg(I386_SHL, REG_ITMP1);
1999 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2000 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2006 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
2007 /* val.i = constant */
2009 d = reg_of_var(iptr->dst, REG_NULL);
2010 if (iptr->dst->flags & INMEMORY ) {
2011 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2012 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2014 if (iptr->val.i & 0x20) {
2015 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
2016 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2017 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2020 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2021 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2024 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2025 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2029 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2031 d = reg_of_var(iptr->dst, REG_NULL);
2032 if (iptr->dst->flags & INMEMORY ){
2033 if (src->prev->flags & INMEMORY) {
2034 /* if (src->prev->regoff == iptr->dst->regoff) { */
2035 /* TODO: optimize */
2036 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2037 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2039 /* if (src->flags & INMEMORY) { */
2040 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2042 /* M_INTMOVE(src->regoff, ECX); */
2045 /* i386_test_imm_reg(32, ECX); */
2046 /* i386_jcc(I386_CC_E, 2 + 3); */
2047 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2048 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2050 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2051 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2052 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2053 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2056 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2057 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2059 if (src->flags & INMEMORY) {
2060 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2062 M_INTMOVE(src->regoff, ECX);
2065 i386_test_imm_reg(32, ECX);
2066 i386_jcc(I386_CC_E, 2 + 3);
2067 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2068 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP3);
2070 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2071 i386_shift_reg(I386_SAR, REG_ITMP3);
2072 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2073 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2079 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2080 /* val.i = constant */
2082 d = reg_of_var(iptr->dst, REG_NULL);
2083 if (iptr->dst->flags & INMEMORY ) {
2084 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2085 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2087 if (iptr->val.i & 0x20) {
2088 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2089 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2090 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2093 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2094 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2097 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2098 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2102 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2104 d = reg_of_var(iptr->dst, REG_NULL);
2105 if (iptr->dst->flags & INMEMORY ){
2106 if (src->prev->flags & INMEMORY) {
2107 /* if (src->prev->regoff == iptr->dst->regoff) { */
2108 /* TODO: optimize */
2109 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2110 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2112 /* if (src->flags & INMEMORY) { */
2113 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2115 /* M_INTMOVE(src->regoff, ECX); */
2118 /* i386_test_imm_reg(32, ECX); */
2119 /* i386_jcc(I386_CC_E, 2 + 2); */
2120 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2121 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2123 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2124 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2125 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2126 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2129 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2130 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2132 if (src->flags & INMEMORY) {
2133 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2135 M_INTMOVE(src->regoff, ECX);
2138 i386_test_imm_reg(32, ECX);
2139 i386_jcc(I386_CC_E, 2 + 2);
2140 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2141 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2143 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2144 i386_shift_reg(I386_SHR, REG_ITMP3);
2145 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2146 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2152 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2153 /* val.l = constant */
2155 d = reg_of_var(iptr->dst, REG_NULL);
2156 if (iptr->dst->flags & INMEMORY ) {
2157 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2158 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2160 if (iptr->val.i & 0x20) {
2161 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2162 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2163 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2166 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2167 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2170 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2171 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2175 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2177 d = reg_of_var(iptr->dst, REG_NULL);
2178 i386_emit_ialu(I386_AND, src, iptr);
2181 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2182 /* val.i = constant */
2184 d = reg_of_var(iptr->dst, REG_NULL);
2185 i386_emit_ialuconst(I386_AND, src, iptr);
2188 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2190 d = reg_of_var(iptr->dst, REG_NULL);
2191 i386_emit_lalu(I386_AND, src, iptr);
2194 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2195 /* val.l = constant */
2197 d = reg_of_var(iptr->dst, REG_NULL);
2198 i386_emit_laluconst(I386_AND, src, iptr);
2201 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2203 d = reg_of_var(iptr->dst, REG_NULL);
2204 i386_emit_ialu(I386_OR, src, iptr);
2207 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2208 /* val.i = constant */
2210 d = reg_of_var(iptr->dst, REG_NULL);
2211 i386_emit_ialuconst(I386_OR, src, iptr);
2214 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2216 d = reg_of_var(iptr->dst, REG_NULL);
2217 i386_emit_lalu(I386_OR, src, iptr);
2220 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2221 /* val.l = constant */
2223 d = reg_of_var(iptr->dst, REG_NULL);
2224 i386_emit_laluconst(I386_OR, src, iptr);
2227 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2229 d = reg_of_var(iptr->dst, REG_NULL);
2230 i386_emit_ialu(I386_XOR, src, iptr);
2233 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2234 /* val.i = constant */
2236 d = reg_of_var(iptr->dst, REG_NULL);
2237 i386_emit_ialuconst(I386_XOR, src, iptr);
2240 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2242 d = reg_of_var(iptr->dst, REG_NULL);
2243 i386_emit_lalu(I386_XOR, src, iptr);
2246 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2247 /* val.l = constant */
2249 d = reg_of_var(iptr->dst, REG_NULL);
2250 i386_emit_laluconst(I386_XOR, src, iptr);
2253 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2254 /* op1 = variable, val.i = constant */
2256 var = &(locals[iptr->op1][TYPE_INT]);
2257 if (var->flags & INMEMORY) {
2258 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2261 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2266 /* floating operations ************************************************/
2268 #define ROUND_TO_SINGLE \
2269 i386_fstps_membase(REG_SP, -8); \
2270 i386_flds_membase(REG_SP, -8);
2272 #define ROUND_TO_DOUBLE \
2273 i386_fstpl_membase(REG_SP, -8); \
2274 i386_fldl_membase(REG_SP, -8);
2276 #define FPU_SET_24BIT_MODE \
2277 if (!fpu_in_24bit_mode) { \
2278 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2279 fpu_in_24bit_mode = 1; \
2282 #define FPU_SET_53BIT_MODE \
2283 if (fpu_in_24bit_mode) { \
2284 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2285 fpu_in_24bit_mode = 0; \
2288 #define ROUND_TO_SINGLE
2289 #define ROUND_TO_DOUBLE
2290 #define FPU_SET_24BIT_MODE
2291 #define FPU_SET_53BIT_MODE
2293 case ICMD_FNEG: /* ..., value ==> ..., - value */
2296 var_to_reg_flt(s1, src, REG_FTMP1);
2297 d = reg_of_var(iptr->dst, REG_FTMP3);
2299 store_reg_to_var_flt(iptr->dst, d);
2302 case ICMD_DNEG: /* ..., value ==> ..., - value */
2305 var_to_reg_flt(s1, src, REG_FTMP1);
2306 d = reg_of_var(iptr->dst, REG_FTMP3);
2308 store_reg_to_var_flt(iptr->dst, d);
2311 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2314 d = reg_of_var(iptr->dst, REG_FTMP3);
2315 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2316 var_to_reg_flt(s2, src, REG_FTMP2);
2319 store_reg_to_var_flt(iptr->dst, d);
2322 case ICMD_DADD: /* ..., 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_FSUB: /* ..., 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_DSUB: /* ..., 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_FMUL: /* ..., 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);
2364 store_reg_to_var_flt(iptr->dst, d);
2367 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2370 d = reg_of_var(iptr->dst, REG_FTMP3);
2371 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2373 /* i386_fldt_mem(subnormal_bias1); */
2376 var_to_reg_flt(s2, src, REG_FTMP2);
2381 /* i386_fldt_mem(subnormal_bias2); */
2384 store_reg_to_var_flt(iptr->dst, d);
2387 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2390 d = reg_of_var(iptr->dst, REG_FTMP3);
2391 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2392 var_to_reg_flt(s2, src, REG_FTMP2);
2396 store_reg_to_var_flt(iptr->dst, d);
2399 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2402 d = reg_of_var(iptr->dst, REG_FTMP3);
2403 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2405 /* i386_fldt_mem(subnormal_bias1); */
2408 var_to_reg_flt(s2, src, REG_FTMP2);
2413 /* i386_fldt_mem(subnormal_bias2); */
2416 store_reg_to_var_flt(iptr->dst, d);
2419 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2422 /* exchanged to skip fxch */
2423 var_to_reg_flt(s2, src, REG_FTMP2);
2424 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2425 d = reg_of_var(iptr->dst, REG_FTMP3);
2431 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2432 store_reg_to_var_flt(iptr->dst, d);
2438 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2441 /* exchanged to skip fxch */
2442 var_to_reg_flt(s2, src, REG_FTMP2);
2443 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2444 d = reg_of_var(iptr->dst, REG_FTMP3);
2450 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2451 store_reg_to_var_flt(iptr->dst, d);
2457 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2458 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2460 d = reg_of_var(iptr->dst, REG_FTMP1);
2461 if (src->flags & INMEMORY) {
2462 i386_fildl_membase(REG_SP, src->regoff * 8);
2467 i386_mov_imm_reg(0, REG_ITMP1);
2468 dseg_adddata(mcodeptr);
2469 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2470 i386_fildl_membase(REG_ITMP1, a);
2473 store_reg_to_var_flt(iptr->dst, d);
2476 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2477 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2479 d = reg_of_var(iptr->dst, REG_FTMP1);
2480 if (src->flags & INMEMORY) {
2481 i386_fildll_membase(REG_SP, src->regoff * 8);
2485 panic("L2F: longs have to be in memory");
2487 store_reg_to_var_flt(iptr->dst, d);
2490 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2492 var_to_reg_flt(s1, src, REG_FTMP1);
2493 d = reg_of_var(iptr->dst, REG_NULL);
2495 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2496 i386_mov_imm_reg(0, REG_ITMP1);
2497 dseg_adddata(mcodeptr);
2498 i386_fldcw_membase(REG_ITMP1, a);
2500 if (iptr->dst->flags & INMEMORY) {
2501 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2504 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2505 i386_fldcw_membase(REG_ITMP1, a);
2507 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2510 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2512 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2516 i386_fistpl_membase(REG_ITMP1, a);
2518 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2520 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2521 i386_fldcw_membase(REG_ITMP1, a);
2523 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2526 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2527 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2530 i386_jcc(I386_CC_NE, a);
2532 /* XXX: change this when we use registers */
2533 i386_flds_membase(REG_SP, src->regoff * 8);
2534 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP1);
2535 i386_call_reg(REG_ITMP1);
2537 if (iptr->dst->flags & INMEMORY) {
2538 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2541 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2545 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2547 var_to_reg_flt(s1, src, REG_FTMP1);
2548 d = reg_of_var(iptr->dst, REG_NULL);
2550 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2551 i386_mov_imm_reg(0, REG_ITMP1);
2552 dseg_adddata(mcodeptr);
2553 i386_fldcw_membase(REG_ITMP1, a);
2555 if (iptr->dst->flags & INMEMORY) {
2556 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2559 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2560 i386_fldcw_membase(REG_ITMP1, a);
2562 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2565 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2567 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2571 i386_fistpl_membase(REG_ITMP1, a);
2573 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2575 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2576 i386_fldcw_membase(REG_ITMP1, a);
2578 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2581 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2582 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2585 i386_jcc(I386_CC_NE, a);
2587 /* XXX: change this when we use registers */
2588 i386_fldl_membase(REG_SP, src->regoff * 8);
2589 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP1);
2590 i386_call_reg(REG_ITMP1);
2592 if (iptr->dst->flags & INMEMORY) {
2593 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2595 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2599 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2601 var_to_reg_flt(s1, src, REG_FTMP1);
2602 d = reg_of_var(iptr->dst, REG_NULL);
2604 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2605 i386_mov_imm_reg(0, REG_ITMP1);
2606 dseg_adddata(mcodeptr);
2607 i386_fldcw_membase(REG_ITMP1, a);
2609 if (iptr->dst->flags & INMEMORY) {
2610 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2613 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2614 i386_fldcw_membase(REG_ITMP1, a);
2616 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2619 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2621 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2624 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2626 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2628 i386_jcc(I386_CC_NE, a);
2630 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2633 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2635 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2637 i386_jcc(I386_CC_NE, a);
2639 /* XXX: change this when we use registers */
2640 i386_flds_membase(REG_SP, src->regoff * 8);
2641 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP1);
2642 i386_call_reg(REG_ITMP1);
2643 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2644 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2647 panic("F2L: longs have to be in memory");
2651 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2653 var_to_reg_flt(s1, src, REG_FTMP1);
2654 d = reg_of_var(iptr->dst, REG_NULL);
2656 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2657 i386_mov_imm_reg(0, REG_ITMP1);
2658 dseg_adddata(mcodeptr);
2659 i386_fldcw_membase(REG_ITMP1, a);
2661 if (iptr->dst->flags & INMEMORY) {
2662 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2665 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2666 i386_fldcw_membase(REG_ITMP1, a);
2668 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2671 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2673 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2676 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2678 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2680 i386_jcc(I386_CC_NE, a);
2682 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2685 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2687 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2689 i386_jcc(I386_CC_NE, a);
2691 /* XXX: change this when we use registers */
2692 i386_fldl_membase(REG_SP, src->regoff * 8);
2693 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP1);
2694 i386_call_reg(REG_ITMP1);
2695 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2696 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2699 panic("D2L: longs have to be in memory");
2703 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2705 var_to_reg_flt(s1, src, REG_FTMP1);
2706 d = reg_of_var(iptr->dst, REG_FTMP3);
2708 store_reg_to_var_flt(iptr->dst, d);
2711 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2713 var_to_reg_flt(s1, src, REG_FTMP1);
2714 d = reg_of_var(iptr->dst, REG_FTMP3);
2716 store_reg_to_var_flt(iptr->dst, d);
2719 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2722 /* exchanged to skip fxch */
2723 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2724 var_to_reg_flt(s1, src, REG_FTMP2);
2725 d = reg_of_var(iptr->dst, REG_ITMP1);
2730 i386_test_imm_reg(0x400, EAX); /* unordered treat as GT */
2731 i386_jcc(I386_CC_E, 6);
2732 i386_alu_imm_reg(I386_AND, 0x000000ff, EAX);
2734 i386_mov_imm_reg(0, d); /* does not affect flags */
2735 i386_jcc(I386_CC_E, 6 + 3 + 5 + 3);
2736 i386_jcc(I386_CC_B, 3 + 5);
2737 i386_alu_imm_reg(I386_SUB, 1, d);
2739 i386_alu_imm_reg(I386_ADD, 1, d);
2740 store_reg_to_var_int(iptr->dst, d);
2743 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2746 /* exchanged to skip fxch */
2747 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2748 var_to_reg_flt(s1, src, REG_FTMP2);
2749 d = reg_of_var(iptr->dst, REG_ITMP1);
2754 i386_test_imm_reg(0x400, EAX); /* unordered treat as LT */
2755 i386_jcc(I386_CC_E, 3);
2756 i386_movb_imm_reg(1, I386_AH);
2758 i386_mov_imm_reg(0, d); /* does not affect flags */
2759 i386_jcc(I386_CC_E, 6 + 3 + 5 + 3);
2760 i386_jcc(I386_CC_B, 3 + 5);
2761 i386_alu_imm_reg(I386_SUB, 1, d);
2763 i386_alu_imm_reg(I386_ADD, 1, d);
2764 store_reg_to_var_int(iptr->dst, d);
2768 /* memory operations **************************************************/
2770 #define gen_bound_check \
2771 if (checkbounds) { \
2772 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2773 i386_jcc(I386_CC_AE, 0); \
2774 codegen_addxboundrefs(mcodeptr, s2); \
2777 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2779 var_to_reg_int(s1, src, REG_ITMP1);
2780 d = reg_of_var(iptr->dst, REG_ITMP1);
2781 gen_nullptr_check(s1);
2782 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2783 store_reg_to_var_int(iptr->dst, d);
2786 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2788 var_to_reg_int(s1, src->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src, REG_ITMP2);
2790 d = reg_of_var(iptr->dst, REG_ITMP1);
2791 if (iptr->op1 == 0) {
2792 gen_nullptr_check(s1);
2795 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2796 store_reg_to_var_int(iptr->dst, d);
2799 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2801 var_to_reg_int(s1, src->prev, REG_ITMP1);
2802 var_to_reg_int(s2, src, REG_ITMP2);
2803 d = reg_of_var(iptr->dst, REG_ITMP3);
2804 if (iptr->op1 == 0) {
2805 gen_nullptr_check(s1);
2809 if (iptr->dst->flags & INMEMORY) {
2810 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2811 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2812 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2813 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2817 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2819 var_to_reg_int(s1, src->prev, REG_ITMP1);
2820 var_to_reg_int(s2, src, REG_ITMP2);
2821 d = reg_of_var(iptr->dst, REG_ITMP1);
2822 if (iptr->op1 == 0) {
2823 gen_nullptr_check(s1);
2826 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2827 store_reg_to_var_int(iptr->dst, d);
2830 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2832 var_to_reg_int(s1, src->prev, REG_ITMP1);
2833 var_to_reg_int(s2, src, REG_ITMP2);
2834 d = reg_of_var(iptr->dst, REG_FTMP1);
2835 if (iptr->op1 == 0) {
2836 gen_nullptr_check(s1);
2839 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2841 store_reg_to_var_flt(iptr->dst, d);
2844 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2846 var_to_reg_int(s1, src->prev, REG_ITMP1);
2847 var_to_reg_int(s2, src, REG_ITMP2);
2848 d = reg_of_var(iptr->dst, REG_FTMP3);
2849 if (iptr->op1 == 0) {
2850 gen_nullptr_check(s1);
2853 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2855 store_reg_to_var_flt(iptr->dst, d);
2858 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2860 var_to_reg_int(s1, src->prev, REG_ITMP1);
2861 var_to_reg_int(s2, src, REG_ITMP2);
2862 d = reg_of_var(iptr->dst, REG_ITMP1);
2863 if (iptr->op1 == 0) {
2864 gen_nullptr_check(s1);
2867 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2868 store_reg_to_var_int(iptr->dst, d);
2871 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2873 var_to_reg_int(s1, src->prev, REG_ITMP1);
2874 var_to_reg_int(s2, src, REG_ITMP2);
2875 d = reg_of_var(iptr->dst, REG_ITMP1);
2876 if (iptr->op1 == 0) {
2877 gen_nullptr_check(s1);
2880 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2881 store_reg_to_var_int(iptr->dst, d);
2884 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2886 var_to_reg_int(s1, src->prev, REG_ITMP1);
2887 var_to_reg_int(s2, src, REG_ITMP2);
2888 d = reg_of_var(iptr->dst, REG_ITMP1);
2889 if (iptr->op1 == 0) {
2890 gen_nullptr_check(s1);
2893 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2894 store_reg_to_var_int(iptr->dst, d);
2898 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2900 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2901 var_to_reg_int(s2, src->prev, REG_ITMP2);
2902 if (iptr->op1 == 0) {
2903 gen_nullptr_check(s1);
2906 var_to_reg_int(s3, src, REG_ITMP3);
2907 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2910 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2912 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2913 var_to_reg_int(s2, src->prev, REG_ITMP2);
2914 if (iptr->op1 == 0) {
2915 gen_nullptr_check(s1);
2919 if (src->flags & INMEMORY) {
2920 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2921 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2922 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2923 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2927 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2929 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2930 var_to_reg_int(s2, src->prev, REG_ITMP2);
2931 if (iptr->op1 == 0) {
2932 gen_nullptr_check(s1);
2935 var_to_reg_int(s3, src, REG_ITMP3);
2936 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2939 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2941 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2942 var_to_reg_int(s2, src->prev, REG_ITMP2);
2943 if (iptr->op1 == 0) {
2944 gen_nullptr_check(s1);
2947 var_to_reg_flt(s3, src, REG_FTMP1);
2948 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2952 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2954 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2955 var_to_reg_int(s2, src->prev, REG_ITMP2);
2956 if (iptr->op1 == 0) {
2957 gen_nullptr_check(s1);
2960 var_to_reg_flt(s3, src, REG_FTMP1);
2961 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2965 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2967 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2968 var_to_reg_int(s2, src->prev, REG_ITMP2);
2969 if (iptr->op1 == 0) {
2970 gen_nullptr_check(s1);
2973 var_to_reg_int(s3, src, REG_ITMP3);
2974 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2977 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2979 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2980 var_to_reg_int(s2, src->prev, REG_ITMP2);
2981 if (iptr->op1 == 0) {
2982 gen_nullptr_check(s1);
2985 var_to_reg_int(s3, src, REG_ITMP3);
2986 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2989 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2991 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2992 var_to_reg_int(s2, src->prev, REG_ITMP2);
2993 if (iptr->op1 == 0) {
2994 gen_nullptr_check(s1);
2997 var_to_reg_int(s3, src, REG_ITMP3);
2998 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2999 M_INTMOVE(s3, REG_ITMP3);
3002 i386_movb_reg_memindex(s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
3006 case ICMD_PUTSTATIC: /* ..., value ==> ... */
3007 /* op1 = type, val.a = field address */
3009 /* if class isn't yet initialized, do it */
3010 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
3011 /* call helper function which patches this code */
3012 i386_mov_imm_reg((s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
3013 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
3014 i386_call_reg(REG_ITMP2);
3017 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
3018 /* here it's slightly slower */
3019 i386_mov_imm_reg(0, REG_ITMP2);
3020 dseg_adddata(mcodeptr);
3021 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3022 switch (iptr->op1) {
3025 var_to_reg_int(s2, src, REG_ITMP1);
3026 i386_mov_reg_membase(s2, REG_ITMP2, 0);
3029 if (src->flags & INMEMORY) {
3030 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3031 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
3032 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3033 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
3035 panic("PUTSTATIC: longs have to be in memory");
3039 var_to_reg_flt(s2, src, REG_FTMP1);
3040 i386_fstps_membase(REG_ITMP2, 0);
3044 var_to_reg_flt(s2, src, REG_FTMP1);
3045 i386_fstpl_membase(REG_ITMP2, 0);
3048 default: panic ("internal error");
3052 case ICMD_GETSTATIC: /* ... ==> ..., value */
3053 /* op1 = type, val.a = field address */
3055 /* if class isn't yet initialized, do it */
3056 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
3057 /* call helper function which patches this code */
3058 i386_mov_imm_reg((s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
3059 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
3060 i386_call_reg(REG_ITMP2);
3063 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
3064 i386_mov_imm_reg(0, REG_ITMP2);
3065 dseg_adddata(mcodeptr);
3066 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3067 switch (iptr->op1) {
3070 d = reg_of_var(iptr->dst, REG_ITMP1);
3071 i386_mov_membase_reg(REG_ITMP2, 0, d);
3072 store_reg_to_var_int(iptr->dst, d);
3075 d = reg_of_var(iptr->dst, REG_NULL);
3076 if (iptr->dst->flags & INMEMORY) {
3077 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3078 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3079 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3080 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3082 panic("GETSTATIC: longs have to be in memory");
3086 d = reg_of_var(iptr->dst, REG_FTMP1);
3087 i386_flds_membase(REG_ITMP2, 0);
3089 store_reg_to_var_flt(iptr->dst, d);
3092 d = reg_of_var(iptr->dst, REG_FTMP1);
3093 i386_fldl_membase(REG_ITMP2, 0);
3095 store_reg_to_var_flt(iptr->dst, d);
3097 default: panic ("internal error");
3101 case ICMD_PUTFIELD: /* ..., value ==> ... */
3102 /* op1 = type, val.i = field offset */
3104 a = ((fieldinfo *)(iptr->val.a))->offset;
3105 switch (iptr->op1) {
3108 var_to_reg_int(s1, src->prev, REG_ITMP1);
3109 var_to_reg_int(s2, src, REG_ITMP2);
3110 gen_nullptr_check(s1);
3111 i386_mov_reg_membase(s2, s1, a);
3114 var_to_reg_int(s1, src->prev, REG_ITMP1);
3115 gen_nullptr_check(s1);
3116 if (src->flags & INMEMORY) {
3117 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3118 i386_mov_reg_membase(REG_ITMP2, s1, a);
3119 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3120 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3122 panic("PUTFIELD: longs have to be in memory");
3126 var_to_reg_int(s1, src->prev, REG_ITMP1);
3127 var_to_reg_flt(s2, src, REG_FTMP1);
3128 gen_nullptr_check(s1);
3129 i386_fstps_membase(s1, a);
3133 var_to_reg_int(s1, src->prev, REG_ITMP1);
3134 var_to_reg_flt(s2, src, REG_FTMP1);
3135 gen_nullptr_check(s1);
3136 i386_fstpl_membase(s1, a);
3139 default: panic ("internal error");
3143 case ICMD_GETFIELD: /* ... ==> ..., value */
3144 /* op1 = type, val.i = field offset */
3146 a = ((fieldinfo *)(iptr->val.a))->offset;
3147 switch (iptr->op1) {
3150 var_to_reg_int(s1, src, REG_ITMP1);
3151 d = reg_of_var(iptr->dst, REG_ITMP2);
3152 gen_nullptr_check(s1);
3153 i386_mov_membase_reg(s1, a, d);
3154 store_reg_to_var_int(iptr->dst, d);
3157 var_to_reg_int(s1, src, REG_ITMP1);
3158 d = reg_of_var(iptr->dst, REG_NULL);
3159 gen_nullptr_check(s1);
3160 i386_mov_membase_reg(s1, a, REG_ITMP2);
3161 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3162 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3163 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3166 var_to_reg_int(s1, src, REG_ITMP1);
3167 d = reg_of_var(iptr->dst, REG_FTMP1);
3168 gen_nullptr_check(s1);
3169 i386_flds_membase(s1, a);
3171 store_reg_to_var_flt(iptr->dst, d);
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_fldl_membase(s1, a);
3179 store_reg_to_var_flt(iptr->dst, d);
3181 default: panic ("internal error");
3186 /* branch operations **************************************************/
3189 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3190 #define ALIGNCODENOP do {} while (0)
3192 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3194 var_to_reg_int(s1, src, REG_ITMP1);
3195 M_INTMOVE(s1, REG_ITMP1_XPTR);
3197 i386_call_imm(0); /* passing exception pointer */
3198 i386_pop_reg(REG_ITMP2_XPC);
3200 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
3201 i386_jmp_reg(REG_ITMP3);
3205 case ICMD_GOTO: /* ... ==> ... */
3206 /* op1 = target JavaVM pc */
3209 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3213 case ICMD_JSR: /* ... ==> ... */
3214 /* op1 = target JavaVM pc */
3217 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3220 case ICMD_RET: /* ... ==> ... */
3221 /* op1 = local variable */
3223 var = &(locals[iptr->op1][TYPE_ADR]);
3224 var_to_reg_int(s1, var, REG_ITMP1);
3228 case ICMD_IFNULL: /* ..., value ==> ... */
3229 /* op1 = target JavaVM pc */
3231 if (src->flags & INMEMORY) {
3232 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3235 i386_test_reg_reg(src->regoff, src->regoff);
3237 i386_jcc(I386_CC_E, 0);
3238 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3241 case ICMD_IFNONNULL: /* ..., value ==> ... */
3242 /* op1 = target JavaVM pc */
3244 if (src->flags & INMEMORY) {
3245 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3248 i386_test_reg_reg(src->regoff, src->regoff);
3250 i386_jcc(I386_CC_NE, 0);
3251 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3254 case ICMD_IFEQ: /* ..., value ==> ... */
3255 /* op1 = target JavaVM pc, val.i = constant */
3257 if (src->flags & INMEMORY) {
3258 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3261 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3263 i386_jcc(I386_CC_E, 0);
3264 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3267 case ICMD_IFLT: /* ..., value ==> ... */
3268 /* op1 = target JavaVM pc, val.i = constant */
3270 if (src->flags & INMEMORY) {
3271 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3274 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3276 i386_jcc(I386_CC_L, 0);
3277 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3280 case ICMD_IFLE: /* ..., value ==> ... */
3281 /* op1 = target JavaVM pc, val.i = constant */
3283 if (src->flags & INMEMORY) {
3284 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3287 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3289 i386_jcc(I386_CC_LE, 0);
3290 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3293 case ICMD_IFNE: /* ..., value ==> ... */
3294 /* op1 = target JavaVM pc, val.i = constant */
3296 if (src->flags & INMEMORY) {
3297 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3300 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3302 i386_jcc(I386_CC_NE, 0);
3303 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3306 case ICMD_IFGT: /* ..., value ==> ... */
3307 /* op1 = target JavaVM pc, val.i = constant */
3309 if (src->flags & INMEMORY) {
3310 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3313 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3315 i386_jcc(I386_CC_G, 0);
3316 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3319 case ICMD_IFGE: /* ..., value ==> ... */
3320 /* op1 = target JavaVM pc, val.i = constant */
3322 if (src->flags & INMEMORY) {
3323 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3326 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3328 i386_jcc(I386_CC_GE, 0);
3329 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3332 case ICMD_IF_LEQ: /* ..., value ==> ... */
3333 /* op1 = target JavaVM pc, val.l = constant */
3335 if (src->flags & INMEMORY) {
3336 if (iptr->val.l == 0) {
3337 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3338 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3341 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3342 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3343 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3344 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3345 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3348 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3349 i386_jcc(I386_CC_E, 0);
3350 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3353 case ICMD_IF_LLT: /* ..., value ==> ... */
3354 /* op1 = target JavaVM pc, val.l = constant */
3356 if (src->flags & INMEMORY) {
3357 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3358 i386_jcc(I386_CC_L, 0);
3359 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3362 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3363 CALCIMMEDIATEBYTES(a, iptr->val.l);
3365 i386_jcc(I386_CC_G, a);
3367 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3368 i386_jcc(I386_CC_B, 0);
3369 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3373 case ICMD_IF_LLE: /* ..., value ==> ... */
3374 /* op1 = target JavaVM pc, val.l = constant */
3376 if (src->flags & INMEMORY) {
3377 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3378 i386_jcc(I386_CC_L, 0);
3379 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3382 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3383 CALCIMMEDIATEBYTES(a, iptr->val.l);
3385 i386_jcc(I386_CC_G, a);
3387 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3388 i386_jcc(I386_CC_BE, 0);
3389 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3393 case ICMD_IF_LNE: /* ..., value ==> ... */
3394 /* op1 = target JavaVM pc, val.l = constant */
3396 if (src->flags & INMEMORY) {
3397 if (iptr->val.l == 0) {
3398 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3399 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3402 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3403 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3404 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3405 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3406 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3409 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3410 i386_jcc(I386_CC_NE, 0);
3411 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3414 case ICMD_IF_LGT: /* ..., value ==> ... */
3415 /* op1 = target JavaVM pc, val.l = constant */
3417 if (src->flags & INMEMORY) {
3418 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3419 i386_jcc(I386_CC_G, 0);
3420 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3423 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3424 CALCIMMEDIATEBYTES(a, iptr->val.l);
3426 i386_jcc(I386_CC_L, a);
3428 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3429 i386_jcc(I386_CC_A, 0);
3430 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3434 case ICMD_IF_LGE: /* ..., value ==> ... */
3435 /* op1 = target JavaVM pc, val.l = constant */
3437 if (src->flags & INMEMORY) {
3438 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3439 i386_jcc(I386_CC_G, 0);
3440 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3443 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3444 CALCIMMEDIATEBYTES(a, iptr->val.l);
3446 i386_jcc(I386_CC_L, a);
3448 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3449 i386_jcc(I386_CC_AE, 0);
3450 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3454 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3455 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3457 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3458 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3459 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3461 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3462 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3464 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3465 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3468 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3470 i386_jcc(I386_CC_E, 0);
3471 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3474 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3475 /* op1 = target JavaVM pc */
3477 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3478 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3479 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3480 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3481 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3482 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3483 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3485 i386_jcc(I386_CC_E, 0);
3486 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3489 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3490 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3492 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3493 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3494 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3496 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3497 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3499 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3500 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3503 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3505 i386_jcc(I386_CC_NE, 0);
3506 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3509 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3510 /* op1 = target JavaVM pc */
3512 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3513 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3514 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3515 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3516 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3517 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3518 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3520 i386_jcc(I386_CC_NE, 0);
3521 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3524 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3525 /* op1 = target JavaVM pc */
3527 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3528 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3529 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3531 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3532 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3534 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3535 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3538 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3540 i386_jcc(I386_CC_L, 0);
3541 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3544 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3545 /* op1 = target JavaVM pc */
3547 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3548 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3549 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3550 i386_jcc(I386_CC_L, 0);
3551 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3554 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3555 CALCOFFSETBYTES(a, REG_SP, src->regoff);
3557 i386_jcc(I386_CC_G, a);
3559 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3560 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3561 i386_jcc(I386_CC_B, 0);
3562 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3566 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3567 /* op1 = target JavaVM pc */
3569 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3570 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3571 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3573 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3574 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3576 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3577 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3580 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3582 i386_jcc(I386_CC_G, 0);
3583 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3586 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3587 /* op1 = target JavaVM pc */
3589 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3590 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3591 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3592 i386_jcc(I386_CC_G, 0);
3593 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3596 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3597 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3599 i386_jcc(I386_CC_L, a);
3601 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3602 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3603 i386_jcc(I386_CC_A, 0);
3604 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3608 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3609 /* op1 = target JavaVM pc */
3611 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3612 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3613 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3615 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3616 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3618 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3619 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3622 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3624 i386_jcc(I386_CC_LE, 0);
3625 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3628 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3629 /* op1 = target JavaVM pc */
3631 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3632 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3633 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3634 i386_jcc(I386_CC_L, 0);
3635 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3638 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3639 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3641 i386_jcc(I386_CC_G, a);
3643 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3644 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3645 i386_jcc(I386_CC_BE, 0);
3646 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3650 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3651 /* op1 = target JavaVM pc */
3653 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3654 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3655 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3657 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3658 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3660 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3661 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3664 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3666 i386_jcc(I386_CC_GE, 0);
3667 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3670 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3671 /* op1 = target JavaVM pc */
3673 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3674 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3675 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3676 i386_jcc(I386_CC_G, 0);
3677 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3680 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3681 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3683 i386_jcc(I386_CC_L, a);
3685 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3686 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3687 i386_jcc(I386_CC_AE, 0);
3688 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3692 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3694 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3697 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3698 /* val.i = constant */
3700 d = reg_of_var(iptr->dst, REG_NULL);
3701 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3704 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3705 /* val.i = constant */
3707 d = reg_of_var(iptr->dst, REG_NULL);
3708 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3711 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3712 /* val.i = constant */
3714 d = reg_of_var(iptr->dst, REG_NULL);
3715 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3718 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3719 /* val.i = constant */
3721 d = reg_of_var(iptr->dst, REG_NULL);
3722 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3725 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3726 /* val.i = constant */
3728 d = reg_of_var(iptr->dst, REG_NULL);
3729 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3732 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3733 /* val.i = constant */
3735 d = reg_of_var(iptr->dst, REG_NULL);
3736 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3740 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3744 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3745 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3746 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3747 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3748 i386_mov_imm_reg((s4) asm_builtin_monitorexit, REG_ITMP1);
3749 i386_call_reg(REG_ITMP1);
3750 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3753 var_to_reg_int(s1, src, REG_RESULT);
3754 M_INTMOVE(s1, REG_RESULT);
3755 goto nowperformreturn;
3757 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3760 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3761 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3762 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3763 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3764 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3765 i386_call_reg(REG_ITMP1);
3766 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3769 if (src->flags & INMEMORY) {
3770 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3771 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3774 panic("LRETURN: longs have to be in memory");
3776 goto nowperformreturn;
3778 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3781 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3782 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3783 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3784 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3785 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3786 i386_call_reg(REG_ITMP1);
3787 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3790 var_to_reg_flt(s1, src, REG_FRESULT);
3791 /* this may be an early return -- keep the offset correct for the remaining code */
3793 goto nowperformreturn;
3795 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3798 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3799 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3800 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3801 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3802 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3803 i386_call_reg(REG_ITMP1);
3804 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3807 var_to_reg_flt(s1, src, REG_FRESULT);
3808 /* this may be an early return -- keep the offset correct for the remaining code */
3810 goto nowperformreturn;
3812 case ICMD_RETURN: /* ... ==> ... */
3815 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3816 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3817 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3818 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3819 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3820 i386_call_reg(REG_ITMP1);
3821 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3829 p = parentargs_base;
3831 /* restore saved registers */
3832 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3834 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3836 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3838 i386_fldl_membase(REG_SP, p * 8);
3840 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3841 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3843 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3848 /* deallocate stack */
3849 if (parentargs_base) {
3850 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3853 /* call trace function */
3855 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3857 i386_mov_imm_membase((s4) method, REG_SP, 0);
3859 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3860 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3862 i386_fstl_membase(REG_SP, 4 + 8);
3863 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3865 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3866 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3867 i386_call_reg(REG_ITMP1);
3869 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3870 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3872 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3881 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3886 tptr = (void **) iptr->target;
3888 s4ptr = iptr->val.a;
3889 l = s4ptr[1]; /* low */
3890 i = s4ptr[2]; /* high */
3892 var_to_reg_int(s1, src, REG_ITMP1);
3893 M_INTMOVE(s1, REG_ITMP1);
3895 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3901 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3902 i386_jcc(I386_CC_A, 0);
3904 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3905 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3907 /* build jump table top down and use address of lowest entry */
3909 /* s4ptr += 3 + i; */
3913 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3914 dseg_addtarget((basicblock *) tptr[0]);
3918 /* length of dataseg after last dseg_addtarget is used by load */
3920 i386_mov_imm_reg(0, REG_ITMP2);
3921 dseg_adddata(mcodeptr);
3922 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3923 i386_jmp_reg(REG_ITMP1);
3929 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3931 s4 i, l, val, *s4ptr;
3934 tptr = (void **) iptr->target;
3936 s4ptr = iptr->val.a;
3937 l = s4ptr[0]; /* default */
3938 i = s4ptr[1]; /* count */
3940 MCODECHECK((i<<2)+8);
3941 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3947 i386_alu_imm_reg(I386_CMP, val, s1);
3948 i386_jcc(I386_CC_E, 0);
3949 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3950 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3954 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3956 tptr = (void **) iptr->target;
3957 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3964 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3965 /* op1 = return type, val.a = function pointer*/
3969 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3970 /* op1 = return type, val.a = function pointer*/
3974 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3975 /* op1 = return type, val.a = function pointer*/
3979 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3980 /* op1 = arg count, val.a = method pointer */
3982 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3983 /* op1 = arg count, val.a = method pointer */
3985 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3986 /* op1 = arg count, val.a = method pointer */
3988 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3989 /* op1 = arg count, val.a = method pointer */
3997 MCODECHECK((s3 << 1) + 64);
3999 if ( (iptr->opc == ICMD_BUILTIN1) ||
4000 (iptr->opc == ICMD_BUILTIN2) ||
4001 (iptr->opc == ICMD_BUILTIN3) ) {
4003 i386_push_reg(REG_ITMP1);
4004 i386_push_reg(REG_ITMP2);
4005 i386_push_reg(REG_ITMP3);
4007 i386_mov_imm_reg((s4) builtin_asm_new_stackframeinfo, REG_ITMP1);
4008 i386_call_reg(REG_ITMP1);
4010 i386_pop_reg(REG_ITMP3);
4011 i386_pop_reg(REG_ITMP2);
4012 i386_pop_reg(REG_ITMP1);
4015 i386_mov_membase_reg(REG_SP, 0 , REG_ITMP2); /*save return adress*/
4016 i386_mov_membase_reg(REG_RESULT, 0 , REG_ITMP3); /*get direct access to structure*/
4018 i386_mov_imm_membase(0x1111, REG_ITMP3, offreturnfromnative); /*store return adress in stack frame info block*/
4019 i386_mov_imm_membase((s4) m, REG_ITMP3, offmethodnative); /*store methodpointer in stack frame info block*/
4020 i386_mov_imm_membase(1111,REG_ITMP3,offaddrreturnfromnative);
4024 /* copy arguments to registers or stack location */
4026 for (; --s3 >= 0; src = src->prev) {
4027 if (src->varkind == ARGVAR) {
4031 if (IS_INT_LNG_TYPE(src->type)) {
4032 if (s3 < intreg_argnum) {
4033 panic("No integer argument registers available!");
4036 if (!IS_2_WORD_TYPE(src->type)) {
4037 if (src->flags & INMEMORY) {
4038 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4039 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4042 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4046 if (src->flags & INMEMORY) {
4047 M_LNGMEMMOVE(src->regoff, s3);
4050 panic("copy arguments: longs have to be in memory");
4056 if (s3 < fltreg_argnum) {
4057 panic("No float argument registers available!");
4060 var_to_reg_flt(d, src, REG_FTMP1);
4061 if (src->type == TYPE_FLT) {
4062 i386_fstps_membase(REG_SP, s3 * 8);
4065 i386_fstpl_membase(REG_SP, s3 * 8);
4072 switch (iptr->opc) {
4081 i386_mov_imm_reg(a, REG_ITMP1);
4082 i386_call_reg(REG_ITMP1);
4085 case ICMD_INVOKESTATIC:
4087 a = (s4) m->stubroutine;
4090 i386_mov_imm_reg(a, REG_ITMP2);
4091 i386_call_reg(REG_ITMP2);
4094 case ICMD_INVOKESPECIAL:
4096 a = (s4) m->stubroutine;
4099 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4100 gen_nullptr_check(REG_ITMP1);
4101 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4103 i386_mov_imm_reg(a, REG_ITMP2);
4104 i386_call_reg(REG_ITMP2);
4107 case ICMD_INVOKEVIRTUAL:
4111 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4112 gen_nullptr_check(REG_ITMP1);
4113 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4114 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4116 i386_call_reg(REG_ITMP1);
4119 case ICMD_INVOKEINTERFACE:
4124 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4125 gen_nullptr_check(REG_ITMP1);
4126 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4127 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4128 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4130 i386_call_reg(REG_ITMP1);
4135 error("Unkown ICMD-Command: %d", iptr->opc);
4138 /* d contains return type */
4140 if (d != TYPE_VOID) {
4141 d = reg_of_var(iptr->dst, REG_NULL);
4143 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4144 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4145 if (iptr->dst->flags & INMEMORY) {
4146 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4147 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4150 panic("RETURN: longs have to be in memory");
4154 if (iptr->dst->flags & INMEMORY) {
4155 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4158 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4163 /* fld from called function -- has other fpu_st_offset counter */
4165 store_reg_to_var_flt(iptr->dst, d);
4172 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4174 /* op1: 0 == array, 1 == class */
4175 /* val.a: (classinfo*) superclass */
4177 /* superclass is an interface:
4179 * return (sub != NULL) &&
4180 * (sub->vftbl->interfacetablelength > super->index) &&
4181 * (sub->vftbl->interfacetable[-super->index] != NULL);
4183 * superclass is a class:
4185 * return ((sub != NULL) && (0
4186 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4187 * super->vftbl->diffvall));
4191 classinfo *super = (classinfo*) iptr->val.a;
4193 var_to_reg_int(s1, src, REG_ITMP1);
4194 d = reg_of_var(iptr->dst, REG_ITMP3);
4196 M_INTMOVE(s1, REG_ITMP1);
4199 i386_alu_reg_reg(I386_XOR, d, d);
4200 if (iptr->op1) { /* class/interface */
4201 if (super->flags & ACC_INTERFACE) { /* interface */
4202 i386_test_reg_reg(s1, s1);
4204 /* TODO: clean up this calculation */
4206 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4209 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4212 /* CALCOFFSETBYTES(a, super->index); */
4213 CALCIMMEDIATEBYTES(a, super->index);
4219 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4226 i386_jcc(I386_CC_E, a);
4228 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4229 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4230 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4232 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4234 /* TODO: clean up this calculation */
4237 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4244 i386_jcc(I386_CC_LE, a);
4245 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4247 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4248 /* i386_setcc_reg(I386_CC_A, d); */
4249 /* i386_jcc(I386_CC_BE, 5); */
4250 i386_jcc(I386_CC_E, 5);
4251 i386_mov_imm_reg(1, d);
4254 } else { /* class */
4255 i386_test_reg_reg(s1, s1);
4257 /* TODO: clean up this calculation */
4259 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4262 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4264 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4267 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4277 i386_jcc(I386_CC_E, a);
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 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4288 i386_jcc(I386_CC_A, 5);
4289 i386_mov_imm_reg(1, d);
4293 panic ("internal error: no inlined array instanceof");
4295 store_reg_to_var_int(iptr->dst, d);
4298 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4300 /* op1: 0 == array, 1 == class */
4301 /* val.a: (classinfo*) superclass */
4303 /* superclass is an interface:
4305 * OK if ((sub == NULL) ||
4306 * (sub->vftbl->interfacetablelength > super->index) &&
4307 * (sub->vftbl->interfacetable[-super->index] != NULL));
4309 * superclass is a class:
4311 * OK if ((sub == NULL) || (0
4312 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4313 * super->vftbl->diffvall));
4317 classinfo *super = (classinfo*) iptr->val.a;
4319 d = reg_of_var(iptr->dst, REG_ITMP3);
4320 var_to_reg_int(s1, src, d);
4321 if (iptr->op1) { /* class/interface */
4322 if (super->flags & ACC_INTERFACE) { /* interface */
4323 i386_test_reg_reg(s1, s1);
4325 /* TODO: clean up this calculation */
4327 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4330 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4333 /* CALCOFFSETBYTES(a, super->index); */
4334 CALCIMMEDIATEBYTES(a, super->index);
4340 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4345 i386_jcc(I386_CC_E, a);
4347 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4348 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4349 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4351 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4352 i386_jcc(I386_CC_LE, 0);
4353 codegen_addxcastrefs(mcodeptr);
4354 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4356 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4357 i386_jcc(I386_CC_E, 0);
4358 codegen_addxcastrefs(mcodeptr);
4360 } else { /* class */
4361 i386_test_reg_reg(s1, s1);
4363 /* TODO: clean up this calculation */
4365 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4370 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4372 if (d != REG_ITMP3) {
4374 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4377 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4383 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4390 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4397 i386_jcc(I386_CC_E, a);
4399 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4400 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4401 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4402 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4403 codegen_threadcritstart(mcodeptr - mcodebase);
4405 if (d != REG_ITMP3) {
4406 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4407 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4408 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4409 codegen_threadcritstop(mcodeptr - mcodebase);
4411 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4414 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4415 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4416 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4417 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4418 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4419 codegen_threadcritstop(mcodeptr - mcodebase);
4423 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4424 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4425 codegen_addxcastrefs(mcodeptr);
4429 panic ("internal error: no inlined array checkcast");
4432 store_reg_to_var_int(iptr->dst, d);
4435 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4437 if (src->flags & INMEMORY) {
4438 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4441 i386_test_reg_reg(src->regoff, src->regoff);
4443 i386_jcc(I386_CC_L, 0);
4444 codegen_addxcheckarefs(mcodeptr);
4447 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4448 /* op1 = dimension, val.a = array descriptor */
4450 /* check for negative sizes and copy sizes to stack if necessary */
4452 MCODECHECK((iptr->op1 << 1) + 64);
4454 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4455 if (src->flags & INMEMORY) {
4456 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4459 i386_test_reg_reg(src->regoff, src->regoff);
4461 i386_jcc(I386_CC_L, 0);
4462 codegen_addxcheckarefs(mcodeptr);
4465 * copy sizes to new stack location, be cause native function
4466 * builtin_nmultianewarray access them as (int *)
4468 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4469 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4471 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4473 if (src->varkind != ARGVAR) {
4474 if (src->flags & INMEMORY) {
4475 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4476 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4479 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4483 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4485 /* a0 = dimension count */
4487 /* save stack pointer */
4488 M_INTMOVE(REG_SP, REG_ITMP1);
4490 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4491 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4493 /* a1 = arraydescriptor */
4495 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4497 /* a2 = pointer to dimensions = stack pointer */
4499 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4501 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4502 i386_call_reg(REG_ITMP1);
4503 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4505 s1 = reg_of_var(iptr->dst, REG_RESULT);
4506 M_INTMOVE(REG_RESULT, s1);
4507 store_reg_to_var_int(iptr->dst, s1);
4511 error ("Unknown pseudo command: %d", iptr->opc);
4514 } /* for instruction */
4516 /* copy values to interface registers */
4518 src = bptr->outstack;
4519 len = bptr->outdepth;
4523 if ((src->varkind != STACKVAR)) {
4525 if (IS_FLT_DBL_TYPE(s2)) {
4526 var_to_reg_flt(s1, src, REG_FTMP1);
4527 if (!(interfaces[len][s2].flags & INMEMORY)) {
4528 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4531 panic("double store");
4532 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4536 var_to_reg_int(s1, src, REG_ITMP1);
4537 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4538 if (!(interfaces[len][s2].flags & INMEMORY)) {
4539 M_INTMOVE(s1, interfaces[len][s2].regoff);
4542 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4546 if (interfaces[len][s2].flags & INMEMORY) {
4547 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4550 panic("copy interface registers: longs have to be in memory (end)");
4557 } /* if (bptr -> flags >= BBREACHED) */
4558 } /* for basic block */
4560 codegen_createlinenumbertable();
4562 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4566 /* generate bound check stubs */
4567 u1 *xcodeptr = NULL;
4569 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4570 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4571 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4572 xboundrefs->branchpos,
4573 (u1*) xcodeptr - (u1*) mcodebase - (2 + 5 + 5 + 2));
4578 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4579 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4583 /* move index into REG_ITMP1 */
4584 i386_mov_reg_reg(xboundrefs->reg, REG_ITMP1); /* 2 bytes */
4586 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4587 dseg_adddata(mcodeptr);
4588 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP3); /* 5 bytes */
4589 i386_alu_reg_reg(I386_ADD, REG_ITMP3, REG_ITMP2_XPC); /* 2 bytes */
4591 if (xcodeptr != NULL) {
4592 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4595 xcodeptr = mcodeptr;
4597 i386_push_reg(REG_ITMP2_XPC);
4599 i386_alu_imm_reg(I386_SUB, 2 * 4, REG_SP);
4600 i386_mov_imm_membase((s4) string_java_lang_ArrayIndexOutOfBoundsException, REG_SP, 0 * 4);
4601 i386_mov_reg_membase(REG_ITMP1, REG_SP, 1 * 4);
4602 i386_mov_imm_reg((s4) new_exception_int, REG_ITMP1);
4603 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4604 i386_alu_imm_reg(I386_ADD, 2 * 4, REG_SP);
4606 i386_pop_reg(REG_ITMP2_XPC);
4608 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4609 i386_jmp_reg(REG_ITMP3);
4613 /* generate negative array size check stubs */
4616 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4617 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4618 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4619 xcheckarefs->branchpos,
4620 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4624 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4625 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4629 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4630 dseg_adddata(mcodeptr);
4631 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4632 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4634 if (xcodeptr != NULL) {
4635 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4638 xcodeptr = mcodeptr;
4640 /* i386_mov_imm_reg((s4) proto_java_lang_NegativeArraySizeException, REG_ITMP1_XPTR); */
4642 i386_push_reg(REG_ITMP2_XPC);
4644 i386_alu_imm_reg(I386_SUB, 1 * 4, REG_SP);
4645 i386_mov_imm_membase((s4) string_java_lang_NegativeArraySizeException, REG_SP, 0 * 4);
4646 i386_mov_imm_reg((s4) new_exception, REG_ITMP1);
4647 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4648 i386_alu_imm_reg(I386_ADD, 1 * 4, REG_SP);
4650 i386_pop_reg(REG_ITMP2_XPC);
4652 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4653 i386_jmp_reg(REG_ITMP3);
4657 /* generate cast check stubs */
4660 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4661 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4662 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4663 xcastrefs->branchpos,
4664 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4668 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4669 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4673 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4674 dseg_adddata(mcodeptr);
4675 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4676 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4678 if (xcodeptr != NULL) {
4679 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4682 xcodeptr = mcodeptr;
4684 /* i386_mov_imm_reg((s4) proto_java_lang_ClassCastException, REG_ITMP1_XPTR); */
4686 i386_push_reg(REG_ITMP2_XPC);
4688 i386_alu_imm_reg(I386_SUB, 1 * 4, REG_SP);
4689 i386_mov_imm_membase((s4) string_java_lang_ClassCastException, REG_SP, 0 * 4);
4690 i386_mov_imm_reg((s4) new_exception, REG_ITMP1);
4691 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4692 i386_alu_imm_reg(I386_ADD, 1 * 4, REG_SP);
4694 i386_pop_reg(REG_ITMP2_XPC);
4696 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4697 i386_jmp_reg(REG_ITMP3);
4701 /* generate divide by zero check stubs */
4704 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4705 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4706 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4707 xdivrefs->branchpos,
4708 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4712 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4713 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4717 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4718 dseg_adddata(mcodeptr);
4719 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4720 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4722 if (xcodeptr != NULL) {
4723 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4726 xcodeptr = mcodeptr;
4728 /* i386_mov_imm_reg((s4) proto_java_lang_ArithmeticException, REG_ITMP1_XPTR); */
4730 i386_push_reg(REG_ITMP2_XPC);
4732 i386_alu_imm_reg(I386_SUB, 2 * 4, REG_SP);
4733 i386_mov_imm_membase((s4) string_java_lang_ArithmeticException, REG_SP, 0 * 4);
4734 i386_mov_imm_membase((s4) string_java_lang_ArithmeticException_message, REG_SP, 1 * 4);
4735 i386_mov_imm_reg((s4) new_exception_message, REG_ITMP1);
4736 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4737 i386_alu_imm_reg(I386_ADD, 2 * 4, REG_SP);
4739 i386_pop_reg(REG_ITMP2_XPC);
4741 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4742 i386_jmp_reg(REG_ITMP3);
4746 /* generate null pointer check stubs */
4749 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4750 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4751 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4752 xnullrefs->branchpos,
4753 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4757 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4758 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4762 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4763 dseg_adddata(mcodeptr);
4764 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4765 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4767 if (xcodeptr != NULL) {
4768 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4771 xcodeptr = mcodeptr;
4773 /* i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR); */
4775 i386_push_reg(REG_ITMP2_XPC);
4777 i386_alu_imm_reg(I386_SUB, 1 * 4, REG_SP);
4778 i386_mov_imm_membase((s4) string_java_lang_NullPointerException, REG_SP, 0 * 4);
4779 i386_mov_imm_reg((s4) new_exception, REG_ITMP1);
4780 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4781 i386_alu_imm_reg(I386_ADD, 1 * 4, REG_SP);
4783 i386_pop_reg(REG_ITMP2_XPC);
4785 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4786 i386_jmp_reg(REG_ITMP3);
4791 codegen_finish((int)((u1*) mcodeptr - mcodebase));
4795 /* function createcompilerstub *************************************************
4797 creates a stub routine which calls the compiler
4799 *******************************************************************************/
4801 #define COMPSTUBSIZE 12
4803 u1 *createcompilerstub(methodinfo *m)
4805 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4806 mcodeptr = s; /* code generation pointer */
4808 /* code for the stub */
4809 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4811 /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching */
4812 i386_mov_imm_reg((s4) asm_call_jit_compiler, REG_ITMP3); /* load address */
4813 i386_jmp_reg(REG_ITMP3); /* jump to compiler */
4816 count_cstub_len += COMPSTUBSIZE;
4823 /* function removecompilerstub *************************************************
4825 deletes a compilerstub from memory (simply by freeing it)
4827 *******************************************************************************/
4829 void removecompilerstub(u1 *stub)
4831 CFREE(stub, COMPSTUBSIZE);
4834 /* function: createnativestub **************************************************
4836 creates a stub routine which calls a native method
4838 *******************************************************************************/
4840 #define NATIVESTUBSIZE 340
4842 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4843 static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
4846 void i386_native_stub_debug(void **p) {
4847 printf("Pos on stack: %p\n",p);
4848 printf("Return adress should be: %p\n",*p);
4851 void i386_native_stub_debug2(void **p) {
4852 printf("Pos on stack: %p\n",p);
4853 printf("Return for lookup is: %p\n",*p);
4856 void traverseStackInfo() {
4857 void **p=builtin_asm_get_stackframeinfo();
4860 printf("base addr:%p, methodinfo:%p\n",*p,(methodinfo*)((*p)+8));
4861 methodinfo *m=*((methodinfo**)((*p)+8));
4862 utf_display(m->name);
4870 u1 *createnativestub(functionptr f, methodinfo *m)
4872 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4876 int stackframesize = 4+12; /* initial 4 bytes is space for jni env,
4877 + 4 byte thread pointer + 4 byte previous pointer + method info*/
4878 int stackframeoffset = 4;
4882 mcodeptr = s; /* make macros work */
4884 if (m->flags & ACC_STATIC) {
4885 stackframesize += 4;
4886 stackframeoffset += 4;
4890 descriptor2types(m); /* set paramcount and paramtypes */
4893 /* i386_push_reg(REG_SP);
4894 i386_mov_imm_reg((s4) i386_native_stub_debug, REG_ITMP1);
4895 i386_call_reg(REG_ITMP1);
4896 i386_pop_reg(REG_ITMP1);*/
4900 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4902 for (p = 0; p < m->paramcount; p++) {
4903 t = m->paramtypes[p];
4904 if (IS_INT_LNG_TYPE(t)) {
4905 if (IS_2_WORD_TYPE(t)) {
4906 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4907 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4908 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4909 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4911 } else if (t == TYPE_ADR) {
4912 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4913 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4914 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4915 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4918 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
4920 i386_mov_reg_membase(EAX, REG_SP, p * 8);
4921 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
4925 if (t == TYPE_FLT) {
4926 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4927 i386_fstps_membase(REG_SP, p * 8);
4928 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4929 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4932 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4933 i386_fstpl_membase(REG_SP, p * 8);
4938 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4939 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4940 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4941 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4944 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
4946 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
4947 i386_call_reg(REG_ITMP1);
4949 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4953 * mark the whole fpu stack as free for native functions
4954 * (only for saved register count == 0)
4965 /* calculate stackframe size for native function */
4966 tptr = m->paramtypes;
4967 for (i = 0; i < m->paramcount; i++) {
4972 stackframesize += 4;
4977 stackframesize += 8;
4981 panic("unknown parameter type in native function");
4985 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
4987 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
4988 i386_mov_imm_membase((s4) m, REG_SP,stackframesize-4);
4989 i386_mov_imm_reg((s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
4990 i386_call_reg(REG_ITMP1);
4991 i386_mov_reg_membase(REG_RESULT,REG_SP,stackframesize-8); /*save thread specific pointer*/
4992 i386_mov_membase_reg(REG_RESULT,0,REG_ITMP2);
4993 i386_mov_reg_membase(REG_ITMP2,REG_SP,stackframesize-12); /*save previous value of memory adress pointed to by thread specific pointer*/
4994 i386_mov_reg_reg(REG_SP,REG_ITMP2);
4995 i386_alu_imm_reg(I386_ADD,stackframesize-12,REG_ITMP2);
4996 i386_mov_reg_membase(REG_ITMP2,REG_RESULT,0);
4999 /* i386_mov_imm_membase((s4) m, REG_SP,stackframesize-4);
5000 i386_mov_imm_membase((s4) m, REG_SP,stackframesize-8);
5001 i386_mov_imm_membase((s4) m, REG_SP,stackframesize-12);*/
5003 /* CREATE DYNAMIC STACK INFO -- END*/
5006 tptr = m->paramtypes;
5007 for (i = 0; i < m->paramcount; i++) {
5012 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5013 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5014 stackframeoffset += 4;
5019 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5020 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5021 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5022 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
5023 stackframeoffset += 8;
5027 panic("unknown parameter type in native function");
5031 if (m->flags & ACC_STATIC) {
5032 i386_mov_imm_membase((s4) m->class, REG_SP, 4);
5035 i386_mov_imm_membase((s4) &env, REG_SP, 0);
5037 i386_mov_imm_reg((s4) f, REG_ITMP1);
5038 i386_call_reg(REG_ITMP1);
5039 /*REMOVE DYNAMIC STACK INFO -BEGIN */
5040 i386_push_reg(REG_RESULT2);
5041 i386_mov_membase_reg(REG_SP,stackframesize-8,REG_ITMP2); /*old value*/
5042 i386_mov_membase_reg(REG_SP,stackframesize-4,REG_RESULT2); /*pointer*/
5043 i386_mov_reg_membase(REG_ITMP2,REG_RESULT2,0);
5044 i386_pop_reg(REG_RESULT2);
5045 /*REMOVE DYNAMIC STACK INFO -END */
5047 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
5051 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
5053 i386_mov_imm_membase((s4) m, REG_SP, 0);
5055 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
5056 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
5058 i386_fstl_membase(REG_SP, 4 + 8);
5059 i386_fsts_membase(REG_SP, 4 + 8 + 8);
5061 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
5062 i386_call_reg(REG_ITMP1);
5064 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
5065 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
5067 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
5071 /* we can't use REG_ITMP3 == REG_RESULT2 */
5072 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5073 i386_push_reg(REG_RESULT);
5074 i386_push_reg(REG_RESULT2);
5075 i386_call_mem((s4) &callgetexceptionptrptr);
5076 i386_mov_membase_reg(REG_RESULT, 0, REG_ITMP2);
5077 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
5078 i386_pop_reg(REG_RESULT2);
5079 i386_pop_reg(REG_RESULT);
5081 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP2);
5082 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP2);
5083 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
5085 i386_jcc(I386_CC_NE, 1);
5089 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5090 i386_push_reg(REG_ITMP2);
5091 i386_call_mem((s4) &callgetexceptionptrptr);
5092 i386_mov_imm_membase(0, REG_RESULT, 0);
5093 i386_pop_reg(REG_ITMP1_XPTR);
5095 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1_XPTR);
5096 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP2);
5097 i386_mov_imm_membase(0, REG_ITMP2, 0);
5099 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
5100 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
5102 i386_mov_imm_reg((s4) asm_handle_nat_exception, REG_ITMP3);
5103 i386_jmp_reg(REG_ITMP3);
5106 count_nstub_len += NATIVESTUBSIZE;
5112 /* function: removenativestub **************************************************
5114 removes a previously created native-stub from memory
5116 *******************************************************************************/
5118 void removenativestub(u1 *stub)
5120 CFREE(stub, NATIVESTUBSIZE);
5125 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
5127 if (iptr->dst->flags & INMEMORY) {
5128 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5129 if (src->regoff == iptr->dst->regoff) {
5130 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5131 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5133 } else if (src->prev->regoff == iptr->dst->regoff) {
5134 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5135 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5138 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5139 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5140 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5143 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5144 if (src->regoff == iptr->dst->regoff) {
5145 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5148 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5149 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
5150 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5153 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5154 if (src->prev->regoff == iptr->dst->regoff) {
5155 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
5158 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5159 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
5160 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5164 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5165 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
5169 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5170 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5171 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
5173 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5174 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5175 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
5177 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5178 M_INTMOVE(src->regoff, iptr->dst->regoff);
5179 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5182 if (src->regoff == iptr->dst->regoff) {
5183 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
5186 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5187 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
5195 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
5197 if (iptr->dst->flags & INMEMORY) {
5198 if (src->flags & INMEMORY) {
5199 if (src->regoff == iptr->dst->regoff) {
5200 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5203 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5204 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
5205 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5209 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5210 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5214 if (src->flags & INMEMORY) {
5215 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5216 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5219 M_INTMOVE(src->regoff, iptr->dst->regoff);
5220 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5227 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
5229 if (iptr->dst->flags & INMEMORY) {
5230 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5231 if (src->regoff == iptr->dst->regoff) {
5232 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5233 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5234 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5235 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5237 } else if (src->prev->regoff == iptr->dst->regoff) {
5238 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5239 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5240 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5241 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5244 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5245 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5246 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5247 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5248 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5249 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5257 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5259 if (iptr->dst->flags & INMEMORY) {
5260 if (src->flags & INMEMORY) {
5261 if (src->regoff == iptr->dst->regoff) {
5262 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5263 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5266 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5267 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5268 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5269 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5270 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP1);
5271 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5279 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5281 if (iptr->dst->flags & INMEMORY) {
5282 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5283 if (src->prev->regoff == iptr->dst->regoff) {
5284 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5285 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5288 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5289 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5290 i386_shift_reg(shift_op, REG_ITMP1);
5291 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5294 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5295 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5296 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5297 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5299 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5300 if (src->prev->regoff == iptr->dst->regoff) {
5301 M_INTMOVE(src->regoff, ECX);
5302 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5305 M_INTMOVE(src->regoff, ECX);
5306 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5307 i386_shift_reg(shift_op, REG_ITMP1);
5308 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5312 M_INTMOVE(src->regoff, ECX);
5313 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5314 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5318 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5319 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5320 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5321 i386_shift_reg(shift_op, iptr->dst->regoff);
5323 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5324 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5325 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5326 i386_shift_reg(shift_op, iptr->dst->regoff);
5328 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5329 M_INTMOVE(src->regoff, ECX);
5330 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5331 i386_shift_reg(shift_op, iptr->dst->regoff);
5334 M_INTMOVE(src->regoff, ECX);
5335 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5336 i386_shift_reg(shift_op, iptr->dst->regoff);
5343 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5345 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5346 if (src->regoff == iptr->dst->regoff) {
5347 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5350 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5351 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5352 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5355 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5356 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5357 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5359 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5360 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5361 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5364 M_INTMOVE(src->regoff, iptr->dst->regoff);
5365 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5371 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5373 if (iptr->dst->flags & INMEMORY) {
5376 if (src->flags & INMEMORY) {
5377 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5380 i386_test_reg_reg(src->regoff, src->regoff);
5384 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 8);
5386 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5387 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5389 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5390 i386_jmp_imm(offset);
5391 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5395 if (src->flags & INMEMORY) {
5396 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5399 i386_test_reg_reg(src->regoff, src->regoff);
5402 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5403 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5405 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5407 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5417 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5418 *(mcodeptr++) = (u1) 0x89;
5419 i386_emit_reg((reg),(dreg));
5423 void i386_mov_imm_reg(s4 imm, s4 reg) {
5424 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5425 i386_emit_imm32((imm));
5429 void i386_movb_imm_reg(s4 imm, s4 reg) {
5430 *(mcodeptr++) = (u1) 0xc6;
5431 i386_emit_reg(0,(reg));
5432 i386_emit_imm8((imm));
5436 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5437 *(mcodeptr++) = (u1) 0x8b;
5438 i386_emit_membase((basereg),(disp),(reg));
5443 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5444 * constant membase immediate length of 32bit
5446 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5447 *(mcodeptr++) = (u1) 0x8b;
5448 i386_address_byte(2, (reg), (basereg));
5449 i386_emit_imm32((disp));
5453 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5454 *(mcodeptr++) = (u1) 0x89;
5455 i386_emit_membase((basereg),(disp),(reg));
5459 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5460 *(mcodeptr++) = (u1) 0x8b;
5461 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5465 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5466 *(mcodeptr++) = (u1) 0x89;
5467 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5471 void i386_mov_mem_reg(s4 mem, s4 dreg) {
5472 *(mcodeptr++) = (u1) 0x8b;
5473 i386_emit_mem((dreg),(mem));
5477 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5478 *(mcodeptr++) = (u1) 0x66;
5479 *(mcodeptr++) = (u1) 0x89;
5480 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5484 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5485 *(mcodeptr++) = (u1) 0x88;
5486 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5490 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5491 *(mcodeptr++) = (u1) 0xc7;
5492 i386_emit_membase((basereg),(disp),0);
5493 i386_emit_imm32((imm));
5497 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5498 *(mcodeptr++) = (u1) 0x0f;
5499 *(mcodeptr++) = (u1) 0xbe;
5500 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5504 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5505 *(mcodeptr++) = (u1) 0x0f;
5506 *(mcodeptr++) = (u1) 0xbf;
5507 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5511 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5512 *(mcodeptr++) = (u1) 0x0f;
5513 *(mcodeptr++) = (u1) 0xb7;
5514 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5522 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5523 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5524 i386_emit_reg((reg),(dreg));
5528 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5529 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5530 i386_emit_membase((basereg),(disp),(reg));
5534 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5535 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5536 i386_emit_membase((basereg),(disp),(reg));
5540 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5541 if (i386_is_imm8(imm)) {
5542 *(mcodeptr++) = (u1) 0x83;
5543 i386_emit_reg((opc),(dreg));
5544 i386_emit_imm8((imm));
5546 *(mcodeptr++) = (u1) 0x81;
5547 i386_emit_reg((opc),(dreg));
5548 i386_emit_imm32((imm));
5553 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5554 if (i386_is_imm8(imm)) {
5555 *(mcodeptr++) = (u1) 0x83;
5556 i386_emit_membase((basereg),(disp),(opc));
5557 i386_emit_imm8((imm));
5559 *(mcodeptr++) = (u1) 0x81;
5560 i386_emit_membase((basereg),(disp),(opc));
5561 i386_emit_imm32((imm));
5566 void i386_test_reg_reg(s4 reg, s4 dreg) {
5567 *(mcodeptr++) = (u1) 0x85;
5568 i386_emit_reg((reg),(dreg));
5572 void i386_test_imm_reg(s4 imm, s4 reg) {
5573 *(mcodeptr++) = (u1) 0xf7;
5574 i386_emit_reg(0,(reg));
5575 i386_emit_imm32((imm));
5581 * inc, dec operations
5583 void i386_dec_mem(s4 mem) {
5584 *(mcodeptr++) = (u1) 0xff;
5585 i386_emit_mem(1,(mem));
5591 *(mcodeptr++) = (u1) 0x99;
5596 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5597 *(mcodeptr++) = (u1) 0x0f;
5598 *(mcodeptr++) = (u1) 0xaf;
5599 i386_emit_reg((dreg),(reg));
5603 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5604 *(mcodeptr++) = (u1) 0x0f;
5605 *(mcodeptr++) = (u1) 0xaf;
5606 i386_emit_membase((basereg),(disp),(dreg));
5610 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5611 if (i386_is_imm8((imm))) {
5612 *(mcodeptr++) = (u1) 0x6b;
5613 i386_emit_reg(0,(dreg));
5614 i386_emit_imm8((imm));
5616 *(mcodeptr++) = (u1) 0x69;
5617 i386_emit_reg(0,(dreg));
5618 i386_emit_imm32((imm));
5623 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5624 if (i386_is_imm8((imm))) {
5625 *(mcodeptr++) = (u1) 0x6b;
5626 i386_emit_reg((dreg),(reg));
5627 i386_emit_imm8((imm));
5629 *(mcodeptr++) = (u1) 0x69;
5630 i386_emit_reg((dreg),(reg));
5631 i386_emit_imm32((imm));
5636 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5637 if (i386_is_imm8((imm))) {
5638 *(mcodeptr++) = (u1) 0x6b;
5639 i386_emit_membase((basereg),(disp),(dreg));
5640 i386_emit_imm8((imm));
5642 *(mcodeptr++) = (u1) 0x69;
5643 i386_emit_membase((basereg),(disp),(dreg));
5644 i386_emit_imm32((imm));
5649 void i386_mul_membase(s4 basereg, s4 disp) {
5650 *(mcodeptr++) = (u1) 0xf7;
5651 i386_emit_membase((basereg),(disp),4);
5655 void i386_idiv_reg(s4 reg) {
5656 *(mcodeptr++) = (u1) 0xf7;
5657 i386_emit_reg(7,(reg));
5663 *(mcodeptr++) = (u1) 0xc3;
5671 void i386_shift_reg(s4 opc, s4 reg) {
5672 *(mcodeptr++) = (u1) 0xd3;
5673 i386_emit_reg((opc),(reg));
5677 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5678 *(mcodeptr++) = (u1) 0xd3;
5679 i386_emit_membase((basereg),(disp),(opc));
5683 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5685 *(mcodeptr++) = (u1) 0xd1;
5686 i386_emit_reg((opc),(dreg));
5688 *(mcodeptr++) = (u1) 0xc1;
5689 i386_emit_reg((opc),(dreg));
5690 i386_emit_imm8((imm));
5695 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5697 *(mcodeptr++) = (u1) 0xd1;
5698 i386_emit_membase((basereg),(disp),(opc));
5700 *(mcodeptr++) = (u1) 0xc1;
5701 i386_emit_membase((basereg),(disp),(opc));
5702 i386_emit_imm8((imm));
5707 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5708 *(mcodeptr++) = (u1) 0x0f;
5709 *(mcodeptr++) = (u1) 0xa5;
5710 i386_emit_reg((reg),(dreg));
5714 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5715 *(mcodeptr++) = (u1) 0x0f;
5716 *(mcodeptr++) = (u1) 0xa4;
5717 i386_emit_reg((reg),(dreg));
5718 i386_emit_imm8((imm));
5722 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5723 *(mcodeptr++) = (u1) 0x0f;
5724 *(mcodeptr++) = (u1) 0xa5;
5725 i386_emit_membase((basereg),(disp),(reg));
5729 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5730 *(mcodeptr++) = (u1) 0x0f;
5731 *(mcodeptr++) = (u1) 0xad;
5732 i386_emit_reg((reg),(dreg));
5736 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5737 *(mcodeptr++) = (u1) 0x0f;
5738 *(mcodeptr++) = (u1) 0xac;
5739 i386_emit_reg((reg),(dreg));
5740 i386_emit_imm8((imm));
5744 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5745 *(mcodeptr++) = (u1) 0x0f;
5746 *(mcodeptr++) = (u1) 0xad;
5747 i386_emit_membase((basereg),(disp),(reg));
5755 void i386_jmp_imm(s4 imm) {
5756 *(mcodeptr++) = (u1) 0xe9;
5757 i386_emit_imm32((imm));
5761 void i386_jmp_reg(s4 reg) {
5762 *(mcodeptr++) = (u1) 0xff;
5763 i386_emit_reg(4,(reg));
5767 void i386_jcc(s4 opc, s4 imm) {
5768 *(mcodeptr++) = (u1) 0x0f;
5769 *(mcodeptr++) = (u1) (0x80 + (opc));
5770 i386_emit_imm32((imm));
5776 * conditional set operations
5778 void i386_setcc_reg(s4 opc, s4 reg) {
5779 *(mcodeptr++) = (u1) 0x0f;
5780 *(mcodeptr++) = (u1) (0x90 + (opc));
5781 i386_emit_reg(0,(reg));
5785 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5786 *(mcodeptr++) = (u1) 0x0f;
5787 *(mcodeptr++) = (u1) (0x90 + (opc));
5788 i386_emit_membase((basereg),(disp),0);
5792 void i386_xadd_reg_mem(s4 reg, s4 mem) {
5793 *(mcodeptr++) = (u1) 0x0f;
5794 *(mcodeptr++) = (u1) 0xc1;
5795 i386_emit_mem((reg),(mem));
5799 void i386_neg_reg(s4 reg) {
5800 *(mcodeptr++) = (u1) 0xf7;
5801 i386_emit_reg(3,(reg));
5805 void i386_neg_membase(s4 basereg, s4 disp) {
5806 *(mcodeptr++) = (u1) 0xf7;
5807 i386_emit_membase((basereg),(disp),3);
5812 void i386_push_imm(s4 imm) {
5813 *(mcodeptr++) = (u1) 0x68;
5814 i386_emit_imm32((imm));
5818 void i386_pop_reg(s4 reg) {
5819 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5823 void i386_push_reg(s4 reg) {
5824 *(mcodeptr++) = (u1) 0x50 + (0x07 & (reg));
5829 *(mcodeptr++) = (u1) 0x90;
5834 *(mcodeptr++) = (u1) 0xf0;
5841 void i386_call_reg(s4 reg) {
5842 *(mcodeptr++) = (u1) 0xff;
5843 i386_emit_reg(2,(reg));
5847 void i386_call_imm(s4 imm) {
5848 *(mcodeptr++) = (u1) 0xe8;
5849 i386_emit_imm32((imm));
5853 void i386_call_mem(s4 mem) {
5854 *(mcodeptr++) = (u1) 0xff;
5855 i386_emit_mem(2, (mem));
5861 * floating point instructions
5864 *(mcodeptr++) = (u1) 0xd9;
5865 *(mcodeptr++) = (u1) 0xe8;
5870 *(mcodeptr++) = (u1) 0xd9;
5871 *(mcodeptr++) = (u1) 0xee;
5875 void i386_fld_reg(s4 reg) {
5876 *(mcodeptr++) = (u1) 0xd9;
5877 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5881 void i386_flds_membase(s4 basereg, s4 disp) {
5882 *(mcodeptr++) = (u1) 0xd9;
5883 i386_emit_membase((basereg),(disp),0);
5887 void i386_fldl_membase(s4 basereg, s4 disp) {
5888 *(mcodeptr++) = (u1) 0xdd;
5889 i386_emit_membase((basereg),(disp),0);
5893 void i386_fldt_membase(s4 basereg, s4 disp) {
5894 *(mcodeptr++) = (u1) 0xdb;
5895 i386_emit_membase((basereg),(disp),5);
5899 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5900 *(mcodeptr++) = (u1) 0xd9;
5901 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5905 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5906 *(mcodeptr++) = (u1) 0xdd;
5907 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5913 void i386_fildl_membase(s4 basereg, s4 disp) {
5914 *(mcodeptr++) = (u1) 0xdb;
5915 i386_emit_membase((basereg),(disp),0);
5919 void i386_fildll_membase(s4 basereg, s4 disp) {
5920 *(mcodeptr++) = (u1) 0xdf;
5921 i386_emit_membase((basereg),(disp),5);
5927 void i386_fst_reg(s4 reg) {
5928 *(mcodeptr++) = (u1) 0xdd;
5929 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5933 void i386_fsts_membase(s4 basereg, s4 disp) {
5934 *(mcodeptr++) = (u1) 0xd9;
5935 i386_emit_membase((basereg),(disp),2);
5939 void i386_fstl_membase(s4 basereg, s4 disp) {
5940 *(mcodeptr++) = (u1) 0xdd;
5941 i386_emit_membase((basereg),(disp),2);
5945 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5946 *(mcodeptr++) = (u1) 0xd9;
5947 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5951 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5952 *(mcodeptr++) = (u1) 0xdd;
5953 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
5957 void i386_fstp_reg(s4 reg) {
5958 *(mcodeptr++) = (u1) 0xdd;
5959 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
5963 void i386_fstps_membase(s4 basereg, s4 disp) {
5964 *(mcodeptr++) = (u1) 0xd9;
5965 i386_emit_membase((basereg),(disp),3);
5969 void i386_fstpl_membase(s4 basereg, s4 disp) {
5970 *(mcodeptr++) = (u1) 0xdd;
5971 i386_emit_membase((basereg),(disp),3);
5975 void i386_fstpt_membase(s4 basereg, s4 disp) {
5976 *(mcodeptr++) = (u1) 0xdb;
5977 i386_emit_membase((basereg),(disp),7);
5981 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5982 *(mcodeptr++) = (u1) 0xd9;
5983 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5987 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5988 *(mcodeptr++) = (u1) 0xdd;
5989 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
5993 void i386_fistl_membase(s4 basereg, s4 disp) {
5994 *(mcodeptr++) = (u1) 0xdb;
5995 i386_emit_membase((basereg),(disp),2);
5999 void i386_fistpl_membase(s4 basereg, s4 disp) {
6000 *(mcodeptr++) = (u1) 0xdb;
6001 i386_emit_membase((basereg),(disp),3);
6005 void i386_fistpll_membase(s4 basereg, s4 disp) {
6006 *(mcodeptr++) = (u1) 0xdf;
6007 i386_emit_membase((basereg),(disp),7);
6012 *(mcodeptr++) = (u1) 0xd9;
6013 *(mcodeptr++) = (u1) 0xe0;
6018 *(mcodeptr++) = (u1) 0xde;
6019 *(mcodeptr++) = (u1) 0xc1;
6023 void i386_fadd_reg_st(s4 reg) {
6024 *(mcodeptr++) = (u1) 0xd8;
6025 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
6029 void i386_fadd_st_reg(s4 reg) {
6030 *(mcodeptr++) = (u1) 0xdc;
6031 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
6035 void i386_faddp_st_reg(s4 reg) {
6036 *(mcodeptr++) = (u1) 0xde;
6037 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
6041 void i386_fadds_membase(s4 basereg, s4 disp) {
6042 *(mcodeptr++) = (u1) 0xd8;
6043 i386_emit_membase((basereg),(disp),0);
6047 void i386_faddl_membase(s4 basereg, s4 disp) {
6048 *(mcodeptr++) = (u1) 0xdc;
6049 i386_emit_membase((basereg),(disp),0);
6053 void i386_fsub_reg_st(s4 reg) {
6054 *(mcodeptr++) = (u1) 0xd8;
6055 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
6059 void i386_fsub_st_reg(s4 reg) {
6060 *(mcodeptr++) = (u1) 0xdc;
6061 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6065 void i386_fsubp_st_reg(s4 reg) {
6066 *(mcodeptr++) = (u1) 0xde;
6067 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6072 *(mcodeptr++) = (u1) 0xde;
6073 *(mcodeptr++) = (u1) 0xe9;
6077 void i386_fsubs_membase(s4 basereg, s4 disp) {
6078 *(mcodeptr++) = (u1) 0xd8;
6079 i386_emit_membase((basereg),(disp),4);
6083 void i386_fsubl_membase(s4 basereg, s4 disp) {
6084 *(mcodeptr++) = (u1) 0xdc;
6085 i386_emit_membase((basereg),(disp),4);
6089 void i386_fmul_reg_st(s4 reg) {
6090 *(mcodeptr++) = (u1) 0xd8;
6091 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6095 void i386_fmul_st_reg(s4 reg) {
6096 *(mcodeptr++) = (u1) 0xdc;
6097 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6102 *(mcodeptr++) = (u1) 0xde;
6103 *(mcodeptr++) = (u1) 0xc9;
6107 void i386_fmulp_st_reg(s4 reg) {
6108 *(mcodeptr++) = (u1) 0xde;
6109 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6113 void i386_fmuls_membase(s4 basereg, s4 disp) {
6114 *(mcodeptr++) = (u1) 0xd8;
6115 i386_emit_membase((basereg),(disp),1);
6119 void i386_fmull_membase(s4 basereg, s4 disp) {
6120 *(mcodeptr++) = (u1) 0xdc;
6121 i386_emit_membase((basereg),(disp),1);
6125 void i386_fdiv_reg_st(s4 reg) {
6126 *(mcodeptr++) = (u1) 0xd8;
6127 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
6131 void i386_fdiv_st_reg(s4 reg) {
6132 *(mcodeptr++) = (u1) 0xdc;
6133 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
6138 *(mcodeptr++) = (u1) 0xde;
6139 *(mcodeptr++) = (u1) 0xf9;
6143 void i386_fdivp_st_reg(s4 reg) {
6144 *(mcodeptr++) = (u1) 0xde;
6145 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
6150 *(mcodeptr++) = (u1) 0xd9;
6151 *(mcodeptr++) = (u1) 0xc9;
6155 void i386_fxch_reg(s4 reg) {
6156 *(mcodeptr++) = (u1) 0xd9;
6157 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6162 *(mcodeptr++) = (u1) 0xd9;
6163 *(mcodeptr++) = (u1) 0xf8;
6167 void i386_fprem1() {
6168 *(mcodeptr++) = (u1) 0xd9;
6169 *(mcodeptr++) = (u1) 0xf5;
6174 *(mcodeptr++) = (u1) 0xdd;
6175 *(mcodeptr++) = (u1) 0xe1;
6179 void i386_fucom_reg(s4 reg) {
6180 *(mcodeptr++) = (u1) 0xdd;
6181 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
6185 void i386_fucomp_reg(s4 reg) {
6186 *(mcodeptr++) = (u1) 0xdd;
6187 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6191 void i386_fucompp() {
6192 *(mcodeptr++) = (u1) 0xda;
6193 *(mcodeptr++) = (u1) 0xe9;
6197 void i386_fnstsw() {
6198 *(mcodeptr++) = (u1) 0xdf;
6199 *(mcodeptr++) = (u1) 0xe0;
6204 *(mcodeptr++) = (u1) 0x9e;
6209 *(mcodeptr++) = (u1) 0x9b;
6210 *(mcodeptr++) = (u1) 0xdb;
6211 *(mcodeptr++) = (u1) 0xe3;
6215 void i386_fldcw_mem(s4 mem) {
6216 *(mcodeptr++) = (u1) 0xd9;
6217 i386_emit_mem(5,(mem));
6221 void i386_fldcw_membase(s4 basereg, s4 disp) {
6222 *(mcodeptr++) = (u1) 0xd9;
6223 i386_emit_membase((basereg),(disp),5);
6228 *(mcodeptr++) = (u1) 0x9b;
6232 void i386_ffree_reg(s4 reg) {
6233 *(mcodeptr++) = (u1) 0xdd;
6234 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
6238 void i386_fdecstp() {
6239 *(mcodeptr++) = (u1) 0xd9;
6240 *(mcodeptr++) = (u1) 0xf6;
6244 void i386_fincstp() {
6245 *(mcodeptr++) = (u1) 0xd9;
6246 *(mcodeptr++) = (u1) 0xf7;
6251 * These are local overrides for various environment variables in Emacs.
6252 * Please do not remove this and leave it at the end of the file, where
6253 * Emacs will automagically detect them.
6254 * ---------------------------------------------------------------------
6257 * indent-tabs-mode: t