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 1048 2004-05-03 18:53:19Z 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); \
316 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
317 void thread_restartcriticalsection(ucontext_t *uc)
320 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[REG_EIP])) != NULL)
321 uc->uc_mcontext.gregs[REG_EIP] = (u4) critical;
325 /* NullPointerException signal handler for hardware null pointer check */
327 void catch_NullPointerException(int sig)
330 /* long faultaddr; */
332 void **_p = (void **) &sig;
333 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
334 java_objectheader *xptr;
336 /* Reset signal handler - necessary for SysV, does no harm for BSD */
338 /* instr = *((int*)(sigctx->eip)); */
339 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
341 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip); */
343 /* if (faultaddr == 0) { */
344 signal(sig, (void *) catch_NullPointerException); /* reinstall handler */
346 sigaddset(&nsig, sig);
347 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
349 xptr = new_exception(string_java_lang_NullPointerException);
351 sigctx->eax = (s4) xptr; /* REG_ITMP1_XPTR */
352 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
353 sigctx->eip = (s4) asm_handle_exception;
358 /* faultaddr += (long) ((instr << 16) >> 16); */
359 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
360 /* panic("Stack overflow"); */
365 /* ArithmeticException signal handler for hardware divide by zero check */
367 void catch_ArithmeticException(int sig)
371 void **_p = (void **) &sig;
372 struct sigcontext *sigctx = (struct sigcontext *) ++_p;
373 java_objectheader *xptr;
375 /* Reset signal handler - necessary for SysV, does no harm for BSD */
377 signal(sig, (void *) catch_ArithmeticException); /* reinstall handler */
379 sigaddset(&nsig, sig);
380 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
382 xptr = new_exception_message(string_java_lang_ArithmeticException,
383 string_java_lang_ArithmeticException_message);
385 sigctx->eax = (s4) xptr; /* REG_ITMP1_XPTR */
386 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
387 sigctx->eip = (s4) asm_handle_exception;
393 void init_exceptions(void)
395 /* install signal handlers we need to convert to exceptions */
399 signal(SIGSEGV, (void *) catch_NullPointerException);
403 signal(SIGBUS, (void *) catch_NullPointerException);
407 signal(SIGFPE, (void *) catch_ArithmeticException);
411 /* function codegen ************************************************************
413 generates machine code
415 *******************************************************************************/
417 /* global code generation pointer */
422 int len, s1, s2, s3, d;
429 int fpu_st_offset = 0;
433 if (compileverbose) {
434 char logtext[MAXLOGTEXT];
435 sprintf(logtext, "Generating code: ");
436 utf_sprint_classname(logtext + strlen(logtext), class->name);
437 sprintf(logtext + strlen(logtext), ".");
438 utf_sprint(logtext + strlen(logtext), method->name);
439 utf_sprint_classname(logtext + strlen(logtext), descriptor);
448 /* space to save used callee saved registers */
450 savedregs_num += (savintregcnt - maxsavintreguse);
451 savedregs_num += (savfltregcnt - maxsavfltreguse);
453 parentargs_base = maxmemuse + savedregs_num;
455 #ifdef USE_THREADS /* space to save argument of monitor_enter */
457 if (checksync && (method->flags & ACC_SYNCHRONIZED))
462 /* create method header */
464 (void) dseg_addaddress(method); /* MethodPointer */
465 (void) dseg_adds4(parentargs_base * 8); /* FrameSize */
469 /* IsSync contains the offset relative to the stack pointer for the
470 argument of monitor_exit used in the exception handler. Since the
471 offset could be zero and give a wrong meaning of the flag it is
475 if (checksync && (method->flags & ACC_SYNCHRONIZED))
476 (void) dseg_adds4((maxmemuse + 1) * 8); /* IsSync */
481 (void) dseg_adds4(0); /* IsSync */
483 (void) dseg_adds4(isleafmethod); /* IsLeaf */
484 (void) dseg_adds4(savintregcnt - maxsavintreguse); /* IntSave */
485 (void) dseg_adds4(savfltregcnt - maxsavfltreguse); /* FltSave */
486 (void) dseg_addlinenumbertablesize(); /* adds a reference for the length of the line number counter
487 We don't know the size yet, since we evaluate the information
488 during code generation, to save one additional iteration over
489 the whole instructions. During code optimization the position
490 could have changed to the information gotten from the class file*/
491 (void) dseg_adds4(exceptiontablelength); /* ExTableSize */
493 /* create exception table */
495 for (ex = extable; ex != NULL; ex = ex->down) {
496 dseg_addtarget(ex->start);
497 dseg_addtarget(ex->end);
498 dseg_addtarget(ex->handler);
499 (void) dseg_addaddress(ex->catchtype);
503 /* initialize mcode variables */
505 mcodeptr = (u1*) mcodebase;
506 mcodeend = (s4*) (mcodebase + mcodesize);
507 MCODECHECK(128 + mparamcount);
509 /* create stack frame (if necessary) */
511 if (parentargs_base) {
512 i386_alu_imm_reg(I386_SUB, parentargs_base * 8, REG_SP);
515 /* save return address and used callee saved registers */
518 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
519 p--; i386_mov_reg_membase(savintregs[r], REG_SP, p * 8);
521 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
522 p--; i386_fld_reg(savfltregs[r]); i386_fstpl_membase(REG_SP, p * 8);
525 /* save monitorenter argument */
528 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
529 if (method->flags & ACC_STATIC) {
530 i386_mov_imm_reg((s4) class, REG_ITMP1);
531 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
534 i386_mov_membase_reg(REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
535 i386_mov_reg_membase(REG_ITMP1, REG_SP, maxmemuse * 8);
540 /* copy argument registers to stack and call trace function with pointer
541 to arguments on stack.
545 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
547 for (p = 0; p < mparamcount && p < TRACE_ARGS_NUM; p++) {
550 if (IS_INT_LNG_TYPE(t)) {
551 if (IS_2_WORD_TYPE(t)) {
552 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
553 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
554 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP1);
555 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
557 /* } else if (t == TYPE_ADR) { */
559 i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
560 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
561 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
562 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
565 /* i386_mov_membase_reg(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX); */
567 /* i386_mov_reg_membase(EAX, REG_SP, p * 8); */
568 /* i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4); */
572 if (!IS_2_WORD_TYPE(t)) {
573 i386_flds_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
574 i386_fstps_membase(REG_SP, p * 8);
575 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
576 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
579 i386_fldl_membase(REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
580 i386_fstpl_membase(REG_SP, p * 8);
585 /* fill up the remaining arguments */
586 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
587 for (p = mparamcount; p < TRACE_ARGS_NUM; p++) {
588 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
589 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
592 i386_mov_imm_membase((s4) method, REG_SP, TRACE_ARGS_NUM * 8);
593 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
594 i386_call_reg(REG_ITMP1);
596 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
599 /* take arguments out of register or stack frame */
601 for (p = 0, l = 0; p < mparamcount; p++) {
603 var = &(locals[l][t]);
605 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
610 if (IS_INT_LNG_TYPE(t)) { /* integer args */
611 if (p < intreg_argnum) { /* register arguments */
612 panic("integer register argument");
613 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
614 /* M_INTMOVE (argintregs[p], r); */
616 } else { /* reg arg -> spilled */
617 /* M_LST (argintregs[p], REG_SP, 8 * r); */
619 } else { /* stack arguments */
620 pa = p - intreg_argnum;
621 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
622 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, r); /* + 4 for return address */
623 } else { /* stack arg -> spilled */
624 if (!IS_2_WORD_TYPE(t)) {
625 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
626 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
629 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
630 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8);
631 i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP1); /* + 4 for return address */
632 i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8 + 4);
637 } else { /* floating args */
638 if (p < fltreg_argnum) { /* register arguments */
639 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
640 panic("There are no float argument registers!");
642 } else { /* reg arg -> spilled */
643 panic("There are no float argument registers!");
646 } else { /* stack arguments */
647 pa = p - fltreg_argnum;
648 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
650 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
652 i386_fstp_reg(r + fpu_st_offset);
656 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
658 i386_fstp_reg(r + fpu_st_offset);
662 } else { /* stack-arg -> spilled */
663 /* i386_mov_membase_reg(REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
664 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, r * 8); */
666 i386_flds_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
667 i386_fstps_membase(REG_SP, r * 8);
670 i386_fldl_membase(REG_SP, (parentargs_base + pa) * 8 + 4);
671 i386_fstpl_membase(REG_SP, r * 8);
678 /* call monitorenter function */
681 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
682 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP1);
683 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
684 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
685 i386_mov_imm_reg((s4) builtin_monitorenter, REG_ITMP1);
686 i386_call_reg(REG_ITMP1);
687 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
692 /* end of header generation */
694 /* walk through all basic blocks */
695 for (bptr = block; bptr != NULL; bptr = bptr->next) {
697 bptr->mpc = (int)((u1*) mcodeptr - mcodebase);
699 if (bptr->flags >= BBREACHED) {
701 /* branch resolving */
704 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
705 gen_resolvebranch((u1*) mcodebase + brefs->branchpos,
706 brefs->branchpos, bptr->mpc);
709 /* copy interface registers to their destination */
714 while (src != NULL) {
716 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
717 if (!IS_2_WORD_TYPE(src->type)) {
718 if (bptr->type == BBTYPE_SBR) {
719 d = reg_of_var(src, REG_ITMP1);
721 store_reg_to_var_int(src, d);
723 } else if (bptr->type == BBTYPE_EXH) {
724 d = reg_of_var(src, REG_ITMP1);
725 M_INTMOVE(REG_ITMP1, d);
726 store_reg_to_var_int(src, d);
730 panic("copy interface registers: longs have to me in memory (begin 1)");
734 d = reg_of_var(src, REG_ITMP1);
735 if ((src->varkind != STACKVAR)) {
737 if (IS_FLT_DBL_TYPE(s2)) {
738 s1 = interfaces[len][s2].regoff;
739 if (!(interfaces[len][s2].flags & INMEMORY)) {
743 if (s2 == TYPE_FLT) {
744 i386_flds_membase(REG_SP, s1 * 8);
747 i386_fldl_membase(REG_SP, s1 * 8);
750 store_reg_to_var_flt(src, d);
753 s1 = interfaces[len][s2].regoff;
754 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
755 if (!(interfaces[len][s2].flags & INMEMORY)) {
759 i386_mov_membase_reg(REG_SP, s1 * 8, d);
761 store_reg_to_var_int(src, d);
764 if (interfaces[len][s2].flags & INMEMORY) {
765 M_LNGMEMMOVE(s1, src->regoff);
768 panic("copy interface registers: longs have to be in memory (begin 2)");
777 /* walk through all instructions */
781 for (iptr = bptr->iinstr;
783 src = iptr->dst, len--, iptr++) {
785 if (iptr->line!=currentline) {
786 dseg_addlinenumber(iptr->line,mcodeptr);
787 currentline=iptr->line;
789 MCODECHECK(64); /* an instruction usually needs < 64 words */
792 case ICMD_NOP: /* ... ==> ... */
795 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
796 if (src->flags & INMEMORY) {
797 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
800 i386_test_reg_reg(src->regoff, src->regoff);
802 i386_jcc(I386_CC_E, 0);
803 codegen_addxnullrefs(mcodeptr);
806 /* constant operations ************************************************/
808 case ICMD_ICONST: /* ... ==> ..., constant */
809 /* op1 = 0, val.i = constant */
811 d = reg_of_var(iptr->dst, REG_ITMP1);
812 if (iptr->dst->flags & INMEMORY) {
813 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
816 if (iptr->val.i == 0) {
817 i386_alu_reg_reg(I386_XOR, d, d);
820 i386_mov_imm_reg(iptr->val.i, d);
825 case ICMD_LCONST: /* ... ==> ..., constant */
826 /* op1 = 0, val.l = constant */
828 d = reg_of_var(iptr->dst, REG_ITMP1);
829 if (iptr->dst->flags & INMEMORY) {
830 i386_mov_imm_membase(iptr->val.l, REG_SP, iptr->dst->regoff * 8);
831 i386_mov_imm_membase(iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
834 panic("LCONST: longs have to be in memory");
838 case ICMD_FCONST: /* ... ==> ..., constant */
839 /* op1 = 0, val.f = constant */
841 d = reg_of_var(iptr->dst, REG_FTMP1);
842 if (iptr->val.f == 0.0) {
847 if (iptr->val.i == 0x80000000) {
851 } else if (iptr->val.f == 1.0) {
855 } else if (iptr->val.f == 2.0) {
862 a = dseg_addfloat(iptr->val.f);
863 i386_mov_imm_reg(0, REG_ITMP1);
864 dseg_adddata(mcodeptr);
865 i386_flds_membase(REG_ITMP1, a);
868 store_reg_to_var_flt(iptr->dst, d);
871 case ICMD_DCONST: /* ... ==> ..., constant */
872 /* op1 = 0, val.d = constant */
874 d = reg_of_var(iptr->dst, REG_FTMP1);
875 if (iptr->val.d == 0.0) {
880 if (iptr->val.l == 0x8000000000000000LL) {
884 } else if (iptr->val.d == 1.0) {
888 } else if (iptr->val.d == 2.0) {
895 a = dseg_adddouble(iptr->val.d);
896 i386_mov_imm_reg(0, REG_ITMP1);
897 dseg_adddata(mcodeptr);
898 i386_fldl_membase(REG_ITMP1, a);
901 store_reg_to_var_flt(iptr->dst, d);
904 case ICMD_ACONST: /* ... ==> ..., constant */
905 /* op1 = 0, val.a = constant */
907 d = reg_of_var(iptr->dst, REG_ITMP1);
908 if (iptr->dst->flags & INMEMORY) {
909 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
912 if ((s4) iptr->val.a == 0) {
913 i386_alu_reg_reg(I386_XOR, d, d);
916 i386_mov_imm_reg((s4) iptr->val.a, d);
922 /* load/store operations **********************************************/
924 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
925 case ICMD_ALOAD: /* op1 = local variable */
927 d = reg_of_var(iptr->dst, REG_ITMP1);
928 if ((iptr->dst->varkind == LOCALVAR) &&
929 (iptr->dst->varnum == iptr->op1)) {
932 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
933 if (iptr->dst->flags & INMEMORY) {
934 if (var->flags & INMEMORY) {
935 i386_mov_membase_reg(REG_SP, var->regoff * 8, REG_ITMP1);
936 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
939 i386_mov_reg_membase(var->regoff, REG_SP, iptr->dst->regoff * 8);
943 if (var->flags & INMEMORY) {
944 i386_mov_membase_reg(REG_SP, var->regoff * 8, iptr->dst->regoff);
947 M_INTMOVE(var->regoff, iptr->dst->regoff);
952 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
953 /* op1 = local variable */
955 d = reg_of_var(iptr->dst, REG_ITMP1);
956 if ((iptr->dst->varkind == LOCALVAR) &&
957 (iptr->dst->varnum == iptr->op1)) {
960 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
961 if (iptr->dst->flags & INMEMORY) {
962 if (var->flags & INMEMORY) {
963 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
966 panic("LLOAD: longs have to be in memory");
970 panic("LLOAD: longs have to be in memory");
974 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
975 /* op1 = local variable */
977 d = reg_of_var(iptr->dst, REG_FTMP1);
978 if ((iptr->dst->varkind == LOCALVAR) &&
979 (iptr->dst->varnum == iptr->op1)) {
982 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
983 if (var->flags & INMEMORY) {
984 i386_flds_membase(REG_SP, var->regoff * 8);
987 i386_fld_reg(var->regoff + fpu_st_offset);
990 store_reg_to_var_flt(iptr->dst, d);
993 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
994 /* op1 = local variable */
996 d = reg_of_var(iptr->dst, REG_FTMP1);
997 if ((iptr->dst->varkind == LOCALVAR) &&
998 (iptr->dst->varnum == iptr->op1)) {
1001 var = &(locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
1002 if (var->flags & INMEMORY) {
1003 i386_fldl_membase(REG_SP, var->regoff * 8);
1006 i386_fld_reg(var->regoff + fpu_st_offset);
1009 store_reg_to_var_flt(iptr->dst, d);
1012 case ICMD_ISTORE: /* ..., value ==> ... */
1013 case ICMD_ASTORE: /* op1 = local variable */
1015 if ((src->varkind == LOCALVAR) &&
1016 (src->varnum == iptr->op1)) {
1019 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1020 if (var->flags & INMEMORY) {
1021 if (src->flags & INMEMORY) {
1022 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1023 i386_mov_reg_membase(REG_ITMP1, REG_SP, var->regoff * 8);
1026 i386_mov_reg_membase(src->regoff, REG_SP, var->regoff * 8);
1030 var_to_reg_int(s1, src, var->regoff);
1031 M_INTMOVE(s1, var->regoff);
1035 case ICMD_LSTORE: /* ..., value ==> ... */
1036 /* op1 = local variable */
1038 if ((src->varkind == LOCALVAR) &&
1039 (src->varnum == iptr->op1)) {
1042 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1043 if (var->flags & INMEMORY) {
1044 if (src->flags & INMEMORY) {
1045 M_LNGMEMMOVE(src->regoff, var->regoff);
1048 panic("LSTORE: longs have to be in memory");
1052 panic("LSTORE: longs have to be in memory");
1056 case ICMD_FSTORE: /* ..., value ==> ... */
1057 /* op1 = local variable */
1059 if ((src->varkind == LOCALVAR) &&
1060 (src->varnum == iptr->op1)) {
1063 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1064 if (var->flags & INMEMORY) {
1065 var_to_reg_flt(s1, src, REG_FTMP1);
1066 i386_fstps_membase(REG_SP, var->regoff * 8);
1069 var_to_reg_flt(s1, src, var->regoff);
1070 /* M_FLTMOVE(s1, var->regoff); */
1071 i386_fstp_reg(var->regoff + fpu_st_offset);
1076 case ICMD_DSTORE: /* ..., value ==> ... */
1077 /* op1 = local variable */
1079 if ((src->varkind == LOCALVAR) &&
1080 (src->varnum == iptr->op1)) {
1083 var = &(locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
1084 if (var->flags & INMEMORY) {
1085 var_to_reg_flt(s1, src, REG_FTMP1);
1086 i386_fstpl_membase(REG_SP, var->regoff * 8);
1089 var_to_reg_flt(s1, src, var->regoff);
1090 /* M_FLTMOVE(s1, var->regoff); */
1091 i386_fstp_reg(var->regoff + fpu_st_offset);
1097 /* pop/dup/swap operations ********************************************/
1099 /* attention: double and longs are only one entry in CACAO ICMDs */
1101 case ICMD_POP: /* ..., value ==> ... */
1102 case ICMD_POP2: /* ..., value, value ==> ... */
1105 #define M_COPY(from,to) \
1106 d = reg_of_var(to, REG_ITMP1); \
1107 if ((from->regoff != to->regoff) || \
1108 ((from->flags ^ to->flags) & INMEMORY)) { \
1109 if (IS_FLT_DBL_TYPE(from->type)) { \
1110 var_to_reg_flt(s1, from, d); \
1111 /* M_FLTMOVE(s1, d);*/ \
1112 store_reg_to_var_flt(to, d); \
1114 if (!IS_2_WORD_TYPE(from->type)) { \
1115 if (to->flags & INMEMORY) { \
1116 if (from->flags & INMEMORY) { \
1117 i386_mov_membase_reg(REG_SP, from->regoff * 8, REG_ITMP1); \
1118 i386_mov_reg_membase(REG_ITMP1, REG_SP, to->regoff * 8); \
1120 i386_mov_reg_membase(from->regoff, REG_SP, to->regoff * 8); \
1123 if (from->flags & INMEMORY) { \
1124 i386_mov_membase_reg(REG_SP, from->regoff * 8, to->regoff); \
1126 i386_mov_reg_reg(from->regoff, to->regoff); \
1130 M_LNGMEMMOVE(from->regoff, to->regoff); \
1135 case ICMD_DUP: /* ..., a ==> ..., a, a */
1136 M_COPY(src, iptr->dst);
1139 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
1141 M_COPY(src, iptr->dst->prev->prev);
1143 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
1145 M_COPY(src, iptr->dst);
1146 M_COPY(src->prev, iptr->dst->prev);
1149 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
1151 M_COPY(src->prev, iptr->dst->prev->prev->prev);
1153 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
1155 M_COPY(src, iptr->dst);
1156 M_COPY(src->prev, iptr->dst->prev);
1157 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1158 M_COPY(src, iptr->dst->prev->prev->prev);
1161 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1163 M_COPY(src, iptr->dst);
1164 M_COPY(src->prev, iptr->dst->prev);
1165 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1166 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1167 M_COPY(src, iptr->dst->prev->prev->prev->prev);
1168 M_COPY(src->prev, iptr->dst->prev->prev->prev->prev->prev);
1171 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1173 M_COPY(src, iptr->dst->prev);
1174 M_COPY(src->prev, iptr->dst);
1178 /* integer operations *************************************************/
1180 case ICMD_INEG: /* ..., value ==> ..., - value */
1182 d = reg_of_var(iptr->dst, REG_NULL);
1183 if (iptr->dst->flags & INMEMORY) {
1184 if (src->flags & INMEMORY) {
1185 if (src->regoff == iptr->dst->regoff) {
1186 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1189 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1190 i386_neg_reg(REG_ITMP1);
1191 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1195 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1196 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1200 if (src->flags & INMEMORY) {
1201 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1202 i386_neg_reg(iptr->dst->regoff);
1205 M_INTMOVE(src->regoff, iptr->dst->regoff);
1206 i386_neg_reg(iptr->dst->regoff);
1211 case ICMD_LNEG: /* ..., value ==> ..., - value */
1213 d = reg_of_var(iptr->dst, REG_NULL);
1214 if (iptr->dst->flags & INMEMORY) {
1215 if (src->flags & INMEMORY) {
1216 if (src->regoff == iptr->dst->regoff) {
1217 i386_neg_membase(REG_SP, iptr->dst->regoff * 8);
1218 i386_alu_imm_membase(I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1219 i386_neg_membase(REG_SP, iptr->dst->regoff * 8 + 4);
1222 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1223 i386_neg_reg(REG_ITMP1);
1224 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1225 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1226 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP1);
1227 i386_neg_reg(REG_ITMP1);
1228 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1234 case ICMD_I2L: /* ..., value ==> ..., value */
1236 d = reg_of_var(iptr->dst, REG_NULL);
1237 if (iptr->dst->flags & INMEMORY) {
1238 if (src->flags & INMEMORY) {
1239 i386_mov_membase_reg(REG_SP, src->regoff * 8, EAX);
1241 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1242 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1245 M_INTMOVE(src->regoff, EAX);
1247 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1248 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1253 case ICMD_L2I: /* ..., value ==> ..., value */
1255 d = reg_of_var(iptr->dst, REG_NULL);
1256 if (iptr->dst->flags & INMEMORY) {
1257 if (src->flags & INMEMORY) {
1258 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1259 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1263 if (src->flags & INMEMORY) {
1264 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1269 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1271 d = reg_of_var(iptr->dst, REG_NULL);
1272 if (iptr->dst->flags & INMEMORY) {
1273 if (src->flags & INMEMORY) {
1274 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1275 i386_shift_imm_reg(I386_SHL, 24, REG_ITMP1);
1276 i386_shift_imm_reg(I386_SAR, 24, REG_ITMP1);
1277 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1280 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1281 i386_shift_imm_membase(I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1282 i386_shift_imm_membase(I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1286 if (src->flags & INMEMORY) {
1287 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1288 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1289 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1292 M_INTMOVE(src->regoff, iptr->dst->regoff);
1293 i386_shift_imm_reg(I386_SHL, 24, iptr->dst->regoff);
1294 i386_shift_imm_reg(I386_SAR, 24, iptr->dst->regoff);
1299 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1301 d = reg_of_var(iptr->dst, REG_NULL);
1302 if (iptr->dst->flags & INMEMORY) {
1303 if (src->flags & INMEMORY) {
1304 if (src->regoff == iptr->dst->regoff) {
1305 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1308 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1309 i386_alu_imm_reg(I386_AND, 0x0000ffff, REG_ITMP1);
1310 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1314 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1315 i386_alu_imm_membase(I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1319 if (src->flags & INMEMORY) {
1320 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1321 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1324 M_INTMOVE(src->regoff, iptr->dst->regoff);
1325 i386_alu_imm_reg(I386_AND, 0x0000ffff, iptr->dst->regoff);
1330 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1332 d = reg_of_var(iptr->dst, REG_NULL);
1333 if (iptr->dst->flags & INMEMORY) {
1334 if (src->flags & INMEMORY) {
1335 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1336 i386_shift_imm_reg(I386_SHL, 16, REG_ITMP1);
1337 i386_shift_imm_reg(I386_SAR, 16, REG_ITMP1);
1338 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1341 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
1342 i386_shift_imm_membase(I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1343 i386_shift_imm_membase(I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1347 if (src->flags & INMEMORY) {
1348 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1349 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1350 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1353 M_INTMOVE(src->regoff, iptr->dst->regoff);
1354 i386_shift_imm_reg(I386_SHL, 16, iptr->dst->regoff);
1355 i386_shift_imm_reg(I386_SAR, 16, iptr->dst->regoff);
1361 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1363 d = reg_of_var(iptr->dst, REG_NULL);
1364 i386_emit_ialu(I386_ADD, src, iptr);
1367 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1368 /* val.i = constant */
1370 d = reg_of_var(iptr->dst, REG_NULL);
1371 /* should we use a inc optimization for smaller code size? */
1372 i386_emit_ialuconst(I386_ADD, src, iptr);
1375 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1377 d = reg_of_var(iptr->dst, REG_NULL);
1378 if (iptr->dst->flags & INMEMORY) {
1379 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1380 if (src->regoff == iptr->dst->regoff) {
1381 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1382 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1383 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1384 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1386 } else if (src->prev->regoff == iptr->dst->regoff) {
1387 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1388 i386_alu_reg_membase(I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1389 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1390 i386_alu_reg_membase(I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1393 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1394 i386_alu_membase_reg(I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1395 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1396 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1397 i386_alu_membase_reg(I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1398 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1405 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1406 /* val.l = constant */
1408 d = reg_of_var(iptr->dst, REG_NULL);
1409 if (iptr->dst->flags & INMEMORY) {
1410 if (src->flags & INMEMORY) {
1411 if (src->regoff == iptr->dst->regoff) {
1412 i386_alu_imm_membase(I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1413 i386_alu_imm_membase(I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1416 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1417 i386_alu_imm_reg(I386_ADD, iptr->val.l, REG_ITMP1);
1418 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1419 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1420 i386_alu_imm_reg(I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1421 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1427 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1429 d = reg_of_var(iptr->dst, REG_NULL);
1430 if (iptr->dst->flags & INMEMORY) {
1431 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1432 if (src->prev->regoff == iptr->dst->regoff) {
1433 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1434 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1437 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1438 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1439 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1442 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1443 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1444 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1445 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1447 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1448 if (src->prev->regoff == iptr->dst->regoff) {
1449 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1452 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1453 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1454 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1458 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1459 i386_alu_reg_membase(I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1463 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1464 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1465 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1467 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1468 M_INTMOVE(src->prev->regoff, d);
1469 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, d);
1471 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1472 /* workaround for reg alloc */
1473 if (src->regoff == iptr->dst->regoff) {
1474 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1475 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1476 M_INTMOVE(REG_ITMP1, d);
1479 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, d);
1480 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1484 /* workaround for reg alloc */
1485 if (src->regoff == iptr->dst->regoff) {
1486 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1487 i386_alu_reg_reg(I386_SUB, src->regoff, REG_ITMP1);
1488 M_INTMOVE(REG_ITMP1, d);
1491 M_INTMOVE(src->prev->regoff, d);
1492 i386_alu_reg_reg(I386_SUB, src->regoff, d);
1498 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1499 /* val.i = constant */
1501 d = reg_of_var(iptr->dst, REG_NULL);
1502 i386_emit_ialuconst(I386_SUB, src, iptr);
1505 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1507 d = reg_of_var(iptr->dst, REG_NULL);
1508 if (iptr->dst->flags & INMEMORY) {
1509 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1510 if (src->prev->regoff == iptr->dst->regoff) {
1511 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1512 i386_alu_reg_membase(I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1513 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1514 i386_alu_reg_membase(I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1517 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1518 i386_alu_membase_reg(I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1519 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1520 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1521 i386_alu_membase_reg(I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1522 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1528 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1529 /* val.l = constant */
1531 d = reg_of_var(iptr->dst, REG_NULL);
1532 if (iptr->dst->flags & INMEMORY) {
1533 if (src->flags & INMEMORY) {
1534 if (src->regoff == iptr->dst->regoff) {
1535 i386_alu_imm_membase(I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1536 i386_alu_imm_membase(I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1539 /* TODO: could be size optimized with lea -- see gcc output */
1540 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1541 i386_alu_imm_reg(I386_SUB, iptr->val.l, REG_ITMP1);
1542 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1543 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1544 i386_alu_imm_reg(I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1545 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1551 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1553 d = reg_of_var(iptr->dst, REG_NULL);
1554 if (iptr->dst->flags & INMEMORY) {
1555 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1556 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1557 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1558 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1560 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1561 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1562 i386_imul_reg_reg(src->prev->regoff, REG_ITMP1);
1563 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1565 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1566 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1567 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1568 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1571 i386_mov_reg_reg(src->prev->regoff, REG_ITMP1);
1572 i386_imul_reg_reg(src->regoff, REG_ITMP1);
1573 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1577 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1578 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1579 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1581 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1582 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1583 i386_imul_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
1585 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1586 M_INTMOVE(src->regoff, iptr->dst->regoff);
1587 i386_imul_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1590 if (src->regoff == iptr->dst->regoff) {
1591 i386_imul_reg_reg(src->prev->regoff, iptr->dst->regoff);
1594 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1595 i386_imul_reg_reg(src->regoff, iptr->dst->regoff);
1601 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1602 /* val.i = constant */
1604 d = reg_of_var(iptr->dst, REG_NULL);
1605 if (iptr->dst->flags & INMEMORY) {
1606 if (src->flags & INMEMORY) {
1607 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1608 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1611 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, REG_ITMP1);
1612 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1616 if (src->flags & INMEMORY) {
1617 i386_imul_imm_membase_reg(iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1620 i386_imul_imm_reg_reg(iptr->val.i, src->regoff, iptr->dst->regoff);
1625 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1627 d = reg_of_var(iptr->dst, REG_NULL);
1628 if (iptr->dst->flags & INMEMORY) {
1629 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1630 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX); /* mem -> EAX */
1631 /* optimize move EAX -> REG_ITMP3 is slower??? */
1632 /* i386_mov_reg_reg(EAX, REG_ITMP3); */
1633 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1635 /* TODO: optimize move EAX -> REG_ITMP3 */
1636 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem -> ITMP3 */
1637 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1638 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1640 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP2); /* mem -> ITMP3 */
1641 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1643 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1644 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1645 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1650 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1651 /* val.l = constant */
1653 d = reg_of_var(iptr->dst, REG_NULL);
1654 if (iptr->dst->flags & INMEMORY) {
1655 if (src->flags & INMEMORY) {
1656 i386_mov_imm_reg(iptr->val.l, EAX); /* imm -> EAX */
1657 i386_mul_membase(REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1658 /* TODO: optimize move EAX -> REG_ITMP3 */
1659 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2); /* imm -> ITMP3 */
1660 i386_imul_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1662 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1663 i386_mov_imm_reg(iptr->val.l, REG_ITMP2); /* imm -> ITMP3 */
1664 i386_imul_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1666 i386_alu_reg_reg(I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1667 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1668 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1673 #define gen_div_check(v) \
1675 if ((v)->flags & INMEMORY) { \
1676 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8); \
1678 i386_test_reg_reg(src->regoff, src->regoff); \
1680 i386_jcc(I386_CC_E, 0); \
1681 codegen_addxdivrefs(mcodeptr); \
1684 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1686 d = reg_of_var(iptr->dst, REG_NULL);
1687 var_to_reg_int(s1, src, REG_ITMP2);
1689 if (src->prev->flags & INMEMORY) {
1690 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1693 M_INTMOVE(src->prev->regoff, EAX);
1696 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1697 i386_jcc(I386_CC_NE, 3 + 6);
1698 i386_alu_imm_reg(I386_CMP, -1, s1);
1699 i386_jcc(I386_CC_E, 1 + 2);
1704 if (iptr->dst->flags & INMEMORY) {
1705 i386_mov_reg_membase(EAX, REG_SP, iptr->dst->regoff * 8);
1708 M_INTMOVE(EAX, iptr->dst->regoff);
1712 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1714 d = reg_of_var(iptr->dst, REG_NULL);
1715 var_to_reg_int(s1, src, REG_ITMP2);
1717 if (src->prev->flags & INMEMORY) {
1718 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, EAX);
1721 M_INTMOVE(src->prev->regoff, EAX);
1724 i386_alu_imm_reg(I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1725 i386_jcc(I386_CC_NE, 2 + 3 + 6);
1726 i386_alu_reg_reg(I386_XOR, EDX, EDX);
1727 i386_alu_imm_reg(I386_CMP, -1, s1);
1728 i386_jcc(I386_CC_E, 1 + 2);
1733 if (iptr->dst->flags & INMEMORY) {
1734 i386_mov_reg_membase(EDX, REG_SP, iptr->dst->regoff * 8);
1737 M_INTMOVE(EDX, iptr->dst->regoff);
1741 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1742 /* val.i = constant */
1744 /* TODO: optimize for `/ 2' */
1745 var_to_reg_int(s1, src, REG_ITMP1);
1746 d = reg_of_var(iptr->dst, REG_ITMP1);
1749 i386_test_reg_reg(d, d);
1751 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1752 i386_jcc(I386_CC_NS, a);
1753 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, d);
1755 i386_shift_imm_reg(I386_SAR, iptr->val.i, d);
1756 store_reg_to_var_int(iptr->dst, d);
1759 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1760 /* val.i = constant */
1762 d = reg_of_var(iptr->dst, REG_NULL);
1763 if (iptr->dst->flags & INMEMORY) {
1764 if (src->flags & INMEMORY) {
1766 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1768 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1769 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1771 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
1772 i386_jcc(I386_CC_NS, a);
1773 i386_alu_imm_reg(I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1774 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1775 i386_shrd_imm_reg_reg(iptr->val.i, REG_ITMP2, REG_ITMP1);
1776 i386_shift_imm_reg(I386_SAR, iptr->val.i, REG_ITMP2);
1778 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1779 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1784 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1785 /* val.i = constant */
1787 var_to_reg_int(s1, src, REG_ITMP1);
1788 d = reg_of_var(iptr->dst, REG_ITMP2);
1790 M_INTMOVE(s1, REG_ITMP1);
1797 CALCIMMEDIATEBYTES(a, iptr->val.i);
1800 /* TODO: optimize */
1802 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1803 i386_test_reg_reg(s1, s1);
1804 i386_jcc(I386_CC_GE, a);
1805 i386_mov_reg_reg(s1, d);
1807 i386_alu_imm_reg(I386_AND, iptr->val.i, d);
1810 /* M_INTMOVE(s1, EAX); */
1812 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1813 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1814 /* i386_alu_reg_reg(I386_AND, iptr->val.i, EAX); */
1815 /* i386_alu_reg_reg(I386_XOR, EDX, EAX); */
1816 /* i386_alu_reg_reg(I386_SUB, EDX, EAX); */
1817 /* M_INTMOVE(EAX, d); */
1819 /* i386_alu_reg_reg(I386_XOR, d, d); */
1820 /* i386_mov_imm_reg(iptr->val.i, ECX); */
1821 /* i386_shrd_reg_reg(s1, d); */
1822 /* i386_shift_imm_reg(I386_SHR, 32 - iptr->val.i, d); */
1824 store_reg_to_var_int(iptr->dst, d);
1827 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1828 /* val.l = constant */
1830 d = reg_of_var(iptr->dst, REG_NULL);
1831 if (iptr->dst->flags & INMEMORY) {
1832 if (src->flags & INMEMORY) {
1833 /* Intel algorithm -- does not work, because constant is wrong */
1834 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1); */
1835 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1837 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1838 /* i386_test_reg_reg(REG_ITMP3, REG_ITMP3); */
1839 /* i386_jcc(I386_CC_NS, offset); */
1840 /* i386_alu_imm_reg(I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1841 /* i386_alu_imm_reg(I386_ADC, 0, REG_ITMP3); */
1843 /* i386_shrd_imm_reg_reg(iptr->val.l, REG_ITMP3, REG_ITMP2); */
1844 /* i386_shift_imm_reg(I386_SAR, iptr->val.l, REG_ITMP3); */
1845 /* i386_shld_imm_reg_reg(iptr->val.l, REG_ITMP2, REG_ITMP3); */
1847 /* i386_shift_imm_reg(I386_SHL, iptr->val.l, REG_ITMP2); */
1849 /* i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1); */
1850 /* i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1851 /* i386_alu_reg_reg(I386_SBB, REG_ITMP3, REG_ITMP2); */
1853 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1854 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1856 /* Alpha algorithm */
1858 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1860 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1866 /* TODO: hmm, don't know if this is always correct */
1868 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1870 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1876 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1877 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1879 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1880 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1881 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1882 i386_jcc(I386_CC_GE, a);
1884 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1885 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1887 i386_neg_reg(REG_ITMP1);
1888 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1889 i386_neg_reg(REG_ITMP2);
1891 i386_alu_imm_reg(I386_AND, iptr->val.l, REG_ITMP1);
1892 i386_alu_imm_reg(I386_AND, iptr->val.l >> 32, REG_ITMP2);
1894 i386_neg_reg(REG_ITMP1);
1895 i386_alu_imm_reg(I386_ADC, 0, REG_ITMP2);
1896 i386_neg_reg(REG_ITMP2);
1898 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1899 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1904 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1906 d = reg_of_var(iptr->dst, REG_NULL);
1907 i386_emit_ishift(I386_SHL, src, iptr);
1910 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1911 /* val.i = constant */
1913 d = reg_of_var(iptr->dst, REG_NULL);
1914 i386_emit_ishiftconst(I386_SHL, src, iptr);
1917 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1919 d = reg_of_var(iptr->dst, REG_NULL);
1920 i386_emit_ishift(I386_SAR, src, iptr);
1923 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1924 /* val.i = constant */
1926 d = reg_of_var(iptr->dst, REG_NULL);
1927 i386_emit_ishiftconst(I386_SAR, src, iptr);
1930 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1932 d = reg_of_var(iptr->dst, REG_NULL);
1933 i386_emit_ishift(I386_SHR, src, iptr);
1936 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1937 /* val.i = constant */
1939 d = reg_of_var(iptr->dst, REG_NULL);
1940 i386_emit_ishiftconst(I386_SHR, src, iptr);
1943 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1945 d = reg_of_var(iptr->dst, REG_NULL);
1946 if (iptr->dst->flags & INMEMORY ){
1947 if (src->prev->flags & INMEMORY) {
1948 /* if (src->prev->regoff == iptr->dst->regoff) { */
1949 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1951 /* if (src->flags & INMEMORY) { */
1952 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
1954 /* M_INTMOVE(src->regoff, ECX); */
1957 /* i386_test_imm_reg(32, ECX); */
1958 /* i386_jcc(I386_CC_E, 2 + 2); */
1959 /* i386_mov_reg_reg(REG_ITMP1, REG_ITMP2); */
1960 /* i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1); */
1962 /* i386_shld_reg_membase(REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1963 /* i386_shift_membase(I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1966 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
1967 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1969 if (src->flags & INMEMORY) {
1970 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
1972 M_INTMOVE(src->regoff, ECX);
1975 i386_test_imm_reg(32, ECX);
1976 i386_jcc(I386_CC_E, 2 + 2);
1977 i386_mov_reg_reg(REG_ITMP1, REG_ITMP3);
1978 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
1980 i386_shld_reg_reg(REG_ITMP1, REG_ITMP3);
1981 i386_shift_reg(I386_SHL, REG_ITMP1);
1982 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1983 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1989 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1990 /* val.i = constant */
1992 d = reg_of_var(iptr->dst, REG_NULL);
1993 if (iptr->dst->flags & INMEMORY ) {
1994 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
1995 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1997 if (iptr->val.i & 0x20) {
1998 i386_mov_reg_reg(REG_ITMP1, REG_ITMP2);
1999 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
2000 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2003 i386_shld_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
2004 i386_shift_imm_reg(I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
2007 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2008 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2012 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
2014 d = reg_of_var(iptr->dst, REG_NULL);
2015 if (iptr->dst->flags & INMEMORY ){
2016 if (src->prev->flags & INMEMORY) {
2017 /* if (src->prev->regoff == iptr->dst->regoff) { */
2018 /* TODO: optimize */
2019 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2020 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2022 /* if (src->flags & INMEMORY) { */
2023 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2025 /* M_INTMOVE(src->regoff, ECX); */
2028 /* i386_test_imm_reg(32, ECX); */
2029 /* i386_jcc(I386_CC_E, 2 + 3); */
2030 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2031 /* i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2); */
2033 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2034 /* i386_shift_reg(I386_SAR, REG_ITMP2); */
2035 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2036 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2039 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2040 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2042 if (src->flags & INMEMORY) {
2043 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2045 M_INTMOVE(src->regoff, ECX);
2048 i386_test_imm_reg(32, ECX);
2049 i386_jcc(I386_CC_E, 2 + 3);
2050 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2051 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP3);
2053 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2054 i386_shift_reg(I386_SAR, REG_ITMP3);
2055 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2056 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2062 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
2063 /* val.i = constant */
2065 d = reg_of_var(iptr->dst, REG_NULL);
2066 if (iptr->dst->flags & INMEMORY ) {
2067 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2068 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2070 if (iptr->val.i & 0x20) {
2071 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2072 i386_shift_imm_reg(I386_SAR, 31, REG_ITMP2);
2073 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2076 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2077 i386_shift_imm_reg(I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
2080 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2081 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2085 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
2087 d = reg_of_var(iptr->dst, REG_NULL);
2088 if (iptr->dst->flags & INMEMORY ){
2089 if (src->prev->flags & INMEMORY) {
2090 /* if (src->prev->regoff == iptr->dst->regoff) { */
2091 /* TODO: optimize */
2092 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1); */
2093 /* i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
2095 /* if (src->flags & INMEMORY) { */
2096 /* i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX); */
2098 /* M_INTMOVE(src->regoff, ECX); */
2101 /* i386_test_imm_reg(32, ECX); */
2102 /* i386_jcc(I386_CC_E, 2 + 2); */
2103 /* i386_mov_reg_reg(REG_ITMP2, REG_ITMP1); */
2104 /* i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2); */
2106 /* i386_shrd_reg_reg(REG_ITMP2, REG_ITMP1); */
2107 /* i386_shift_reg(I386_SHR, REG_ITMP2); */
2108 /* i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
2109 /* i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
2112 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
2113 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
2115 if (src->flags & INMEMORY) {
2116 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
2118 M_INTMOVE(src->regoff, ECX);
2121 i386_test_imm_reg(32, ECX);
2122 i386_jcc(I386_CC_E, 2 + 2);
2123 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1);
2124 i386_alu_reg_reg(I386_XOR, REG_ITMP3, REG_ITMP3);
2126 i386_shrd_reg_reg(REG_ITMP3, REG_ITMP1);
2127 i386_shift_reg(I386_SHR, REG_ITMP3);
2128 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2129 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2135 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
2136 /* val.l = constant */
2138 d = reg_of_var(iptr->dst, REG_NULL);
2139 if (iptr->dst->flags & INMEMORY ) {
2140 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
2141 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
2143 if (iptr->val.i & 0x20) {
2144 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1);
2145 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
2146 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2149 i386_shrd_imm_reg_reg(iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
2150 i386_shift_imm_reg(I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
2153 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2154 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2158 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2160 d = reg_of_var(iptr->dst, REG_NULL);
2161 i386_emit_ialu(I386_AND, src, iptr);
2164 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
2165 /* val.i = constant */
2167 d = reg_of_var(iptr->dst, REG_NULL);
2168 i386_emit_ialuconst(I386_AND, src, iptr);
2171 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2173 d = reg_of_var(iptr->dst, REG_NULL);
2174 i386_emit_lalu(I386_AND, src, iptr);
2177 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2178 /* val.l = constant */
2180 d = reg_of_var(iptr->dst, REG_NULL);
2181 i386_emit_laluconst(I386_AND, src, iptr);
2184 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2186 d = reg_of_var(iptr->dst, REG_NULL);
2187 i386_emit_ialu(I386_OR, src, iptr);
2190 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2191 /* val.i = constant */
2193 d = reg_of_var(iptr->dst, REG_NULL);
2194 i386_emit_ialuconst(I386_OR, src, iptr);
2197 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2199 d = reg_of_var(iptr->dst, REG_NULL);
2200 i386_emit_lalu(I386_OR, src, iptr);
2203 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2204 /* val.l = constant */
2206 d = reg_of_var(iptr->dst, REG_NULL);
2207 i386_emit_laluconst(I386_OR, src, iptr);
2210 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2212 d = reg_of_var(iptr->dst, REG_NULL);
2213 i386_emit_ialu(I386_XOR, src, iptr);
2216 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2217 /* val.i = constant */
2219 d = reg_of_var(iptr->dst, REG_NULL);
2220 i386_emit_ialuconst(I386_XOR, src, iptr);
2223 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2225 d = reg_of_var(iptr->dst, REG_NULL);
2226 i386_emit_lalu(I386_XOR, src, iptr);
2229 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2230 /* val.l = constant */
2232 d = reg_of_var(iptr->dst, REG_NULL);
2233 i386_emit_laluconst(I386_XOR, src, iptr);
2236 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2237 /* op1 = variable, val.i = constant */
2239 var = &(locals[iptr->op1][TYPE_INT]);
2240 if (var->flags & INMEMORY) {
2241 i386_alu_imm_membase(I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2244 i386_alu_imm_reg(I386_ADD, iptr->val.i, var->regoff);
2249 /* floating operations ************************************************/
2251 #define ROUND_TO_SINGLE \
2252 i386_fstps_membase(REG_SP, -8); \
2253 i386_flds_membase(REG_SP, -8);
2255 #define ROUND_TO_DOUBLE \
2256 i386_fstpl_membase(REG_SP, -8); \
2257 i386_fldl_membase(REG_SP, -8);
2259 #define FPU_SET_24BIT_MODE \
2260 if (!fpu_in_24bit_mode) { \
2261 i386_fldcw_mem(&fpu_ctrlwrd_24bit); \
2262 fpu_in_24bit_mode = 1; \
2265 #define FPU_SET_53BIT_MODE \
2266 if (fpu_in_24bit_mode) { \
2267 i386_fldcw_mem(&fpu_ctrlwrd_53bit); \
2268 fpu_in_24bit_mode = 0; \
2271 #define ROUND_TO_SINGLE
2272 #define ROUND_TO_DOUBLE
2273 #define FPU_SET_24BIT_MODE
2274 #define FPU_SET_53BIT_MODE
2276 case ICMD_FNEG: /* ..., value ==> ..., - value */
2279 var_to_reg_flt(s1, src, REG_FTMP1);
2280 d = reg_of_var(iptr->dst, REG_FTMP3);
2282 store_reg_to_var_flt(iptr->dst, d);
2285 case ICMD_DNEG: /* ..., value ==> ..., - value */
2288 var_to_reg_flt(s1, src, REG_FTMP1);
2289 d = reg_of_var(iptr->dst, REG_FTMP3);
2291 store_reg_to_var_flt(iptr->dst, d);
2294 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2297 d = reg_of_var(iptr->dst, REG_FTMP3);
2298 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2299 var_to_reg_flt(s2, src, REG_FTMP2);
2302 store_reg_to_var_flt(iptr->dst, d);
2305 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2308 d = reg_of_var(iptr->dst, REG_FTMP3);
2309 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2310 var_to_reg_flt(s2, src, REG_FTMP2);
2313 store_reg_to_var_flt(iptr->dst, d);
2316 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2319 d = reg_of_var(iptr->dst, REG_FTMP3);
2320 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2321 var_to_reg_flt(s2, src, REG_FTMP2);
2324 store_reg_to_var_flt(iptr->dst, d);
2327 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2330 d = reg_of_var(iptr->dst, REG_FTMP3);
2331 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2332 var_to_reg_flt(s2, src, REG_FTMP2);
2335 store_reg_to_var_flt(iptr->dst, d);
2338 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2341 d = reg_of_var(iptr->dst, REG_FTMP3);
2342 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2343 var_to_reg_flt(s2, src, REG_FTMP2);
2347 store_reg_to_var_flt(iptr->dst, d);
2350 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2353 d = reg_of_var(iptr->dst, REG_FTMP3);
2354 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2356 /* i386_fldt_mem(subnormal_bias1); */
2359 var_to_reg_flt(s2, src, REG_FTMP2);
2364 /* i386_fldt_mem(subnormal_bias2); */
2367 store_reg_to_var_flt(iptr->dst, d);
2370 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2373 d = reg_of_var(iptr->dst, REG_FTMP3);
2374 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2375 var_to_reg_flt(s2, src, REG_FTMP2);
2379 store_reg_to_var_flt(iptr->dst, d);
2382 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2385 d = reg_of_var(iptr->dst, REG_FTMP3);
2386 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2388 /* i386_fldt_mem(subnormal_bias1); */
2391 var_to_reg_flt(s2, src, REG_FTMP2);
2396 /* i386_fldt_mem(subnormal_bias2); */
2399 store_reg_to_var_flt(iptr->dst, d);
2402 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2405 /* exchanged to skip fxch */
2406 var_to_reg_flt(s2, src, REG_FTMP2);
2407 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2408 d = reg_of_var(iptr->dst, REG_FTMP3);
2414 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2415 store_reg_to_var_flt(iptr->dst, d);
2421 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2424 /* exchanged to skip fxch */
2425 var_to_reg_flt(s2, src, REG_FTMP2);
2426 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2427 d = reg_of_var(iptr->dst, REG_FTMP3);
2433 i386_jcc(I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2434 store_reg_to_var_flt(iptr->dst, d);
2440 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2441 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2443 d = reg_of_var(iptr->dst, REG_FTMP1);
2444 if (src->flags & INMEMORY) {
2445 i386_fildl_membase(REG_SP, src->regoff * 8);
2450 i386_mov_imm_reg(0, REG_ITMP1);
2451 dseg_adddata(mcodeptr);
2452 i386_mov_reg_membase(src->regoff, REG_ITMP1, a);
2453 i386_fildl_membase(REG_ITMP1, a);
2456 store_reg_to_var_flt(iptr->dst, d);
2459 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2460 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2462 d = reg_of_var(iptr->dst, REG_FTMP1);
2463 if (src->flags & INMEMORY) {
2464 i386_fildll_membase(REG_SP, src->regoff * 8);
2468 panic("L2F: longs have to be in memory");
2470 store_reg_to_var_flt(iptr->dst, d);
2473 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2475 var_to_reg_flt(s1, src, REG_FTMP1);
2476 d = reg_of_var(iptr->dst, REG_NULL);
2478 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2479 i386_mov_imm_reg(0, REG_ITMP1);
2480 dseg_adddata(mcodeptr);
2481 i386_fldcw_membase(REG_ITMP1, a);
2483 if (iptr->dst->flags & INMEMORY) {
2484 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2487 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2488 i386_fldcw_membase(REG_ITMP1, a);
2490 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2493 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2495 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2499 i386_fistpl_membase(REG_ITMP1, a);
2501 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2503 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2504 i386_fldcw_membase(REG_ITMP1, a);
2506 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2509 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2510 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2513 i386_jcc(I386_CC_NE, a);
2515 /* XXX: change this when we use registers */
2516 i386_flds_membase(REG_SP, src->regoff * 8);
2517 i386_mov_imm_reg((s4) asm_builtin_f2i, REG_ITMP1);
2518 i386_call_reg(REG_ITMP1);
2520 if (iptr->dst->flags & INMEMORY) {
2521 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2524 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2528 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2530 var_to_reg_flt(s1, src, REG_FTMP1);
2531 d = reg_of_var(iptr->dst, REG_NULL);
2533 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2534 i386_mov_imm_reg(0, REG_ITMP1);
2535 dseg_adddata(mcodeptr);
2536 i386_fldcw_membase(REG_ITMP1, a);
2538 if (iptr->dst->flags & INMEMORY) {
2539 i386_fistpl_membase(REG_SP, iptr->dst->regoff * 8);
2542 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2543 i386_fldcw_membase(REG_ITMP1, a);
2545 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2548 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2550 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2554 i386_fistpl_membase(REG_ITMP1, a);
2556 i386_mov_membase_reg(REG_ITMP1, a, iptr->dst->regoff);
2558 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2559 i386_fldcw_membase(REG_ITMP1, a);
2561 i386_alu_imm_reg(I386_CMP, 0x80000000, iptr->dst->regoff);
2564 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2565 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2568 i386_jcc(I386_CC_NE, a);
2570 /* XXX: change this when we use registers */
2571 i386_fldl_membase(REG_SP, src->regoff * 8);
2572 i386_mov_imm_reg((s4) asm_builtin_d2i, REG_ITMP1);
2573 i386_call_reg(REG_ITMP1);
2575 if (iptr->dst->flags & INMEMORY) {
2576 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2578 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2582 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2584 var_to_reg_flt(s1, src, REG_FTMP1);
2585 d = reg_of_var(iptr->dst, REG_NULL);
2587 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2588 i386_mov_imm_reg(0, REG_ITMP1);
2589 dseg_adddata(mcodeptr);
2590 i386_fldcw_membase(REG_ITMP1, a);
2592 if (iptr->dst->flags & INMEMORY) {
2593 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2596 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2597 i386_fldcw_membase(REG_ITMP1, a);
2599 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2602 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2604 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2607 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2609 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2611 i386_jcc(I386_CC_NE, a);
2613 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2616 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2618 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2620 i386_jcc(I386_CC_NE, a);
2622 /* XXX: change this when we use registers */
2623 i386_flds_membase(REG_SP, src->regoff * 8);
2624 i386_mov_imm_reg((s4) asm_builtin_f2l, REG_ITMP1);
2625 i386_call_reg(REG_ITMP1);
2626 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2627 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2630 panic("F2L: longs have to be in memory");
2634 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2636 var_to_reg_flt(s1, src, REG_FTMP1);
2637 d = reg_of_var(iptr->dst, REG_NULL);
2639 a = dseg_adds4(0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2640 i386_mov_imm_reg(0, REG_ITMP1);
2641 dseg_adddata(mcodeptr);
2642 i386_fldcw_membase(REG_ITMP1, a);
2644 if (iptr->dst->flags & INMEMORY) {
2645 i386_fistpll_membase(REG_SP, iptr->dst->regoff * 8);
2648 a = dseg_adds4(0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2649 i386_fldcw_membase(REG_ITMP1, a);
2651 i386_alu_imm_membase(I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2654 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2656 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2659 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2661 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2663 i386_jcc(I386_CC_NE, a);
2665 i386_alu_imm_membase(I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2668 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2670 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2672 i386_jcc(I386_CC_NE, a);
2674 /* XXX: change this when we use registers */
2675 i386_fldl_membase(REG_SP, src->regoff * 8);
2676 i386_mov_imm_reg((s4) asm_builtin_d2l, REG_ITMP1);
2677 i386_call_reg(REG_ITMP1);
2678 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2679 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2682 panic("D2L: longs have to be in memory");
2686 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2688 var_to_reg_flt(s1, src, REG_FTMP1);
2689 d = reg_of_var(iptr->dst, REG_FTMP3);
2691 store_reg_to_var_flt(iptr->dst, d);
2694 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2696 var_to_reg_flt(s1, src, REG_FTMP1);
2697 d = reg_of_var(iptr->dst, REG_FTMP3);
2699 store_reg_to_var_flt(iptr->dst, d);
2702 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2705 /* exchanged to skip fxch */
2706 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2707 var_to_reg_flt(s1, src, REG_FTMP2);
2708 d = reg_of_var(iptr->dst, REG_ITMP1);
2713 i386_test_imm_reg(0x400, EAX); /* unordered treat as GT */
2714 i386_jcc(I386_CC_E, 6);
2715 i386_alu_imm_reg(I386_AND, 0x000000ff, EAX);
2717 i386_mov_imm_reg(0, d); /* does not affect flags */
2718 i386_jcc(I386_CC_E, 6 + 3 + 5 + 3);
2719 i386_jcc(I386_CC_B, 3 + 5);
2720 i386_alu_imm_reg(I386_SUB, 1, d);
2722 i386_alu_imm_reg(I386_ADD, 1, d);
2723 store_reg_to_var_int(iptr->dst, d);
2726 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2729 /* exchanged to skip fxch */
2730 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2731 var_to_reg_flt(s1, src, REG_FTMP2);
2732 d = reg_of_var(iptr->dst, REG_ITMP1);
2737 i386_test_imm_reg(0x400, EAX); /* unordered treat as LT */
2738 i386_jcc(I386_CC_E, 3);
2739 i386_movb_imm_reg(1, I386_AH);
2741 i386_mov_imm_reg(0, d); /* does not affect flags */
2742 i386_jcc(I386_CC_E, 6 + 3 + 5 + 3);
2743 i386_jcc(I386_CC_B, 3 + 5);
2744 i386_alu_imm_reg(I386_SUB, 1, d);
2746 i386_alu_imm_reg(I386_ADD, 1, d);
2747 store_reg_to_var_int(iptr->dst, d);
2751 /* memory operations **************************************************/
2753 #define gen_bound_check \
2754 if (checkbounds) { \
2755 i386_alu_membase_reg(I386_CMP, s1, OFFSET(java_arrayheader, size), s2); \
2756 i386_jcc(I386_CC_AE, 0); \
2757 codegen_addxboundrefs(mcodeptr, s2); \
2760 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2762 var_to_reg_int(s1, src, REG_ITMP1);
2763 d = reg_of_var(iptr->dst, REG_ITMP1);
2764 gen_nullptr_check(s1);
2765 i386_mov_membase_reg(s1, OFFSET(java_arrayheader, size), d);
2766 store_reg_to_var_int(iptr->dst, d);
2769 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2771 var_to_reg_int(s1, src->prev, REG_ITMP1);
2772 var_to_reg_int(s2, src, REG_ITMP2);
2773 d = reg_of_var(iptr->dst, REG_ITMP1);
2774 if (iptr->op1 == 0) {
2775 gen_nullptr_check(s1);
2778 i386_mov_memindex_reg(OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2779 store_reg_to_var_int(iptr->dst, d);
2782 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2784 var_to_reg_int(s1, src->prev, REG_ITMP1);
2785 var_to_reg_int(s2, src, REG_ITMP2);
2786 d = reg_of_var(iptr->dst, REG_ITMP3);
2787 if (iptr->op1 == 0) {
2788 gen_nullptr_check(s1);
2792 if (iptr->dst->flags & INMEMORY) {
2793 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2794 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2795 i386_mov_memindex_reg(OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2796 i386_mov_reg_membase(REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2800 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2802 var_to_reg_int(s1, src->prev, REG_ITMP1);
2803 var_to_reg_int(s2, src, REG_ITMP2);
2804 d = reg_of_var(iptr->dst, REG_ITMP1);
2805 if (iptr->op1 == 0) {
2806 gen_nullptr_check(s1);
2809 i386_mov_memindex_reg(OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2810 store_reg_to_var_int(iptr->dst, d);
2813 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2815 var_to_reg_int(s1, src->prev, REG_ITMP1);
2816 var_to_reg_int(s2, src, REG_ITMP2);
2817 d = reg_of_var(iptr->dst, REG_FTMP1);
2818 if (iptr->op1 == 0) {
2819 gen_nullptr_check(s1);
2822 i386_flds_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2824 store_reg_to_var_flt(iptr->dst, d);
2827 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2829 var_to_reg_int(s1, src->prev, REG_ITMP1);
2830 var_to_reg_int(s2, src, REG_ITMP2);
2831 d = reg_of_var(iptr->dst, REG_FTMP3);
2832 if (iptr->op1 == 0) {
2833 gen_nullptr_check(s1);
2836 i386_fldl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2838 store_reg_to_var_flt(iptr->dst, d);
2841 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2843 var_to_reg_int(s1, src->prev, REG_ITMP1);
2844 var_to_reg_int(s2, src, REG_ITMP2);
2845 d = reg_of_var(iptr->dst, REG_ITMP1);
2846 if (iptr->op1 == 0) {
2847 gen_nullptr_check(s1);
2850 i386_movzwl_memindex_reg(OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2851 store_reg_to_var_int(iptr->dst, d);
2854 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2856 var_to_reg_int(s1, src->prev, REG_ITMP1);
2857 var_to_reg_int(s2, src, REG_ITMP2);
2858 d = reg_of_var(iptr->dst, REG_ITMP1);
2859 if (iptr->op1 == 0) {
2860 gen_nullptr_check(s1);
2863 i386_movswl_memindex_reg(OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2864 store_reg_to_var_int(iptr->dst, d);
2867 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2869 var_to_reg_int(s1, src->prev, REG_ITMP1);
2870 var_to_reg_int(s2, src, REG_ITMP2);
2871 d = reg_of_var(iptr->dst, REG_ITMP1);
2872 if (iptr->op1 == 0) {
2873 gen_nullptr_check(s1);
2876 i386_movsbl_memindex_reg(OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2877 store_reg_to_var_int(iptr->dst, d);
2881 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2883 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2884 var_to_reg_int(s2, src->prev, REG_ITMP2);
2885 if (iptr->op1 == 0) {
2886 gen_nullptr_check(s1);
2889 var_to_reg_int(s3, src, REG_ITMP3);
2890 i386_mov_reg_memindex(s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2893 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2895 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2896 var_to_reg_int(s2, src->prev, REG_ITMP2);
2897 if (iptr->op1 == 0) {
2898 gen_nullptr_check(s1);
2902 if (src->flags & INMEMORY) {
2903 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP3);
2904 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2905 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2906 i386_mov_reg_memindex(REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2910 case ICMD_IASTORE: /* ..., 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);
2918 var_to_reg_int(s3, src, REG_ITMP3);
2919 i386_mov_reg_memindex(s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2922 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2924 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2925 var_to_reg_int(s2, src->prev, REG_ITMP2);
2926 if (iptr->op1 == 0) {
2927 gen_nullptr_check(s1);
2930 var_to_reg_flt(s3, src, REG_FTMP1);
2931 i386_fstps_memindex(OFFSET(java_floatarray, data[0]), s1, s2, 2);
2935 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2937 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2938 var_to_reg_int(s2, src->prev, REG_ITMP2);
2939 if (iptr->op1 == 0) {
2940 gen_nullptr_check(s1);
2943 var_to_reg_flt(s3, src, REG_FTMP1);
2944 i386_fstpl_memindex(OFFSET(java_doublearray, data[0]), s1, s2, 3);
2948 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2950 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2951 var_to_reg_int(s2, src->prev, REG_ITMP2);
2952 if (iptr->op1 == 0) {
2953 gen_nullptr_check(s1);
2956 var_to_reg_int(s3, src, REG_ITMP3);
2957 i386_movw_reg_memindex(s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2960 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2962 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2963 var_to_reg_int(s2, src->prev, REG_ITMP2);
2964 if (iptr->op1 == 0) {
2965 gen_nullptr_check(s1);
2968 var_to_reg_int(s3, src, REG_ITMP3);
2969 i386_movw_reg_memindex(s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2972 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2974 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2975 var_to_reg_int(s2, src->prev, REG_ITMP2);
2976 if (iptr->op1 == 0) {
2977 gen_nullptr_check(s1);
2980 var_to_reg_int(s3, src, REG_ITMP3);
2981 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2982 M_INTMOVE(s3, REG_ITMP3);
2985 i386_movb_reg_memindex(s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2989 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2990 /* op1 = type, val.a = field address */
2992 /* if class isn't yet initialized, do it */
2993 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2994 /* call helper function which patches this code */
2995 i386_mov_imm_reg((s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
2996 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
2997 i386_call_reg(REG_ITMP2);
3000 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
3001 /* here it's slightly slower */
3002 i386_mov_imm_reg(0, REG_ITMP2);
3003 dseg_adddata(mcodeptr);
3004 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3005 switch (iptr->op1) {
3008 var_to_reg_int(s2, src, REG_ITMP1);
3009 i386_mov_reg_membase(s2, REG_ITMP2, 0);
3012 if (src->flags & INMEMORY) {
3013 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3014 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0);
3015 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3016 i386_mov_reg_membase(REG_ITMP1, REG_ITMP2, 0 + 4);
3018 panic("PUTSTATIC: longs have to be in memory");
3022 var_to_reg_flt(s2, src, REG_FTMP1);
3023 i386_fstps_membase(REG_ITMP2, 0);
3027 var_to_reg_flt(s2, src, REG_FTMP1);
3028 i386_fstpl_membase(REG_ITMP2, 0);
3031 default: panic ("internal error");
3035 case ICMD_GETSTATIC: /* ... ==> ..., value */
3036 /* op1 = type, val.a = field address */
3038 /* if class isn't yet initialized, do it */
3039 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
3040 /* call helper function which patches this code */
3041 i386_mov_imm_reg((s4) ((fieldinfo *) iptr->val.a)->class, REG_ITMP1);
3042 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
3043 i386_call_reg(REG_ITMP2);
3046 a = dseg_addaddress(&(((fieldinfo *) iptr->val.a)->value));
3047 i386_mov_imm_reg(0, REG_ITMP2);
3048 dseg_adddata(mcodeptr);
3049 i386_mov_membase_reg(REG_ITMP2, a, REG_ITMP2);
3050 switch (iptr->op1) {
3053 d = reg_of_var(iptr->dst, REG_ITMP1);
3054 i386_mov_membase_reg(REG_ITMP2, 0, d);
3055 store_reg_to_var_int(iptr->dst, d);
3058 d = reg_of_var(iptr->dst, REG_NULL);
3059 if (iptr->dst->flags & INMEMORY) {
3060 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP1);
3061 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
3062 i386_mov_membase_reg(REG_ITMP2, 0 + 4, REG_ITMP1);
3063 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
3065 panic("GETSTATIC: longs have to be in memory");
3069 d = reg_of_var(iptr->dst, REG_FTMP1);
3070 i386_flds_membase(REG_ITMP2, 0);
3072 store_reg_to_var_flt(iptr->dst, d);
3075 d = reg_of_var(iptr->dst, REG_FTMP1);
3076 i386_fldl_membase(REG_ITMP2, 0);
3078 store_reg_to_var_flt(iptr->dst, d);
3080 default: panic ("internal error");
3084 case ICMD_PUTFIELD: /* ..., value ==> ... */
3085 /* op1 = type, val.i = field offset */
3087 a = ((fieldinfo *)(iptr->val.a))->offset;
3088 switch (iptr->op1) {
3091 var_to_reg_int(s1, src->prev, REG_ITMP1);
3092 var_to_reg_int(s2, src, REG_ITMP2);
3093 gen_nullptr_check(s1);
3094 i386_mov_reg_membase(s2, s1, a);
3097 var_to_reg_int(s1, src->prev, REG_ITMP1);
3098 gen_nullptr_check(s1);
3099 if (src->flags & INMEMORY) {
3100 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP2);
3101 i386_mov_reg_membase(REG_ITMP2, s1, a);
3102 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3103 i386_mov_reg_membase(REG_ITMP2, s1, a + 4);
3105 panic("PUTFIELD: longs have to be in memory");
3109 var_to_reg_int(s1, src->prev, REG_ITMP1);
3110 var_to_reg_flt(s2, src, REG_FTMP1);
3111 gen_nullptr_check(s1);
3112 i386_fstps_membase(s1, a);
3116 var_to_reg_int(s1, src->prev, REG_ITMP1);
3117 var_to_reg_flt(s2, src, REG_FTMP1);
3118 gen_nullptr_check(s1);
3119 i386_fstpl_membase(s1, a);
3122 default: panic ("internal error");
3126 case ICMD_GETFIELD: /* ... ==> ..., value */
3127 /* op1 = type, val.i = field offset */
3129 a = ((fieldinfo *)(iptr->val.a))->offset;
3130 switch (iptr->op1) {
3133 var_to_reg_int(s1, src, REG_ITMP1);
3134 d = reg_of_var(iptr->dst, REG_ITMP2);
3135 gen_nullptr_check(s1);
3136 i386_mov_membase_reg(s1, a, d);
3137 store_reg_to_var_int(iptr->dst, d);
3140 var_to_reg_int(s1, src, REG_ITMP1);
3141 d = reg_of_var(iptr->dst, REG_NULL);
3142 gen_nullptr_check(s1);
3143 i386_mov_membase_reg(s1, a, REG_ITMP2);
3144 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3145 i386_mov_membase_reg(s1, a + 4, REG_ITMP2);
3146 i386_mov_reg_membase(REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3149 var_to_reg_int(s1, src, REG_ITMP1);
3150 d = reg_of_var(iptr->dst, REG_FTMP1);
3151 gen_nullptr_check(s1);
3152 i386_flds_membase(s1, a);
3154 store_reg_to_var_flt(iptr->dst, d);
3157 var_to_reg_int(s1, src, REG_ITMP1);
3158 d = reg_of_var(iptr->dst, REG_FTMP1);
3159 gen_nullptr_check(s1);
3160 i386_fldl_membase(s1, a);
3162 store_reg_to_var_flt(iptr->dst, d);
3164 default: panic ("internal error");
3169 /* branch operations **************************************************/
3172 /* #define ALIGNCODENOP {if((int)((long)mcodeptr&7)){M_NOP;}} */
3173 #define ALIGNCODENOP do {} while (0)
3175 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3177 var_to_reg_int(s1, src, REG_ITMP1);
3178 M_INTMOVE(s1, REG_ITMP1_XPTR);
3180 i386_call_imm(0); /* passing exception pointer */
3181 i386_pop_reg(REG_ITMP2_XPC);
3183 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
3184 i386_jmp_reg(REG_ITMP3);
3188 case ICMD_GOTO: /* ... ==> ... */
3189 /* op1 = target JavaVM pc */
3192 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3196 case ICMD_JSR: /* ... ==> ... */
3197 /* op1 = target JavaVM pc */
3200 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3203 case ICMD_RET: /* ... ==> ... */
3204 /* op1 = local variable */
3206 var = &(locals[iptr->op1][TYPE_ADR]);
3207 var_to_reg_int(s1, var, REG_ITMP1);
3211 case ICMD_IFNULL: /* ..., value ==> ... */
3212 /* op1 = target JavaVM pc */
3214 if (src->flags & INMEMORY) {
3215 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3218 i386_test_reg_reg(src->regoff, src->regoff);
3220 i386_jcc(I386_CC_E, 0);
3221 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3224 case ICMD_IFNONNULL: /* ..., value ==> ... */
3225 /* op1 = target JavaVM pc */
3227 if (src->flags & INMEMORY) {
3228 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
3231 i386_test_reg_reg(src->regoff, src->regoff);
3233 i386_jcc(I386_CC_NE, 0);
3234 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3237 case ICMD_IFEQ: /* ..., value ==> ... */
3238 /* op1 = target JavaVM pc, val.i = constant */
3240 if (src->flags & INMEMORY) {
3241 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3244 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3246 i386_jcc(I386_CC_E, 0);
3247 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3250 case ICMD_IFLT: /* ..., value ==> ... */
3251 /* op1 = target JavaVM pc, val.i = constant */
3253 if (src->flags & INMEMORY) {
3254 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3257 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3259 i386_jcc(I386_CC_L, 0);
3260 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3263 case ICMD_IFLE: /* ..., value ==> ... */
3264 /* op1 = target JavaVM pc, val.i = constant */
3266 if (src->flags & INMEMORY) {
3267 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3270 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3272 i386_jcc(I386_CC_LE, 0);
3273 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3276 case ICMD_IFNE: /* ..., value ==> ... */
3277 /* op1 = target JavaVM pc, val.i = constant */
3279 if (src->flags & INMEMORY) {
3280 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3283 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3285 i386_jcc(I386_CC_NE, 0);
3286 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3289 case ICMD_IFGT: /* ..., value ==> ... */
3290 /* op1 = target JavaVM pc, val.i = constant */
3292 if (src->flags & INMEMORY) {
3293 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3296 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3298 i386_jcc(I386_CC_G, 0);
3299 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3302 case ICMD_IFGE: /* ..., value ==> ... */
3303 /* op1 = target JavaVM pc, val.i = constant */
3305 if (src->flags & INMEMORY) {
3306 i386_alu_imm_membase(I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3309 i386_alu_imm_reg(I386_CMP, iptr->val.i, src->regoff);
3311 i386_jcc(I386_CC_GE, 0);
3312 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3315 case ICMD_IF_LEQ: /* ..., value ==> ... */
3316 /* op1 = target JavaVM pc, val.l = constant */
3318 if (src->flags & INMEMORY) {
3319 if (iptr->val.l == 0) {
3320 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3321 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3324 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3325 i386_alu_imm_reg(I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3326 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3327 i386_alu_imm_reg(I386_XOR, iptr->val.l, REG_ITMP1);
3328 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3331 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3332 i386_jcc(I386_CC_E, 0);
3333 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3336 case ICMD_IF_LLT: /* ..., value ==> ... */
3337 /* op1 = target JavaVM pc, val.l = constant */
3339 if (src->flags & INMEMORY) {
3340 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3341 i386_jcc(I386_CC_L, 0);
3342 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3345 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3346 CALCIMMEDIATEBYTES(a, iptr->val.l);
3348 i386_jcc(I386_CC_G, a);
3350 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3351 i386_jcc(I386_CC_B, 0);
3352 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3356 case ICMD_IF_LLE: /* ..., value ==> ... */
3357 /* op1 = target JavaVM pc, val.l = constant */
3359 if (src->flags & INMEMORY) {
3360 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3361 i386_jcc(I386_CC_L, 0);
3362 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3365 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3366 CALCIMMEDIATEBYTES(a, iptr->val.l);
3368 i386_jcc(I386_CC_G, a);
3370 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3371 i386_jcc(I386_CC_BE, 0);
3372 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3376 case ICMD_IF_LNE: /* ..., value ==> ... */
3377 /* op1 = target JavaVM pc, val.l = constant */
3379 if (src->flags & INMEMORY) {
3380 if (iptr->val.l == 0) {
3381 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3382 i386_alu_membase_reg(I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3385 i386_mov_imm_reg(iptr->val.l, REG_ITMP1);
3386 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3387 i386_mov_imm_reg(iptr->val.l >> 32, REG_ITMP2);
3388 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3389 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3392 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3393 i386_jcc(I386_CC_NE, 0);
3394 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3397 case ICMD_IF_LGT: /* ..., value ==> ... */
3398 /* op1 = target JavaVM pc, val.l = constant */
3400 if (src->flags & INMEMORY) {
3401 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3402 i386_jcc(I386_CC_G, 0);
3403 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3406 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3407 CALCIMMEDIATEBYTES(a, iptr->val.l);
3409 i386_jcc(I386_CC_L, a);
3411 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3412 i386_jcc(I386_CC_A, 0);
3413 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3417 case ICMD_IF_LGE: /* ..., value ==> ... */
3418 /* op1 = target JavaVM pc, val.l = constant */
3420 if (src->flags & INMEMORY) {
3421 i386_alu_imm_membase(I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3422 i386_jcc(I386_CC_G, 0);
3423 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3426 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3427 CALCIMMEDIATEBYTES(a, iptr->val.l);
3429 i386_jcc(I386_CC_L, a);
3431 i386_alu_imm_membase(I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3432 i386_jcc(I386_CC_AE, 0);
3433 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3437 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3438 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3440 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3441 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3442 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3444 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3445 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3447 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3448 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3451 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3453 i386_jcc(I386_CC_E, 0);
3454 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3457 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3458 /* op1 = target JavaVM pc */
3460 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3461 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3462 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3463 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3464 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3465 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3466 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3468 i386_jcc(I386_CC_E, 0);
3469 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3472 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3473 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3475 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3476 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3477 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3479 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3480 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3482 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3483 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3486 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3488 i386_jcc(I386_CC_NE, 0);
3489 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3492 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3493 /* op1 = target JavaVM pc */
3495 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3496 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3497 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3498 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3499 i386_alu_membase_reg(I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3500 i386_alu_reg_reg(I386_OR, REG_ITMP2, REG_ITMP1);
3501 i386_test_reg_reg(REG_ITMP1, REG_ITMP1);
3503 i386_jcc(I386_CC_NE, 0);
3504 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3507 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3508 /* op1 = target JavaVM pc */
3510 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3511 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3512 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3514 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3515 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3517 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3518 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3521 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3523 i386_jcc(I386_CC_L, 0);
3524 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3527 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3528 /* op1 = target JavaVM pc */
3530 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3531 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3532 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3533 i386_jcc(I386_CC_L, 0);
3534 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3537 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3538 CALCOFFSETBYTES(a, REG_SP, src->regoff);
3540 i386_jcc(I386_CC_G, a);
3542 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3543 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3544 i386_jcc(I386_CC_B, 0);
3545 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3549 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3550 /* op1 = target JavaVM pc */
3552 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3553 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3554 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3556 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3557 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3559 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3560 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3563 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3565 i386_jcc(I386_CC_G, 0);
3566 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3569 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3570 /* op1 = target JavaVM pc */
3572 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3573 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3574 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3575 i386_jcc(I386_CC_G, 0);
3576 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3579 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3580 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3582 i386_jcc(I386_CC_L, a);
3584 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3585 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3586 i386_jcc(I386_CC_A, 0);
3587 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3591 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3592 /* op1 = target JavaVM pc */
3594 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3595 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3596 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3598 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3599 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3601 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3602 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3605 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3607 i386_jcc(I386_CC_LE, 0);
3608 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3611 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3612 /* op1 = target JavaVM pc */
3614 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3615 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3616 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3617 i386_jcc(I386_CC_L, 0);
3618 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3621 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3622 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3624 i386_jcc(I386_CC_G, a);
3626 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3627 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3628 i386_jcc(I386_CC_BE, 0);
3629 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3633 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3634 /* op1 = target JavaVM pc */
3636 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3637 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
3638 i386_alu_reg_membase(I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3640 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3641 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3643 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3644 i386_alu_reg_membase(I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3647 i386_alu_reg_reg(I386_CMP, src->regoff, src->prev->regoff);
3649 i386_jcc(I386_CC_GE, 0);
3650 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3653 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3654 /* op1 = target JavaVM pc */
3656 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3657 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3658 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3659 i386_jcc(I386_CC_G, 0);
3660 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3663 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3664 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3666 i386_jcc(I386_CC_L, a);
3668 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
3669 i386_alu_membase_reg(I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3670 i386_jcc(I386_CC_AE, 0);
3671 codegen_addreference(BlockPtrOfPC(iptr->op1), mcodeptr);
3675 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3677 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3680 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3681 /* val.i = constant */
3683 d = reg_of_var(iptr->dst, REG_NULL);
3684 i386_emit_ifcc_iconst(I386_CC_NE, src, iptr);
3687 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3688 /* val.i = constant */
3690 d = reg_of_var(iptr->dst, REG_NULL);
3691 i386_emit_ifcc_iconst(I386_CC_E, src, iptr);
3694 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3695 /* val.i = constant */
3697 d = reg_of_var(iptr->dst, REG_NULL);
3698 i386_emit_ifcc_iconst(I386_CC_GE, src, iptr);
3701 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3702 /* val.i = constant */
3704 d = reg_of_var(iptr->dst, REG_NULL);
3705 i386_emit_ifcc_iconst(I386_CC_L, src, iptr);
3708 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3709 /* val.i = constant */
3711 d = reg_of_var(iptr->dst, REG_NULL);
3712 i386_emit_ifcc_iconst(I386_CC_LE, src, iptr);
3715 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3716 /* val.i = constant */
3718 d = reg_of_var(iptr->dst, REG_NULL);
3719 i386_emit_ifcc_iconst(I386_CC_G, src, iptr);
3723 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3726 var_to_reg_int(s1, src, REG_RESULT);
3727 M_INTMOVE(s1, REG_RESULT);
3730 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3731 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP2);
3732 i386_mov_reg_membase(REG_RESULT, REG_SP, maxmemuse * 8);
3734 i386_alu_imm_reg(I386_SUB, 1 * 8, REG_SP);
3735 i386_mov_reg_membase(REG_ITMP2, REG_SP, 0 * 8);
3736 i386_mov_imm_reg((s4) asm_builtin_monitorexit, REG_ITMP1);
3737 i386_call_reg(REG_ITMP1);
3738 i386_alu_imm_reg(I386_ADD, 1 * 8, REG_SP);
3740 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_RESULT);
3744 goto nowperformreturn;
3746 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3748 if (src->flags & INMEMORY) {
3749 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_RESULT);
3750 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3753 panic("LRETURN: longs have to be in memory");
3757 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3758 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP2);
3759 i386_mov_reg_membase(REG_RESULT, REG_SP, maxmemuse * 8);
3760 i386_mov_reg_membase(REG_RESULT2, REG_SP, maxmemuse * 8 + 4);
3762 i386_alu_imm_reg(I386_SUB, 1 * 8, REG_SP);
3763 i386_mov_reg_membase(REG_ITMP2, REG_SP, 0 * 8);
3764 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3765 i386_call_reg(REG_ITMP1);
3766 i386_alu_imm_reg(I386_ADD, 1 * 8, REG_SP);
3768 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_RESULT);
3769 i386_mov_membase_reg(REG_SP, maxmemuse * 8 + 4, REG_RESULT2);
3773 goto nowperformreturn;
3775 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3776 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3778 var_to_reg_flt(s1, src, REG_FRESULT);
3779 /* this may be an early return -- keep the offset correct for the remaining code */
3783 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3784 i386_mov_membase_reg(REG_SP, maxmemuse * 8, REG_ITMP2);
3785 i386_fstl_membase(REG_SP, maxmemuse * 8);
3787 i386_alu_imm_reg(I386_SUB, 1 * 8, REG_SP);
3788 i386_mov_reg_membase(REG_ITMP2, REG_SP, 0 * 8);
3789 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3790 i386_call_reg(REG_ITMP1);
3791 i386_alu_imm_reg(I386_ADD, 1 * 8, REG_SP);
3793 i386_fldl_membase(REG_SP, maxmemuse * 8);
3797 goto nowperformreturn;
3799 case ICMD_RETURN: /* ... ==> ... */
3802 if (checksync && (method->flags & ACC_SYNCHRONIZED)) {
3803 i386_mov_membase_reg(REG_SP, 8 * maxmemuse, REG_ITMP1);
3804 i386_alu_imm_reg(I386_SUB, 4, REG_SP);
3805 i386_mov_reg_membase(REG_ITMP1, REG_SP, 0);
3806 i386_mov_imm_reg((s4) builtin_monitorexit, REG_ITMP1);
3807 i386_call_reg(REG_ITMP1);
3808 i386_alu_imm_reg(I386_ADD, 4, REG_SP);
3816 p = parentargs_base;
3818 /* restore saved registers */
3819 for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {
3821 i386_mov_membase_reg(REG_SP, p * 8, savintregs[r]);
3823 for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) {
3825 i386_fldl_membase(REG_SP, p * 8);
3827 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3828 i386_fstp_reg(savfltregs[r] + fpu_st_offset + 1);
3830 i386_fstp_reg(savfltregs[r] + fpu_st_offset);
3835 /* deallocate stack */
3836 if (parentargs_base) {
3837 i386_alu_imm_reg(I386_ADD, parentargs_base * 8, REG_SP);
3840 /* call trace function */
3842 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3844 i386_mov_imm_membase((s4) method, REG_SP, 0);
3846 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
3847 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
3849 i386_fstl_membase(REG_SP, 4 + 8);
3850 i386_fsts_membase(REG_SP, 4 + 8 + 8);
3852 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
3853 /* i386_mov_imm_reg(asm_builtin_exittrace, REG_ITMP1); */
3854 i386_call_reg(REG_ITMP1);
3856 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
3857 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
3859 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3868 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3873 tptr = (void **) iptr->target;
3875 s4ptr = iptr->val.a;
3876 l = s4ptr[1]; /* low */
3877 i = s4ptr[2]; /* high */
3879 var_to_reg_int(s1, src, REG_ITMP1);
3880 M_INTMOVE(s1, REG_ITMP1);
3882 i386_alu_imm_reg(I386_SUB, l, REG_ITMP1);
3888 i386_alu_imm_reg(I386_CMP, i - 1, REG_ITMP1);
3889 i386_jcc(I386_CC_A, 0);
3891 /* codegen_addreference(BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3892 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3894 /* build jump table top down and use address of lowest entry */
3896 /* s4ptr += 3 + i; */
3900 /* dseg_addtarget(BlockPtrOfPC(*--s4ptr)); */
3901 dseg_addtarget((basicblock *) tptr[0]);
3905 /* length of dataseg after last dseg_addtarget is used by load */
3907 i386_mov_imm_reg(0, REG_ITMP2);
3908 dseg_adddata(mcodeptr);
3909 i386_mov_memindex_reg(-dseglen, REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3910 i386_jmp_reg(REG_ITMP1);
3916 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3918 s4 i, l, val, *s4ptr;
3921 tptr = (void **) iptr->target;
3923 s4ptr = iptr->val.a;
3924 l = s4ptr[0]; /* default */
3925 i = s4ptr[1]; /* count */
3927 MCODECHECK((i<<2)+8);
3928 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3934 i386_alu_imm_reg(I386_CMP, val, s1);
3935 i386_jcc(I386_CC_E, 0);
3936 /* codegen_addreference(BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3937 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3941 /* codegen_addreference(BlockPtrOfPC(l), mcodeptr); */
3943 tptr = (void **) iptr->target;
3944 codegen_addreference((basicblock *) tptr[0], mcodeptr);
3951 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3952 /* op1 = return type, val.a = function pointer*/
3956 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3957 /* op1 = return type, val.a = function pointer*/
3961 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3962 /* op1 = return type, val.a = function pointer*/
3966 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3967 /* op1 = arg count, val.a = method pointer */
3969 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3970 /* op1 = arg count, val.a = method pointer */
3972 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3973 /* op1 = arg count, val.a = method pointer */
3975 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3976 /* op1 = arg count, val.a = method pointer */
3984 MCODECHECK((s3 << 1) + 64);
3986 if ( (iptr->opc == ICMD_BUILTIN1) ||
3987 (iptr->opc == ICMD_BUILTIN2) ||
3988 (iptr->opc == ICMD_BUILTIN3) ) {
3990 i386_push_reg(REG_ITMP1);
3991 i386_push_reg(REG_ITMP2);
3992 i386_push_reg(REG_ITMP3);
3994 i386_mov_imm_reg((s4) builtin_asm_new_stackframeinfo, REG_ITMP1);
3995 i386_call_reg(REG_ITMP1);
3997 i386_pop_reg(REG_ITMP3);
3998 i386_pop_reg(REG_ITMP2);
3999 i386_pop_reg(REG_ITMP1);
4002 i386_mov_membase_reg(REG_SP, 0 , REG_ITMP2); /*save return adress*/
4003 i386_mov_membase_reg(REG_RESULT, 0 , REG_ITMP3); /*get direct access to structure*/
4005 i386_mov_imm_membase(0x1111, REG_ITMP3, offreturnfromnative); /*store return adress in stack frame info block*/
4006 i386_mov_imm_membase((s4) m, REG_ITMP3, offmethodnative); /*store methodpointer in stack frame info block*/
4007 i386_mov_imm_membase(1111,REG_ITMP3,offaddrreturnfromnative);
4011 /* copy arguments to registers or stack location */
4013 for (; --s3 >= 0; src = src->prev) {
4014 if (src->varkind == ARGVAR) {
4018 if (IS_INT_LNG_TYPE(src->type)) {
4019 if (s3 < intreg_argnum) {
4020 panic("No integer argument registers available!");
4023 if (!IS_2_WORD_TYPE(src->type)) {
4024 if (src->flags & INMEMORY) {
4025 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4026 i386_mov_reg_membase(REG_ITMP1, REG_SP, s3 * 8);
4029 i386_mov_reg_membase(src->regoff, REG_SP, s3 * 8);
4033 if (src->flags & INMEMORY) {
4034 M_LNGMEMMOVE(src->regoff, s3);
4037 panic("copy arguments: longs have to be in memory");
4043 if (s3 < fltreg_argnum) {
4044 panic("No float argument registers available!");
4047 var_to_reg_flt(d, src, REG_FTMP1);
4048 if (src->type == TYPE_FLT) {
4049 i386_fstps_membase(REG_SP, s3 * 8);
4052 i386_fstpl_membase(REG_SP, s3 * 8);
4059 switch (iptr->opc) {
4067 i386_mov_imm_reg(a, REG_ITMP1);
4068 i386_call_reg(REG_ITMP1);
4071 case ICMD_INVOKESTATIC:
4073 a = (u4) m->stubroutine;
4076 i386_mov_imm_reg(a, REG_ITMP2);
4077 i386_call_reg(REG_ITMP2);
4080 case ICMD_INVOKESPECIAL:
4082 a = (u4) m->stubroutine;
4085 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4086 gen_nullptr_check(REG_ITMP1);
4087 i386_mov_membase_reg(REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
4089 i386_mov_imm_reg(a, REG_ITMP2);
4090 i386_call_reg(REG_ITMP2);
4093 case ICMD_INVOKEVIRTUAL:
4097 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4098 gen_nullptr_check(REG_ITMP1);
4099 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
4100 i386_mov_membase32_reg(REG_ITMP2, OFFSET(vftbl, table[0]) + sizeof(methodptr) * m->vftblindex, REG_ITMP1);
4102 i386_call_reg(REG_ITMP1);
4105 case ICMD_INVOKEINTERFACE:
4110 i386_mov_membase_reg(REG_SP, 0, REG_ITMP1);
4111 gen_nullptr_check(REG_ITMP1);
4112 i386_mov_membase_reg(REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4113 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - sizeof(methodptr) * ci->index, REG_ITMP2);
4114 i386_mov_membase32_reg(REG_ITMP2, sizeof(methodptr) * (m - ci->methods), REG_ITMP1);
4116 i386_call_reg(REG_ITMP1);
4121 error("Unkown ICMD-Command: %d", iptr->opc);
4124 /* d contains return type */
4126 if (d != TYPE_VOID) {
4127 d = reg_of_var(iptr->dst, REG_NULL);
4129 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4130 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4131 if (iptr->dst->flags & INMEMORY) {
4132 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4133 i386_mov_reg_membase(REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4136 panic("RETURN: longs have to be in memory");
4140 if (iptr->dst->flags & INMEMORY) {
4141 i386_mov_reg_membase(REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4144 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4149 /* fld from called function -- has other fpu_st_offset counter */
4151 store_reg_to_var_flt(iptr->dst, d);
4158 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4160 /* op1: 0 == array, 1 == class */
4161 /* val.a: (classinfo*) superclass */
4163 /* superclass is an interface:
4165 * return (sub != NULL) &&
4166 * (sub->vftbl->interfacetablelength > super->index) &&
4167 * (sub->vftbl->interfacetable[-super->index] != NULL);
4169 * superclass is a class:
4171 * return ((sub != NULL) && (0
4172 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4173 * super->vftbl->diffvall));
4177 classinfo *super = (classinfo*) iptr->val.a;
4179 var_to_reg_int(s1, src, REG_ITMP1);
4180 d = reg_of_var(iptr->dst, REG_ITMP3);
4182 M_INTMOVE(s1, REG_ITMP1);
4185 i386_alu_reg_reg(I386_XOR, d, d);
4186 if (iptr->op1) { /* class/interface */
4187 if (super->flags & ACC_INTERFACE) { /* interface */
4188 i386_test_reg_reg(s1, s1);
4190 /* TODO: clean up this calculation */
4192 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4195 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4198 /* CALCOFFSETBYTES(a, super->index); */
4199 CALCIMMEDIATEBYTES(a, super->index);
4205 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4212 i386_jcc(I386_CC_E, a);
4214 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4215 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4216 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4218 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4220 /* TODO: clean up this calculation */
4223 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4230 i386_jcc(I386_CC_LE, a);
4231 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4233 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP1);
4234 /* i386_setcc_reg(I386_CC_A, d); */
4235 /* i386_jcc(I386_CC_BE, 5); */
4236 i386_jcc(I386_CC_E, 5);
4237 i386_mov_imm_reg(1, d);
4240 } else { /* class */
4241 i386_test_reg_reg(s1, s1);
4243 /* TODO: clean up this calculation */
4245 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4248 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4250 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4253 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4263 i386_jcc(I386_CC_E, a);
4265 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4266 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4267 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4268 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4269 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4270 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4271 i386_alu_reg_reg(I386_XOR, d, d);
4273 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4274 i386_jcc(I386_CC_A, 5);
4275 i386_mov_imm_reg(1, d);
4279 panic ("internal error: no inlined array instanceof");
4281 store_reg_to_var_int(iptr->dst, d);
4284 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4286 /* op1: 0 == array, 1 == class */
4287 /* val.a: (classinfo*) superclass */
4289 /* superclass is an interface:
4291 * OK if ((sub == NULL) ||
4292 * (sub->vftbl->interfacetablelength > super->index) &&
4293 * (sub->vftbl->interfacetable[-super->index] != NULL));
4295 * superclass is a class:
4297 * OK if ((sub == NULL) || (0
4298 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4299 * super->vftbl->diffvall));
4303 classinfo *super = (classinfo*) iptr->val.a;
4305 d = reg_of_var(iptr->dst, REG_ITMP3);
4306 var_to_reg_int(s1, src, d);
4307 if (iptr->op1) { /* class/interface */
4308 if (super->flags & ACC_INTERFACE) { /* interface */
4309 i386_test_reg_reg(s1, s1);
4311 /* TODO: clean up this calculation */
4313 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4316 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetablelength));
4319 /* CALCOFFSETBYTES(a, super->index); */
4320 CALCIMMEDIATEBYTES(a, super->index);
4326 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*));
4331 i386_jcc(I386_CC_E, a);
4333 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4334 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetablelength), REG_ITMP2);
4335 i386_alu_imm_reg(I386_SUB, super->index, REG_ITMP2);
4337 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4338 i386_jcc(I386_CC_LE, 0);
4339 codegen_addxcastrefs(mcodeptr);
4340 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4342 i386_alu_imm_reg(I386_CMP, 0, REG_ITMP2);
4343 i386_jcc(I386_CC_E, 0);
4344 codegen_addxcastrefs(mcodeptr);
4346 } else { /* class */
4347 i386_test_reg_reg(s1, s1);
4349 /* TODO: clean up this calculation */
4351 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4356 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl, baseval));
4358 if (d != REG_ITMP3) {
4360 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4363 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4369 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, baseval));
4376 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl, diffval));
4383 i386_jcc(I386_CC_E, a);
4385 i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4386 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4387 i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
4388 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4389 codegen_threadcritstart(mcodeptr - mcodebase);
4391 if (d != REG_ITMP3) {
4392 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
4393 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4394 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4395 codegen_threadcritstop(mcodeptr - mcodebase);
4397 i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
4400 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP2);
4401 i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
4402 i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
4403 i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
4404 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4405 codegen_threadcritstop(mcodeptr - mcodebase);
4409 i386_alu_reg_reg(I386_CMP, REG_ITMP2, REG_ITMP1);
4410 i386_jcc(I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4411 codegen_addxcastrefs(mcodeptr);
4415 panic ("internal error: no inlined array checkcast");
4418 store_reg_to_var_int(iptr->dst, d);
4421 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4423 if (src->flags & INMEMORY) {
4424 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4427 i386_test_reg_reg(src->regoff, src->regoff);
4429 i386_jcc(I386_CC_L, 0);
4430 codegen_addxcheckarefs(mcodeptr);
4433 case ICMD_CHECKOOM: /* ... ==> ... */
4435 i386_test_reg_reg(REG_RESULT, REG_RESULT);
4436 i386_jcc(I386_CC_E, 0);
4437 codegen_addxoomrefs(mcodeptr);
4440 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4441 /* op1 = dimension, val.a = array descriptor */
4443 /* check for negative sizes and copy sizes to stack if necessary */
4445 MCODECHECK((iptr->op1 << 1) + 64);
4447 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4448 if (src->flags & INMEMORY) {
4449 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
4452 i386_test_reg_reg(src->regoff, src->regoff);
4454 i386_jcc(I386_CC_L, 0);
4455 codegen_addxcheckarefs(mcodeptr);
4458 * copy sizes to new stack location, be cause native function
4459 * builtin_nmultianewarray access them as (int *)
4461 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
4462 i386_mov_reg_membase(REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4464 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4466 if (src->varkind != ARGVAR) {
4467 if (src->flags & INMEMORY) {
4468 i386_mov_membase_reg(REG_SP, (src->regoff + intreg_argnum) * 8, REG_ITMP1);
4469 i386_mov_reg_membase(REG_ITMP1, REG_SP, (s1 + intreg_argnum) * 8);
4472 i386_mov_reg_membase(src->regoff, REG_SP, (s1 + intreg_argnum) * 8);
4476 i386_alu_imm_reg(I386_SUB, iptr->op1 * 4, REG_SP);
4478 /* a0 = dimension count */
4480 /* save stack pointer */
4481 M_INTMOVE(REG_SP, REG_ITMP1);
4483 i386_alu_imm_reg(I386_SUB, 12, REG_SP);
4484 i386_mov_imm_membase(iptr->op1, REG_SP, 0);
4486 /* a1 = arraydescriptor */
4488 i386_mov_imm_membase((s4) iptr->val.a, REG_SP, 4);
4490 /* a2 = pointer to dimensions = stack pointer */
4492 i386_mov_reg_membase(REG_ITMP1, REG_SP, 8);
4494 i386_mov_imm_reg((s4) (builtin_nmultianewarray), REG_ITMP1);
4495 i386_call_reg(REG_ITMP1);
4496 i386_alu_imm_reg(I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4498 s1 = reg_of_var(iptr->dst, REG_RESULT);
4499 M_INTMOVE(REG_RESULT, s1);
4500 store_reg_to_var_int(iptr->dst, s1);
4504 error ("Unknown pseudo command: %d", iptr->opc);
4507 } /* for instruction */
4509 /* copy values to interface registers */
4511 src = bptr->outstack;
4512 len = bptr->outdepth;
4516 if ((src->varkind != STACKVAR)) {
4518 if (IS_FLT_DBL_TYPE(s2)) {
4519 var_to_reg_flt(s1, src, REG_FTMP1);
4520 if (!(interfaces[len][s2].flags & INMEMORY)) {
4521 M_FLTMOVE(s1,interfaces[len][s2].regoff);
4524 panic("double store");
4525 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4529 var_to_reg_int(s1, src, REG_ITMP1);
4530 if (!IS_2_WORD_TYPE(interfaces[len][s2].type)) {
4531 if (!(interfaces[len][s2].flags & INMEMORY)) {
4532 M_INTMOVE(s1, interfaces[len][s2].regoff);
4535 i386_mov_reg_membase(s1, REG_SP, interfaces[len][s2].regoff * 8);
4539 if (interfaces[len][s2].flags & INMEMORY) {
4540 M_LNGMEMMOVE(s1, interfaces[len][s2].regoff);
4543 panic("copy interface registers: longs have to be in memory (end)");
4550 } /* if (bptr -> flags >= BBREACHED) */
4551 } /* for basic block */
4553 codegen_createlinenumbertable();
4555 /* bptr -> mpc = (int)((u1*) mcodeptr - mcodebase); */
4559 /* generate bound check stubs */
4560 u1 *xcodeptr = NULL;
4562 for (; xboundrefs != NULL; xboundrefs = xboundrefs->next) {
4563 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4564 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4565 xboundrefs->branchpos,
4566 (u1*) xcodeptr - (u1*) mcodebase - (2 + 5 + 5 + 2));
4571 gen_resolvebranch((u1*) mcodebase + xboundrefs->branchpos,
4572 xboundrefs->branchpos, (u1*) mcodeptr - mcodebase);
4576 /* move index register into REG_ITMP1 */
4577 i386_mov_reg_reg(xboundrefs->reg, REG_ITMP1); /* 2 bytes */
4579 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4580 dseg_adddata(mcodeptr);
4581 i386_mov_imm_reg(xboundrefs->branchpos - 6, REG_ITMP3); /* 5 bytes */
4582 i386_alu_reg_reg(I386_ADD, REG_ITMP3, REG_ITMP2_XPC); /* 2 bytes */
4584 if (xcodeptr != NULL) {
4585 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4588 xcodeptr = mcodeptr;
4590 i386_push_reg(REG_ITMP2_XPC);
4592 i386_alu_imm_reg(I386_SUB, 2 * 4, REG_SP);
4593 i386_mov_imm_membase((s4) string_java_lang_ArrayIndexOutOfBoundsException, REG_SP, 0 * 4);
4594 i386_mov_reg_membase(REG_ITMP1, REG_SP, 1 * 4);
4595 i386_mov_imm_reg((s4) new_exception_int, REG_ITMP1);
4596 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4597 i386_alu_imm_reg(I386_ADD, 2 * 4, REG_SP);
4599 i386_pop_reg(REG_ITMP2_XPC);
4601 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4602 i386_jmp_reg(REG_ITMP3);
4606 /* generate negative array size check stubs */
4609 for (; xcheckarefs != NULL; xcheckarefs = xcheckarefs->next) {
4610 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4611 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4612 xcheckarefs->branchpos,
4613 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4617 gen_resolvebranch((u1*) mcodebase + xcheckarefs->branchpos,
4618 xcheckarefs->branchpos, (u1*) mcodeptr - mcodebase);
4622 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4623 dseg_adddata(mcodeptr);
4624 i386_mov_imm_reg(xcheckarefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4625 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4627 if (xcodeptr != NULL) {
4628 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4631 xcodeptr = mcodeptr;
4633 i386_push_reg(REG_ITMP2_XPC);
4635 i386_alu_imm_reg(I386_SUB, 1 * 4, REG_SP);
4636 i386_mov_imm_membase((s4) string_java_lang_NegativeArraySizeException, REG_SP, 0 * 4);
4637 i386_mov_imm_reg((s4) new_exception, REG_ITMP1);
4638 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4639 i386_alu_imm_reg(I386_ADD, 1 * 4, REG_SP);
4641 i386_pop_reg(REG_ITMP2_XPC);
4643 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4644 i386_jmp_reg(REG_ITMP3);
4648 /* generate cast check stubs */
4651 for (; xcastrefs != NULL; xcastrefs = xcastrefs->next) {
4652 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4653 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4654 xcastrefs->branchpos,
4655 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4659 gen_resolvebranch((u1*) mcodebase + xcastrefs->branchpos,
4660 xcastrefs->branchpos, (u1*) mcodeptr - mcodebase);
4664 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4665 dseg_adddata(mcodeptr);
4666 i386_mov_imm_reg(xcastrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4667 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4669 if (xcodeptr != NULL) {
4670 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4673 xcodeptr = mcodeptr;
4675 i386_push_reg(REG_ITMP2_XPC);
4677 i386_alu_imm_reg(I386_SUB, 1 * 4, REG_SP);
4678 i386_mov_imm_membase((s4) string_java_lang_ClassCastException, REG_SP, 0 * 4);
4679 i386_mov_imm_reg((s4) new_exception, REG_ITMP1);
4680 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4681 i386_alu_imm_reg(I386_ADD, 1 * 4, REG_SP);
4683 i386_pop_reg(REG_ITMP2_XPC);
4685 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4686 i386_jmp_reg(REG_ITMP3);
4690 /* generate divide by zero check stubs */
4693 for (; xdivrefs != NULL; xdivrefs = xdivrefs->next) {
4694 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4695 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4696 xdivrefs->branchpos,
4697 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4701 gen_resolvebranch((u1*) mcodebase + xdivrefs->branchpos,
4702 xdivrefs->branchpos, (u1*) mcodeptr - mcodebase);
4706 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4707 dseg_adddata(mcodeptr);
4708 i386_mov_imm_reg(xdivrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4709 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4711 if (xcodeptr != NULL) {
4712 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4715 xcodeptr = mcodeptr;
4717 i386_push_reg(REG_ITMP2_XPC);
4719 i386_alu_imm_reg(I386_SUB, 2 * 4, REG_SP);
4720 i386_mov_imm_membase((s4) string_java_lang_ArithmeticException, REG_SP, 0 * 4);
4721 i386_mov_imm_membase((s4) string_java_lang_ArithmeticException_message, REG_SP, 1 * 4);
4722 i386_mov_imm_reg((s4) new_exception_message, REG_ITMP1);
4723 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4724 i386_alu_imm_reg(I386_ADD, 2 * 4, REG_SP);
4726 i386_pop_reg(REG_ITMP2_XPC);
4728 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4729 i386_jmp_reg(REG_ITMP3);
4733 /* generate oom check stubs */
4736 for (; xoomrefs != NULL; xoomrefs = xoomrefs->next) {
4737 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4738 gen_resolvebranch((u1*) mcodebase + xoomrefs->branchpos,
4739 xoomrefs->branchpos,
4740 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4744 gen_resolvebranch((u1*) mcodebase + xoomrefs->branchpos,
4745 xoomrefs->branchpos, (u1*) mcodeptr - mcodebase);
4749 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4750 dseg_adddata(mcodeptr);
4751 i386_mov_imm_reg(xoomrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4752 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4754 if (xcodeptr != NULL) {
4755 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4758 xcodeptr = mcodeptr;
4760 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4761 i386_push_reg(REG_ITMP2_XPC);
4762 i386_mov_imm_reg((s4) &builtin_get_exceptionptrptr, REG_ITMP1);
4763 i386_call_reg(REG_ITMP1);
4764 i386_mov_membase_reg(REG_RESULT, 0, REG_ITMP3);
4765 i386_mov_imm_membase(0, REG_RESULT, 0);
4766 i386_mov_reg_reg(REG_ITMP3, REG_ITMP1_XPTR);
4767 i386_pop_reg(REG_ITMP2_XPC);
4769 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP3);
4770 i386_mov_membase_reg(REG_ITMP3, 0, REG_ITMP1_XPTR);
4771 i386_mov_imm_membase(0, REG_ITMP3, 0);
4774 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4775 i386_jmp_reg(REG_ITMP3);
4779 /* generate null pointer check stubs */
4782 for (; xnullrefs != NULL; xnullrefs = xnullrefs->next) {
4783 if ((exceptiontablelength == 0) && (xcodeptr != NULL)) {
4784 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4785 xnullrefs->branchpos,
4786 (u1*) xcodeptr - (u1*) mcodebase - (5 + 5 + 2));
4790 gen_resolvebranch((u1*) mcodebase + xnullrefs->branchpos,
4791 xnullrefs->branchpos, (u1*) mcodeptr - mcodebase);
4795 i386_mov_imm_reg(0, REG_ITMP2_XPC); /* 5 bytes */
4796 dseg_adddata(mcodeptr);
4797 i386_mov_imm_reg(xnullrefs->branchpos - 6, REG_ITMP1); /* 5 bytes */
4798 i386_alu_reg_reg(I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4800 if (xcodeptr != NULL) {
4801 i386_jmp_imm(((u1 *) xcodeptr - (u1 *) mcodeptr) - 5);
4804 xcodeptr = mcodeptr;
4806 /* i386_mov_imm_reg((s4) proto_java_lang_NullPointerException, REG_ITMP1_XPTR); */
4808 i386_push_reg(REG_ITMP2_XPC);
4810 i386_alu_imm_reg(I386_SUB, 1 * 4, REG_SP);
4811 i386_mov_imm_membase((s4) string_java_lang_NullPointerException, REG_SP, 0 * 4);
4812 i386_mov_imm_reg((s4) new_exception, REG_ITMP1);
4813 i386_call_reg(REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4814 i386_alu_imm_reg(I386_ADD, 1 * 4, REG_SP);
4816 i386_pop_reg(REG_ITMP2_XPC);
4818 i386_mov_imm_reg((s4) asm_handle_exception, REG_ITMP3);
4819 i386_jmp_reg(REG_ITMP3);
4824 codegen_finish((int)((u1*) mcodeptr - mcodebase));
4826 if (compileverbose) {
4827 char logtext[MAXLOGTEXT];
4828 sprintf(logtext, "Generating code done: ");
4829 utf_sprint_classname(logtext + strlen(logtext), class->name);
4830 sprintf(logtext + strlen(logtext), ".");
4831 utf_sprint(logtext + strlen(logtext), method->name);
4832 utf_sprint_classname(logtext + strlen(logtext), descriptor);
4838 /* function createcompilerstub *************************************************
4840 creates a stub routine which calls the compiler
4842 *******************************************************************************/
4844 #define COMPSTUBSIZE 12
4846 u1 *createcompilerstub(methodinfo *m)
4848 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4849 mcodeptr = s; /* code generation pointer */
4851 /* code for the stub */
4852 i386_mov_imm_reg((s4) m, REG_ITMP1);/* pass method pointer to compiler */
4854 /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching */
4855 i386_mov_imm_reg((s4) asm_call_jit_compiler, REG_ITMP3); /* load address */
4856 i386_jmp_reg(REG_ITMP3); /* jump to compiler */
4859 count_cstub_len += COMPSTUBSIZE;
4866 /* function removecompilerstub *************************************************
4868 deletes a compilerstub from memory (simply by freeing it)
4870 *******************************************************************************/
4872 void removecompilerstub(u1 *stub)
4874 CFREE(stub, COMPSTUBSIZE);
4877 /* function: createnativestub **************************************************
4879 creates a stub routine which calls a native method
4881 *******************************************************************************/
4883 #define NATIVESTUBSIZE 340
4885 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4886 static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
4889 void i386_native_stub_debug(void **p) {
4890 printf("Pos on stack: %p\n",p);
4891 printf("Return adress should be: %p\n",*p);
4894 void i386_native_stub_debug2(void **p) {
4895 printf("Pos on stack: %p\n",p);
4896 printf("Return for lookup is: %p\n",*p);
4899 void traverseStackInfo() {
4900 void **p=builtin_asm_get_stackframeinfo();
4903 printf("base addr:%p, methodinfo:%p\n",*p,(methodinfo*)((*p)+8));
4904 methodinfo *m=*((methodinfo**)((*p)+8));
4905 utf_display(m->name);
4913 u1 *createnativestub(functionptr f, methodinfo *m)
4915 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4919 int stackframesize = 4+12; /* initial 4 bytes is space for jni env,
4920 + 4 byte thread pointer + 4 byte previous pointer + method info*/
4921 int stackframeoffset = 4;
4925 mcodeptr = s; /* make macros work */
4927 if (m->flags & ACC_STATIC) {
4928 stackframesize += 4;
4929 stackframeoffset += 4;
4933 descriptor2types(m); /* set paramcount and paramtypes */
4936 /* i386_push_reg(REG_SP);
4937 i386_mov_imm_reg((s4) i386_native_stub_debug, REG_ITMP1);
4938 i386_call_reg(REG_ITMP1);
4939 i386_pop_reg(REG_ITMP1);*/
4942 /* if function is static, check for initialized */
4944 if (m->flags & ACC_STATIC) {
4945 /* if class isn't yet initialized, do it */
4946 if (!m->class->initialized) {
4947 /* call helper function which patches this code */
4948 i386_mov_imm_reg((s4) m->class, REG_ITMP1);
4949 i386_mov_imm_reg((s4) asm_check_clinit, REG_ITMP2);
4950 i386_call_reg(REG_ITMP2);
4955 i386_alu_imm_reg(I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
4957 for (p = 0; p < m->paramcount; p++) {
4958 t = m->paramtypes[p];
4959 if (IS_INT_LNG_TYPE(t)) {
4960 if (IS_2_WORD_TYPE(t)) {
4961 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4962 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
4963 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4964 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4966 } else if (t == TYPE_ADR) {
4967 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
4968 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4969 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4970 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4973 i386_mov_membase_reg(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
4975 i386_mov_reg_membase(EAX, REG_SP, p * 8);
4976 i386_mov_reg_membase(EDX, REG_SP, p * 8 + 4);
4980 if (!IS_2_WORD_TYPE(t)) {
4981 i386_flds_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4982 i386_fstps_membase(REG_SP, p * 8);
4983 i386_alu_reg_reg(I386_XOR, REG_ITMP2, REG_ITMP2);
4984 i386_mov_reg_membase(REG_ITMP2, REG_SP, p * 8 + 4);
4987 i386_fldl_membase(REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
4988 i386_fstpl_membase(REG_SP, p * 8);
4993 i386_alu_reg_reg(I386_XOR, REG_ITMP1, REG_ITMP1);
4994 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
4995 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8);
4996 i386_mov_reg_membase(REG_ITMP1, REG_SP, p * 8 + 4);
4999 i386_mov_imm_membase((s4) m, REG_SP, TRACE_ARGS_NUM * 8);
5001 i386_mov_imm_reg((s4) builtin_trace_args, REG_ITMP1);
5002 i386_call_reg(REG_ITMP1);
5004 i386_alu_imm_reg(I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5008 * mark the whole fpu stack as free for native functions
5009 * (only for saved register count == 0)
5020 /* calculate stackframe size for native function */
5021 tptr = m->paramtypes;
5022 for (i = 0; i < m->paramcount; i++) {
5027 stackframesize += 4;
5032 stackframesize += 8;
5036 panic("unknown parameter type in native function");
5040 i386_alu_imm_reg(I386_SUB, stackframesize, REG_SP);
5042 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
5043 i386_mov_imm_membase((s4) m, REG_SP,stackframesize-4);
5044 i386_mov_imm_reg((s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
5045 i386_call_reg(REG_ITMP1);
5046 i386_mov_reg_membase(REG_RESULT,REG_SP,stackframesize-8); /*save thread specific pointer*/
5047 i386_mov_membase_reg(REG_RESULT,0,REG_ITMP2);
5048 i386_mov_reg_membase(REG_ITMP2,REG_SP,stackframesize-12); /*save previous value of memory adress pointed to by thread specific pointer*/
5049 i386_mov_reg_reg(REG_SP,REG_ITMP2);
5050 i386_alu_imm_reg(I386_ADD,stackframesize-12,REG_ITMP2);
5051 i386_mov_reg_membase(REG_ITMP2,REG_RESULT,0);
5054 /* i386_mov_imm_membase((s4) m, REG_SP,stackframesize-4);
5055 i386_mov_imm_membase((s4) m, REG_SP,stackframesize-8);
5056 i386_mov_imm_membase((s4) m, REG_SP,stackframesize-12);*/
5058 /* CREATE DYNAMIC STACK INFO -- END*/
5061 tptr = m->paramtypes;
5062 for (i = 0; i < m->paramcount; i++) {
5067 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5068 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5069 stackframeoffset += 4;
5074 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5075 i386_mov_membase_reg(REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5076 i386_mov_reg_membase(REG_ITMP1, REG_SP, stackframeoffset);
5077 i386_mov_reg_membase(REG_ITMP2, REG_SP, stackframeoffset + 4);
5078 stackframeoffset += 8;
5082 panic("unknown parameter type in native function");
5086 if (m->flags & ACC_STATIC) {
5087 /* put class into second argument */
5088 i386_mov_imm_membase((s4) m->class, REG_SP, 4);
5091 /* put env into first argument */
5092 i386_mov_imm_membase((s4) &env, REG_SP, 0);
5094 i386_mov_imm_reg((s4) f, REG_ITMP1);
5095 i386_call_reg(REG_ITMP1);
5096 /*REMOVE DYNAMIC STACK INFO -BEGIN */
5097 i386_push_reg(REG_RESULT2);
5098 i386_mov_membase_reg(REG_SP,stackframesize-8,REG_ITMP2); /*old value*/
5099 i386_mov_membase_reg(REG_SP,stackframesize-4,REG_RESULT2); /*pointer*/
5100 i386_mov_reg_membase(REG_ITMP2,REG_RESULT2,0);
5101 i386_pop_reg(REG_RESULT2);
5102 /*REMOVE DYNAMIC STACK INFO -END */
5104 i386_alu_imm_reg(I386_ADD, stackframesize, REG_SP);
5108 i386_alu_imm_reg(I386_SUB, 4 + 8 + 8 + 4, REG_SP);
5110 i386_mov_imm_membase((s4) m, REG_SP, 0);
5112 i386_mov_reg_membase(REG_RESULT, REG_SP, 4);
5113 i386_mov_reg_membase(REG_RESULT2, REG_SP, 4 + 4);
5115 i386_fstl_membase(REG_SP, 4 + 8);
5116 i386_fsts_membase(REG_SP, 4 + 8 + 8);
5118 i386_mov_imm_reg((s4) builtin_displaymethodstop, REG_ITMP1);
5119 i386_call_reg(REG_ITMP1);
5121 i386_mov_membase_reg(REG_SP, 4, REG_RESULT);
5122 i386_mov_membase_reg(REG_SP, 4 + 4, REG_RESULT2);
5124 i386_alu_imm_reg(I386_ADD, 4 + 8 + 8 + 4, REG_SP);
5128 /* we can't use REG_ITMP3 == REG_RESULT2 */
5129 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5130 i386_push_reg(REG_RESULT);
5131 i386_push_reg(REG_RESULT2);
5132 i386_call_mem((s4) &callgetexceptionptrptr);
5133 i386_mov_membase_reg(REG_RESULT, 0, REG_ITMP2);
5134 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
5135 i386_pop_reg(REG_RESULT2);
5136 i386_pop_reg(REG_RESULT);
5138 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP2);
5139 i386_mov_membase_reg(REG_ITMP2, 0, REG_ITMP2);
5140 i386_test_reg_reg(REG_ITMP2, REG_ITMP2);
5142 i386_jcc(I386_CC_NE, 1);
5146 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5147 i386_push_reg(REG_ITMP2);
5148 i386_call_mem((s4) &callgetexceptionptrptr);
5149 i386_mov_imm_membase(0, REG_RESULT, 0);
5150 i386_pop_reg(REG_ITMP1_XPTR);
5152 i386_mov_reg_reg(REG_ITMP2, REG_ITMP1_XPTR);
5153 i386_mov_imm_reg((s4) &_exceptionptr, REG_ITMP2);
5154 i386_mov_imm_membase(0, REG_ITMP2, 0);
5156 i386_mov_membase_reg(REG_SP, 0, REG_ITMP2_XPC);
5157 i386_alu_imm_reg(I386_SUB, 2, REG_ITMP2_XPC);
5159 i386_mov_imm_reg((s4) asm_handle_nat_exception, REG_ITMP3);
5160 i386_jmp_reg(REG_ITMP3);
5163 count_nstub_len += NATIVESTUBSIZE;
5169 /* function: removenativestub **************************************************
5171 removes a previously created native-stub from memory
5173 *******************************************************************************/
5175 void removenativestub(u1 *stub)
5177 CFREE(stub, NATIVESTUBSIZE);
5182 void i386_emit_ialu(s4 alu_op, stackptr src, instruction *iptr)
5184 if (iptr->dst->flags & INMEMORY) {
5185 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5186 if (src->regoff == iptr->dst->regoff) {
5187 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5188 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5190 } else if (src->prev->regoff == iptr->dst->regoff) {
5191 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5192 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5195 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5196 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5197 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5200 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5201 if (src->regoff == iptr->dst->regoff) {
5202 i386_alu_reg_membase(alu_op, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5205 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5206 i386_alu_reg_reg(alu_op, src->prev->regoff, REG_ITMP1);
5207 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5210 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5211 if (src->prev->regoff == iptr->dst->regoff) {
5212 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
5215 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5216 i386_alu_reg_reg(alu_op, src->regoff, REG_ITMP1);
5217 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5221 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5222 i386_alu_reg_membase(alu_op, src->regoff, REG_SP, iptr->dst->regoff * 8);
5226 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5227 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5228 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
5230 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5231 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5232 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, iptr->dst->regoff);
5234 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5235 M_INTMOVE(src->regoff, iptr->dst->regoff);
5236 i386_alu_membase_reg(alu_op, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5239 if (src->regoff == iptr->dst->regoff) {
5240 i386_alu_reg_reg(alu_op, src->prev->regoff, iptr->dst->regoff);
5243 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5244 i386_alu_reg_reg(alu_op, src->regoff, iptr->dst->regoff);
5252 void i386_emit_ialuconst(s4 alu_op, stackptr src, instruction *iptr)
5254 if (iptr->dst->flags & INMEMORY) {
5255 if (src->flags & INMEMORY) {
5256 if (src->regoff == iptr->dst->regoff) {
5257 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5260 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5261 i386_alu_imm_reg(alu_op, iptr->val.i, REG_ITMP1);
5262 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5266 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5267 i386_alu_imm_membase(alu_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5271 if (src->flags & INMEMORY) {
5272 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5273 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5276 M_INTMOVE(src->regoff, iptr->dst->regoff);
5277 i386_alu_imm_reg(alu_op, iptr->val.i, iptr->dst->regoff);
5284 void i386_emit_lalu(s4 alu_op, stackptr src, instruction *iptr)
5286 if (iptr->dst->flags & INMEMORY) {
5287 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5288 if (src->regoff == iptr->dst->regoff) {
5289 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5290 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5291 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5292 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5294 } else if (src->prev->regoff == iptr->dst->regoff) {
5295 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5296 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5297 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5298 i386_alu_reg_membase(alu_op, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5301 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5302 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8, REG_ITMP1);
5303 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5304 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
5305 i386_alu_membase_reg(alu_op, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5306 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5314 void i386_emit_laluconst(s4 alu_op, stackptr src, instruction *iptr)
5316 if (iptr->dst->flags & INMEMORY) {
5317 if (src->flags & INMEMORY) {
5318 if (src->regoff == iptr->dst->regoff) {
5319 i386_alu_imm_membase(alu_op, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
5320 i386_alu_imm_membase(alu_op, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
5323 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5324 i386_alu_imm_reg(alu_op, iptr->val.l, REG_ITMP1);
5325 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5326 i386_mov_membase_reg(REG_SP, src->regoff * 8 + 4, REG_ITMP1);
5327 i386_alu_imm_reg(alu_op, iptr->val.l >> 32, REG_ITMP1);
5328 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
5336 void i386_emit_ishift(s4 shift_op, stackptr src, instruction *iptr)
5338 if (iptr->dst->flags & INMEMORY) {
5339 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5340 if (src->prev->regoff == iptr->dst->regoff) {
5341 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5342 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5345 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5346 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5347 i386_shift_reg(shift_op, REG_ITMP1);
5348 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5351 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5352 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5353 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5354 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5356 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5357 if (src->prev->regoff == iptr->dst->regoff) {
5358 M_INTMOVE(src->regoff, ECX);
5359 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5362 M_INTMOVE(src->regoff, ECX);
5363 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, REG_ITMP1);
5364 i386_shift_reg(shift_op, REG_ITMP1);
5365 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5369 M_INTMOVE(src->regoff, ECX);
5370 i386_mov_reg_membase(src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
5371 i386_shift_membase(shift_op, REG_SP, iptr->dst->regoff * 8);
5375 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5376 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5377 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5378 i386_shift_reg(shift_op, iptr->dst->regoff);
5380 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
5381 i386_mov_membase_reg(REG_SP, src->regoff * 8, ECX);
5382 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5383 i386_shift_reg(shift_op, iptr->dst->regoff);
5385 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
5386 M_INTMOVE(src->regoff, ECX);
5387 i386_mov_membase_reg(REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
5388 i386_shift_reg(shift_op, iptr->dst->regoff);
5391 M_INTMOVE(src->regoff, ECX);
5392 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
5393 i386_shift_reg(shift_op, iptr->dst->regoff);
5400 void i386_emit_ishiftconst(s4 shift_op, stackptr src, instruction *iptr)
5402 if ((src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5403 if (src->regoff == iptr->dst->regoff) {
5404 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5407 i386_mov_membase_reg(REG_SP, src->regoff * 8, REG_ITMP1);
5408 i386_shift_imm_reg(shift_op, iptr->val.i, REG_ITMP1);
5409 i386_mov_reg_membase(REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
5412 } else if ((src->flags & INMEMORY) && !(iptr->dst->flags & INMEMORY)) {
5413 i386_mov_membase_reg(REG_SP, src->regoff * 8, iptr->dst->regoff);
5414 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5416 } else if (!(src->flags & INMEMORY) && (iptr->dst->flags & INMEMORY)) {
5417 i386_mov_reg_membase(src->regoff, REG_SP, iptr->dst->regoff * 8);
5418 i386_shift_imm_membase(shift_op, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5421 M_INTMOVE(src->regoff, iptr->dst->regoff);
5422 i386_shift_imm_reg(shift_op, iptr->val.i, iptr->dst->regoff);
5428 void i386_emit_ifcc_iconst(s4 if_op, stackptr src, instruction *iptr)
5430 if (iptr->dst->flags & INMEMORY) {
5433 if (src->flags & INMEMORY) {
5434 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5437 i386_test_reg_reg(src->regoff, src->regoff);
5441 CALCOFFSETBYTES(offset, REG_SP, iptr->dst->regoff * 8);
5443 i386_jcc(if_op, offset + (iptr[1].opc == ICMD_ELSE_ICONST) ? 5 + offset : 0);
5444 i386_mov_imm_membase(iptr->val.i, REG_SP, iptr->dst->regoff * 8);
5446 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5447 i386_jmp_imm(offset);
5448 i386_mov_imm_membase(iptr[1].val.i, REG_SP, iptr->dst->regoff * 8);
5452 if (src->flags & INMEMORY) {
5453 i386_alu_imm_membase(I386_CMP, 0, REG_SP, src->regoff * 8);
5456 i386_test_reg_reg(src->regoff, src->regoff);
5459 i386_jcc(if_op, (iptr[1].opc == ICMD_ELSE_ICONST) ? 10 : 5);
5460 i386_mov_imm_reg(iptr->val.i, iptr->dst->regoff);
5462 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
5464 i386_mov_imm_reg(iptr[1].val.i, iptr->dst->regoff);
5474 void i386_mov_reg_reg(s4 reg, s4 dreg) {
5475 *(mcodeptr++) = (u1) 0x89;
5476 i386_emit_reg((reg),(dreg));
5480 void i386_mov_imm_reg(s4 imm, s4 reg) {
5481 *(mcodeptr++) = (u1) 0xb8 + ((reg) & 0x07);
5482 i386_emit_imm32((imm));
5486 void i386_movb_imm_reg(s4 imm, s4 reg) {
5487 *(mcodeptr++) = (u1) 0xc6;
5488 i386_emit_reg(0,(reg));
5489 i386_emit_imm8((imm));
5493 void i386_mov_membase_reg(s4 basereg, s4 disp, s4 reg) {
5494 *(mcodeptr++) = (u1) 0x8b;
5495 i386_emit_membase((basereg),(disp),(reg));
5500 * this one is for INVOKEVIRTUAL/INVOKEINTERFACE to have a
5501 * constant membase immediate length of 32bit
5503 void i386_mov_membase32_reg(s4 basereg, s4 disp, s4 reg) {
5504 *(mcodeptr++) = (u1) 0x8b;
5505 i386_address_byte(2, (reg), (basereg));
5506 i386_emit_imm32((disp));
5510 void i386_mov_reg_membase(s4 reg, s4 basereg, s4 disp) {
5511 *(mcodeptr++) = (u1) 0x89;
5512 i386_emit_membase((basereg),(disp),(reg));
5516 void i386_mov_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5517 *(mcodeptr++) = (u1) 0x8b;
5518 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5522 void i386_mov_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5523 *(mcodeptr++) = (u1) 0x89;
5524 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5528 void i386_mov_mem_reg(s4 mem, s4 dreg) {
5529 *(mcodeptr++) = (u1) 0x8b;
5530 i386_emit_mem((dreg),(mem));
5534 void i386_movw_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5535 *(mcodeptr++) = (u1) 0x66;
5536 *(mcodeptr++) = (u1) 0x89;
5537 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5541 void i386_movb_reg_memindex(s4 reg, s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5542 *(mcodeptr++) = (u1) 0x88;
5543 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5547 void i386_mov_imm_membase(s4 imm, s4 basereg, s4 disp) {
5548 *(mcodeptr++) = (u1) 0xc7;
5549 i386_emit_membase((basereg),(disp),0);
5550 i386_emit_imm32((imm));
5554 void i386_movsbl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5555 *(mcodeptr++) = (u1) 0x0f;
5556 *(mcodeptr++) = (u1) 0xbe;
5557 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5561 void i386_movswl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5562 *(mcodeptr++) = (u1) 0x0f;
5563 *(mcodeptr++) = (u1) 0xbf;
5564 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5568 void i386_movzwl_memindex_reg(s4 disp, s4 basereg, s4 indexreg, s4 scale, s4 reg) {
5569 *(mcodeptr++) = (u1) 0x0f;
5570 *(mcodeptr++) = (u1) 0xb7;
5571 i386_emit_memindex((reg),(disp),(basereg),(indexreg),(scale));
5579 void i386_alu_reg_reg(s4 opc, s4 reg, s4 dreg) {
5580 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5581 i386_emit_reg((reg),(dreg));
5585 void i386_alu_reg_membase(s4 opc, s4 reg, s4 basereg, s4 disp) {
5586 *(mcodeptr++) = (((u1) (opc)) << 3) + 1;
5587 i386_emit_membase((basereg),(disp),(reg));
5591 void i386_alu_membase_reg(s4 opc, s4 basereg, s4 disp, s4 reg) {
5592 *(mcodeptr++) = (((u1) (opc)) << 3) + 3;
5593 i386_emit_membase((basereg),(disp),(reg));
5597 void i386_alu_imm_reg(s4 opc, s4 imm, s4 dreg) {
5598 if (i386_is_imm8(imm)) {
5599 *(mcodeptr++) = (u1) 0x83;
5600 i386_emit_reg((opc),(dreg));
5601 i386_emit_imm8((imm));
5603 *(mcodeptr++) = (u1) 0x81;
5604 i386_emit_reg((opc),(dreg));
5605 i386_emit_imm32((imm));
5610 void i386_alu_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5611 if (i386_is_imm8(imm)) {
5612 *(mcodeptr++) = (u1) 0x83;
5613 i386_emit_membase((basereg),(disp),(opc));
5614 i386_emit_imm8((imm));
5616 *(mcodeptr++) = (u1) 0x81;
5617 i386_emit_membase((basereg),(disp),(opc));
5618 i386_emit_imm32((imm));
5623 void i386_test_reg_reg(s4 reg, s4 dreg) {
5624 *(mcodeptr++) = (u1) 0x85;
5625 i386_emit_reg((reg),(dreg));
5629 void i386_test_imm_reg(s4 imm, s4 reg) {
5630 *(mcodeptr++) = (u1) 0xf7;
5631 i386_emit_reg(0,(reg));
5632 i386_emit_imm32((imm));
5638 * inc, dec operations
5640 void i386_dec_mem(s4 mem) {
5641 *(mcodeptr++) = (u1) 0xff;
5642 i386_emit_mem(1,(mem));
5648 *(mcodeptr++) = (u1) 0x99;
5653 void i386_imul_reg_reg(s4 reg, s4 dreg) {
5654 *(mcodeptr++) = (u1) 0x0f;
5655 *(mcodeptr++) = (u1) 0xaf;
5656 i386_emit_reg((dreg),(reg));
5660 void i386_imul_membase_reg(s4 basereg, s4 disp, s4 dreg) {
5661 *(mcodeptr++) = (u1) 0x0f;
5662 *(mcodeptr++) = (u1) 0xaf;
5663 i386_emit_membase((basereg),(disp),(dreg));
5667 void i386_imul_imm_reg(s4 imm, s4 dreg) {
5668 if (i386_is_imm8((imm))) {
5669 *(mcodeptr++) = (u1) 0x6b;
5670 i386_emit_reg(0,(dreg));
5671 i386_emit_imm8((imm));
5673 *(mcodeptr++) = (u1) 0x69;
5674 i386_emit_reg(0,(dreg));
5675 i386_emit_imm32((imm));
5680 void i386_imul_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5681 if (i386_is_imm8((imm))) {
5682 *(mcodeptr++) = (u1) 0x6b;
5683 i386_emit_reg((dreg),(reg));
5684 i386_emit_imm8((imm));
5686 *(mcodeptr++) = (u1) 0x69;
5687 i386_emit_reg((dreg),(reg));
5688 i386_emit_imm32((imm));
5693 void i386_imul_imm_membase_reg(s4 imm, s4 basereg, s4 disp, s4 dreg) {
5694 if (i386_is_imm8((imm))) {
5695 *(mcodeptr++) = (u1) 0x6b;
5696 i386_emit_membase((basereg),(disp),(dreg));
5697 i386_emit_imm8((imm));
5699 *(mcodeptr++) = (u1) 0x69;
5700 i386_emit_membase((basereg),(disp),(dreg));
5701 i386_emit_imm32((imm));
5706 void i386_mul_membase(s4 basereg, s4 disp) {
5707 *(mcodeptr++) = (u1) 0xf7;
5708 i386_emit_membase((basereg),(disp),4);
5712 void i386_idiv_reg(s4 reg) {
5713 *(mcodeptr++) = (u1) 0xf7;
5714 i386_emit_reg(7,(reg));
5720 *(mcodeptr++) = (u1) 0xc3;
5728 void i386_shift_reg(s4 opc, s4 reg) {
5729 *(mcodeptr++) = (u1) 0xd3;
5730 i386_emit_reg((opc),(reg));
5734 void i386_shift_membase(s4 opc, s4 basereg, s4 disp) {
5735 *(mcodeptr++) = (u1) 0xd3;
5736 i386_emit_membase((basereg),(disp),(opc));
5740 void i386_shift_imm_reg(s4 opc, s4 imm, s4 dreg) {
5742 *(mcodeptr++) = (u1) 0xd1;
5743 i386_emit_reg((opc),(dreg));
5745 *(mcodeptr++) = (u1) 0xc1;
5746 i386_emit_reg((opc),(dreg));
5747 i386_emit_imm8((imm));
5752 void i386_shift_imm_membase(s4 opc, s4 imm, s4 basereg, s4 disp) {
5754 *(mcodeptr++) = (u1) 0xd1;
5755 i386_emit_membase((basereg),(disp),(opc));
5757 *(mcodeptr++) = (u1) 0xc1;
5758 i386_emit_membase((basereg),(disp),(opc));
5759 i386_emit_imm8((imm));
5764 void i386_shld_reg_reg(s4 reg, s4 dreg) {
5765 *(mcodeptr++) = (u1) 0x0f;
5766 *(mcodeptr++) = (u1) 0xa5;
5767 i386_emit_reg((reg),(dreg));
5771 void i386_shld_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5772 *(mcodeptr++) = (u1) 0x0f;
5773 *(mcodeptr++) = (u1) 0xa4;
5774 i386_emit_reg((reg),(dreg));
5775 i386_emit_imm8((imm));
5779 void i386_shld_reg_membase(s4 reg, s4 basereg, s4 disp) {
5780 *(mcodeptr++) = (u1) 0x0f;
5781 *(mcodeptr++) = (u1) 0xa5;
5782 i386_emit_membase((basereg),(disp),(reg));
5786 void i386_shrd_reg_reg(s4 reg, s4 dreg) {
5787 *(mcodeptr++) = (u1) 0x0f;
5788 *(mcodeptr++) = (u1) 0xad;
5789 i386_emit_reg((reg),(dreg));
5793 void i386_shrd_imm_reg_reg(s4 imm, s4 reg, s4 dreg) {
5794 *(mcodeptr++) = (u1) 0x0f;
5795 *(mcodeptr++) = (u1) 0xac;
5796 i386_emit_reg((reg),(dreg));
5797 i386_emit_imm8((imm));
5801 void i386_shrd_reg_membase(s4 reg, s4 basereg, s4 disp) {
5802 *(mcodeptr++) = (u1) 0x0f;
5803 *(mcodeptr++) = (u1) 0xad;
5804 i386_emit_membase((basereg),(disp),(reg));
5812 void i386_jmp_imm(s4 imm) {
5813 *(mcodeptr++) = (u1) 0xe9;
5814 i386_emit_imm32((imm));
5818 void i386_jmp_reg(s4 reg) {
5819 *(mcodeptr++) = (u1) 0xff;
5820 i386_emit_reg(4,(reg));
5824 void i386_jcc(s4 opc, s4 imm) {
5825 *(mcodeptr++) = (u1) 0x0f;
5826 *(mcodeptr++) = (u1) (0x80 + (opc));
5827 i386_emit_imm32((imm));
5833 * conditional set operations
5835 void i386_setcc_reg(s4 opc, s4 reg) {
5836 *(mcodeptr++) = (u1) 0x0f;
5837 *(mcodeptr++) = (u1) (0x90 + (opc));
5838 i386_emit_reg(0,(reg));
5842 void i386_setcc_membase(s4 opc, s4 basereg, s4 disp) {
5843 *(mcodeptr++) = (u1) 0x0f;
5844 *(mcodeptr++) = (u1) (0x90 + (opc));
5845 i386_emit_membase((basereg),(disp),0);
5849 void i386_xadd_reg_mem(s4 reg, s4 mem) {
5850 *(mcodeptr++) = (u1) 0x0f;
5851 *(mcodeptr++) = (u1) 0xc1;
5852 i386_emit_mem((reg),(mem));
5856 void i386_neg_reg(s4 reg) {
5857 *(mcodeptr++) = (u1) 0xf7;
5858 i386_emit_reg(3,(reg));
5862 void i386_neg_membase(s4 basereg, s4 disp) {
5863 *(mcodeptr++) = (u1) 0xf7;
5864 i386_emit_membase((basereg),(disp),3);
5869 void i386_push_imm(s4 imm) {
5870 *(mcodeptr++) = (u1) 0x68;
5871 i386_emit_imm32((imm));
5875 void i386_pop_reg(s4 reg) {
5876 *(mcodeptr++) = (u1) 0x58 + (0x07 & (reg));
5880 void i386_push_reg(s4 reg) {
5881 *(mcodeptr++) = (u1) 0x50 + (0x07 & (reg));
5886 *(mcodeptr++) = (u1) 0x90;
5891 *(mcodeptr++) = (u1) 0xf0;
5898 void i386_call_reg(s4 reg) {
5899 *(mcodeptr++) = (u1) 0xff;
5900 i386_emit_reg(2,(reg));
5904 void i386_call_imm(s4 imm) {
5905 *(mcodeptr++) = (u1) 0xe8;
5906 i386_emit_imm32((imm));
5910 void i386_call_mem(s4 mem) {
5911 *(mcodeptr++) = (u1) 0xff;
5912 i386_emit_mem(2, (mem));
5918 * floating point instructions
5921 *(mcodeptr++) = (u1) 0xd9;
5922 *(mcodeptr++) = (u1) 0xe8;
5927 *(mcodeptr++) = (u1) 0xd9;
5928 *(mcodeptr++) = (u1) 0xee;
5932 void i386_fld_reg(s4 reg) {
5933 *(mcodeptr++) = (u1) 0xd9;
5934 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
5938 void i386_flds_membase(s4 basereg, s4 disp) {
5939 *(mcodeptr++) = (u1) 0xd9;
5940 i386_emit_membase((basereg),(disp),0);
5944 void i386_fldl_membase(s4 basereg, s4 disp) {
5945 *(mcodeptr++) = (u1) 0xdd;
5946 i386_emit_membase((basereg),(disp),0);
5950 void i386_fldt_membase(s4 basereg, s4 disp) {
5951 *(mcodeptr++) = (u1) 0xdb;
5952 i386_emit_membase((basereg),(disp),5);
5956 void i386_flds_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5957 *(mcodeptr++) = (u1) 0xd9;
5958 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5962 void i386_fldl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
5963 *(mcodeptr++) = (u1) 0xdd;
5964 i386_emit_memindex(0,(disp),(basereg),(indexreg),(scale));
5970 void i386_fildl_membase(s4 basereg, s4 disp) {
5971 *(mcodeptr++) = (u1) 0xdb;
5972 i386_emit_membase((basereg),(disp),0);
5976 void i386_fildll_membase(s4 basereg, s4 disp) {
5977 *(mcodeptr++) = (u1) 0xdf;
5978 i386_emit_membase((basereg),(disp),5);
5984 void i386_fst_reg(s4 reg) {
5985 *(mcodeptr++) = (u1) 0xdd;
5986 *(mcodeptr++) = (u1) 0xd0 + (0x07 & (reg));
5990 void i386_fsts_membase(s4 basereg, s4 disp) {
5991 *(mcodeptr++) = (u1) 0xd9;
5992 i386_emit_membase((basereg),(disp),2);
5996 void i386_fstl_membase(s4 basereg, s4 disp) {
5997 *(mcodeptr++) = (u1) 0xdd;
5998 i386_emit_membase((basereg),(disp),2);
6002 void i386_fsts_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
6003 *(mcodeptr++) = (u1) 0xd9;
6004 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
6008 void i386_fstl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
6009 *(mcodeptr++) = (u1) 0xdd;
6010 i386_emit_memindex(2,(disp),(basereg),(indexreg),(scale));
6014 void i386_fstp_reg(s4 reg) {
6015 *(mcodeptr++) = (u1) 0xdd;
6016 *(mcodeptr++) = (u1) 0xd8 + (0x07 & (reg));
6020 void i386_fstps_membase(s4 basereg, s4 disp) {
6021 *(mcodeptr++) = (u1) 0xd9;
6022 i386_emit_membase((basereg),(disp),3);
6026 void i386_fstpl_membase(s4 basereg, s4 disp) {
6027 *(mcodeptr++) = (u1) 0xdd;
6028 i386_emit_membase((basereg),(disp),3);
6032 void i386_fstpt_membase(s4 basereg, s4 disp) {
6033 *(mcodeptr++) = (u1) 0xdb;
6034 i386_emit_membase((basereg),(disp),7);
6038 void i386_fstps_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
6039 *(mcodeptr++) = (u1) 0xd9;
6040 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
6044 void i386_fstpl_memindex(s4 disp, s4 basereg, s4 indexreg, s4 scale) {
6045 *(mcodeptr++) = (u1) 0xdd;
6046 i386_emit_memindex(3,(disp),(basereg),(indexreg),(scale));
6050 void i386_fistl_membase(s4 basereg, s4 disp) {
6051 *(mcodeptr++) = (u1) 0xdb;
6052 i386_emit_membase((basereg),(disp),2);
6056 void i386_fistpl_membase(s4 basereg, s4 disp) {
6057 *(mcodeptr++) = (u1) 0xdb;
6058 i386_emit_membase((basereg),(disp),3);
6062 void i386_fistpll_membase(s4 basereg, s4 disp) {
6063 *(mcodeptr++) = (u1) 0xdf;
6064 i386_emit_membase((basereg),(disp),7);
6069 *(mcodeptr++) = (u1) 0xd9;
6070 *(mcodeptr++) = (u1) 0xe0;
6075 *(mcodeptr++) = (u1) 0xde;
6076 *(mcodeptr++) = (u1) 0xc1;
6080 void i386_fadd_reg_st(s4 reg) {
6081 *(mcodeptr++) = (u1) 0xd8;
6082 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
6086 void i386_fadd_st_reg(s4 reg) {
6087 *(mcodeptr++) = (u1) 0xdc;
6088 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
6092 void i386_faddp_st_reg(s4 reg) {
6093 *(mcodeptr++) = (u1) 0xde;
6094 *(mcodeptr++) = (u1) 0xc0 + (0x0f & (reg));
6098 void i386_fadds_membase(s4 basereg, s4 disp) {
6099 *(mcodeptr++) = (u1) 0xd8;
6100 i386_emit_membase((basereg),(disp),0);
6104 void i386_faddl_membase(s4 basereg, s4 disp) {
6105 *(mcodeptr++) = (u1) 0xdc;
6106 i386_emit_membase((basereg),(disp),0);
6110 void i386_fsub_reg_st(s4 reg) {
6111 *(mcodeptr++) = (u1) 0xd8;
6112 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
6116 void i386_fsub_st_reg(s4 reg) {
6117 *(mcodeptr++) = (u1) 0xdc;
6118 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6122 void i386_fsubp_st_reg(s4 reg) {
6123 *(mcodeptr++) = (u1) 0xde;
6124 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6129 *(mcodeptr++) = (u1) 0xde;
6130 *(mcodeptr++) = (u1) 0xe9;
6134 void i386_fsubs_membase(s4 basereg, s4 disp) {
6135 *(mcodeptr++) = (u1) 0xd8;
6136 i386_emit_membase((basereg),(disp),4);
6140 void i386_fsubl_membase(s4 basereg, s4 disp) {
6141 *(mcodeptr++) = (u1) 0xdc;
6142 i386_emit_membase((basereg),(disp),4);
6146 void i386_fmul_reg_st(s4 reg) {
6147 *(mcodeptr++) = (u1) 0xd8;
6148 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6152 void i386_fmul_st_reg(s4 reg) {
6153 *(mcodeptr++) = (u1) 0xdc;
6154 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6159 *(mcodeptr++) = (u1) 0xde;
6160 *(mcodeptr++) = (u1) 0xc9;
6164 void i386_fmulp_st_reg(s4 reg) {
6165 *(mcodeptr++) = (u1) 0xde;
6166 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6170 void i386_fmuls_membase(s4 basereg, s4 disp) {
6171 *(mcodeptr++) = (u1) 0xd8;
6172 i386_emit_membase((basereg),(disp),1);
6176 void i386_fmull_membase(s4 basereg, s4 disp) {
6177 *(mcodeptr++) = (u1) 0xdc;
6178 i386_emit_membase((basereg),(disp),1);
6182 void i386_fdiv_reg_st(s4 reg) {
6183 *(mcodeptr++) = (u1) 0xd8;
6184 *(mcodeptr++) = (u1) 0xf0 + (0x07 & (reg));
6188 void i386_fdiv_st_reg(s4 reg) {
6189 *(mcodeptr++) = (u1) 0xdc;
6190 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
6195 *(mcodeptr++) = (u1) 0xde;
6196 *(mcodeptr++) = (u1) 0xf9;
6200 void i386_fdivp_st_reg(s4 reg) {
6201 *(mcodeptr++) = (u1) 0xde;
6202 *(mcodeptr++) = (u1) 0xf8 + (0x07 & (reg));
6207 *(mcodeptr++) = (u1) 0xd9;
6208 *(mcodeptr++) = (u1) 0xc9;
6212 void i386_fxch_reg(s4 reg) {
6213 *(mcodeptr++) = (u1) 0xd9;
6214 *(mcodeptr++) = (u1) 0xc8 + (0x07 & (reg));
6219 *(mcodeptr++) = (u1) 0xd9;
6220 *(mcodeptr++) = (u1) 0xf8;
6224 void i386_fprem1() {
6225 *(mcodeptr++) = (u1) 0xd9;
6226 *(mcodeptr++) = (u1) 0xf5;
6231 *(mcodeptr++) = (u1) 0xdd;
6232 *(mcodeptr++) = (u1) 0xe1;
6236 void i386_fucom_reg(s4 reg) {
6237 *(mcodeptr++) = (u1) 0xdd;
6238 *(mcodeptr++) = (u1) 0xe0 + (0x07 & (reg));
6242 void i386_fucomp_reg(s4 reg) {
6243 *(mcodeptr++) = (u1) 0xdd;
6244 *(mcodeptr++) = (u1) 0xe8 + (0x07 & (reg));
6248 void i386_fucompp() {
6249 *(mcodeptr++) = (u1) 0xda;
6250 *(mcodeptr++) = (u1) 0xe9;
6254 void i386_fnstsw() {
6255 *(mcodeptr++) = (u1) 0xdf;
6256 *(mcodeptr++) = (u1) 0xe0;
6261 *(mcodeptr++) = (u1) 0x9e;
6266 *(mcodeptr++) = (u1) 0x9b;
6267 *(mcodeptr++) = (u1) 0xdb;
6268 *(mcodeptr++) = (u1) 0xe3;
6272 void i386_fldcw_mem(s4 mem) {
6273 *(mcodeptr++) = (u1) 0xd9;
6274 i386_emit_mem(5,(mem));
6278 void i386_fldcw_membase(s4 basereg, s4 disp) {
6279 *(mcodeptr++) = (u1) 0xd9;
6280 i386_emit_membase((basereg),(disp),5);
6285 *(mcodeptr++) = (u1) 0x9b;
6289 void i386_ffree_reg(s4 reg) {
6290 *(mcodeptr++) = (u1) 0xdd;
6291 *(mcodeptr++) = (u1) 0xc0 + (0x07 & (reg));
6295 void i386_fdecstp() {
6296 *(mcodeptr++) = (u1) 0xd9;
6297 *(mcodeptr++) = (u1) 0xf6;
6301 void i386_fincstp() {
6302 *(mcodeptr++) = (u1) 0xd9;
6303 *(mcodeptr++) = (u1) 0xf7;
6308 * These are local overrides for various environment variables in Emacs.
6309 * Please do not remove this and leave it at the end of the file, where
6310 * Emacs will automagically detect them.
6311 * ---------------------------------------------------------------------
6314 * indent-tabs-mode: t