1 /* vm/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 Changes: Joseph Wenninger
33 $Id: codegen.c 1715 2004-12-06 16:23:55Z twisti $
43 #include <machine/signal.h>
47 #include "native/jni.h"
48 #include "native/native.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/loader.h"
53 #include "vm/tables.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/jit.h"
56 #include "vm/jit/parse.h"
57 #include "vm/jit/reg.h"
58 #include "vm/jit/i386/codegen.h"
59 #include "vm/jit/i386/emitfuncs.h"
60 #include "vm/jit/i386/types.h"
61 #include "vm/jit/i386/asmoffsets.h"
64 /* register descripton - array ************************************************/
66 /* #define REG_RES 0 reserved register for OS or code generator */
67 /* #define REG_RET 1 return value register */
68 /* #define REG_EXC 2 exception value register (only old jit) */
69 /* #define REG_SAV 3 (callee) saved register */
70 /* #define REG_TMP 4 scratch temporary register (caller saved) */
71 /* #define REG_ARG 5 argument register (caller saved) */
73 /* #define REG_END -1 last entry in tables */
75 static int nregdescint[] = {
76 REG_RET, REG_RES, REG_RES, REG_TMP, REG_RES, REG_SAV, REG_SAV, REG_SAV,
81 static int nregdescfloat[] = {
82 /* rounding problems with callee saved registers */
83 /* REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
84 /* REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
85 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
90 /*******************************************************************************
92 include independent code generation stuff -- include after register
93 descriptions to avoid extern definitions
95 *******************************************************************************/
97 #include "vm/jit/codegen.inc"
98 #include "vm/jit/reg.inc"
100 #include "vm/jit/lsra.inc"
103 void codegen_stubcalled() {
104 log_text("Stub has been called");
107 void codegen_general_stubcalled() {
108 log_text("general exception stub has been called");
112 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
113 void thread_restartcriticalsection(ucontext_t *uc)
117 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.mc_eip)) != NULL)
118 uc->uc_mcontext.mc_eip = (u4) critical;
120 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[REG_EIP])) != NULL)
121 uc->uc_mcontext.gregs[REG_EIP] = (u4) critical;
129 /* NullPointerException signal handler for hardware null pointer check */
131 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
134 /* long faultaddr; */
137 ucontext_t *_uc = (ucontext_t *) _p;
138 mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
140 struct ucontext *_uc = (struct ucontext *) _p;
141 struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
143 struct sigaction act;
145 /* Reset signal handler - necessary for SysV, does no harm for BSD */
147 /* instr = *((int*)(sigctx->eip)); */
148 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
150 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip);*/
152 /* if (faultaddr == 0) { */
153 /* signal(sig, (void *) catch_NullPointerException); */
154 act.sa_sigaction = (functionptr) catch_NullPointerException;
155 act.sa_flags = SA_SIGINFO;
156 sigaction(sig, &act, NULL); /* reinstall handler */
159 sigaddset(&nsig, sig);
160 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
163 sigctx->mc_ecx = sigctx->mc_eip; /* REG_ITMP2_XPC*/
164 sigctx->mc_eax = (u4) string_java_lang_NullPointerException;
165 sigctx->mc_eip = (u4) asm_throw_and_handle_exception;
167 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
168 sigctx->eax = (u4) string_java_lang_NullPointerException;
169 sigctx->eip = (u4) asm_throw_and_handle_exception;
174 /* faultaddr += (long) ((instr << 16) >> 16); */
175 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
176 /* panic("Stack overflow"); */
181 /* ArithmeticException signal handler for hardware divide by zero check */
183 void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
187 /* void **_p = (void **) &sig; */
188 /* struct sigcontext *sigctx = (struct sigcontext *) ++_p; */
191 ucontext_t *_uc = (ucontext_t *) _p;
192 mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
194 struct ucontext *_uc = (struct ucontext *) _p;
195 struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
198 struct sigaction act;
200 /* Reset signal handler - necessary for SysV, does no harm for BSD */
202 /* signal(sig, (void *) catch_ArithmeticException); */
203 act.sa_sigaction = (functionptr) catch_ArithmeticException;
204 act.sa_flags = SA_SIGINFO;
205 sigaction(sig, &act, NULL); /* reinstall handler */
208 sigaddset(&nsig, sig);
209 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
212 sigctx->mc_ecx = sigctx->mc_eip; /* REG_ITMP2_XPC */
213 sigctx->mc_eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
215 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
216 sigctx->eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
222 void init_exceptions(void)
224 struct sigaction act;
226 /* install signal handlers we need to convert to exceptions */
227 sigemptyset(&act.sa_mask);
231 /* signal(SIGSEGV, (void *) catch_NullPointerException); */
232 act.sa_sigaction = (functionptr) catch_NullPointerException;
233 act.sa_flags = SA_SIGINFO;
234 sigaction(SIGSEGV, &act, NULL);
238 /* signal(SIGBUS, (void *) catch_NullPointerException); */
239 act.sa_sigaction = (functionptr) catch_NullPointerException;
240 act.sa_flags = SA_SIGINFO;
241 sigaction(SIGBUS, &act, NULL);
245 /* signal(SIGFPE, (void *) catch_ArithmeticException); */
246 act.sa_sigaction = (functionptr) catch_ArithmeticException;
247 act.sa_flags = SA_SIGINFO;
248 sigaction(SIGFPE, &act, NULL);
252 /* function codegen ************************************************************
254 generates machine code
256 *******************************************************************************/
258 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
260 s4 len, s1, s2, s3, d;
268 s4 fpu_st_offset = 0;
274 s4 savedregs_num = 0;
276 /* space to save used callee saved registers */
278 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
279 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
281 parentargs_base = rd->maxmemuse + savedregs_num;
284 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
286 if (checksync && (m->flags & ACC_SYNCHRONIZED))
291 /* create method header */
293 (void) dseg_addaddress(cd, m); /* MethodPointer */
294 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
296 #if defined(USE_THREADS)
298 /* IsSync contains the offset relative to the stack pointer for the
299 argument of monitor_exit used in the exception handler. Since the
300 offset could be zero and give a wrong meaning of the flag it is
304 if (checksync && (m->flags & ACC_SYNCHRONIZED))
305 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
310 (void) dseg_adds4(cd, 0); /* IsSync */
312 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
313 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse); /* IntSave */
314 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse); /* FltSave */
316 /* adds a reference for the length of the line number counter. We don't
317 know the size yet, since we evaluate the information during code
318 generation, to save one additional iteration over the whole
319 instructions. During code optimization the position could have changed
320 to the information gotten from the class file */
321 (void) dseg_addlinenumbertablesize(cd);
323 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
325 /* create exception table */
327 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
328 dseg_addtarget(cd, ex->start);
329 dseg_addtarget(cd, ex->end);
330 dseg_addtarget(cd, ex->handler);
331 (void) dseg_addaddress(cd, ex->catchtype);
335 /* initialize mcode variables */
337 cd->mcodeptr = cd->mcodebase;
338 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
339 MCODECHECK(128 + m->paramcount);
341 /* create stack frame (if necessary) */
343 if (parentargs_base) {
344 i386_alu_imm_reg(cd, I386_SUB, parentargs_base * 8, REG_SP);
347 /* save return address and used callee saved registers */
350 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
351 p--; i386_mov_reg_membase(cd, rd->savintregs[i], REG_SP, p * 8);
353 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
354 p--; i386_fld_reg(cd, rd->savfltregs[i]); i386_fstpl_membase(cd, REG_SP, p * 8);
357 /* save monitorenter argument */
359 #if defined(USE_THREADS)
360 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
361 s4 func_enter = (m->flags & ACC_STATIC) ?
362 (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
364 if (m->flags & ACC_STATIC) {
365 i386_mov_imm_reg(cd, (s4) m->class, REG_ITMP1);
366 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
369 i386_mov_membase_reg(cd, REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
370 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
373 /* call monitorenter function */
375 i386_alu_imm_reg(cd, I386_SUB, 4, REG_SP);
376 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0);
377 i386_mov_imm_reg(cd, func_enter, REG_ITMP1);
378 i386_call_reg(cd, REG_ITMP1);
379 i386_alu_imm_reg(cd, I386_ADD, 4, REG_SP);
383 /* copy argument registers to stack and call trace function with pointer
384 to arguments on stack.
388 i386_alu_imm_reg(cd, I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
390 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
391 t = m->paramtypes[p];
393 if (IS_INT_LNG_TYPE(t)) {
394 if (IS_2_WORD_TYPE(t)) {
395 i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
396 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
397 i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP1);
398 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
400 /* } else if (t == TYPE_ADR) { */
402 i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
403 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
404 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
405 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
408 /* i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX); */
410 /* i386_mov_reg_membase(cd, EAX, REG_SP, p * 8); */
411 /* i386_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4); */
415 if (!IS_2_WORD_TYPE(t)) {
416 i386_flds_membase(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
417 i386_fstps_membase(cd, REG_SP, p * 8);
418 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
419 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
422 i386_fldl_membase(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
423 i386_fstpl_membase(cd, REG_SP, p * 8);
428 /* fill up the remaining arguments */
429 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
430 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
431 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
432 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
435 i386_mov_imm_membase(cd, (s4) m, REG_SP, TRACE_ARGS_NUM * 8);
436 i386_mov_imm_reg(cd, (s4) builtin_trace_args, REG_ITMP1);
437 i386_call_reg(cd, REG_ITMP1);
439 i386_alu_imm_reg(cd, I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
442 /* take arguments out of register or stack frame */
444 for (p = 0, l = 0; p < m->paramcount; p++) {
445 t = m->paramtypes[p];
446 var = &(rd->locals[l][t]);
448 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
452 if (IS_INT_LNG_TYPE(t)) { /* integer args */
453 if (p < rd->intreg_argnum) { /* register arguments */
454 panic("integer register argument");
455 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
456 /* M_INTMOVE (argintregs[p], r); */
458 } else { /* reg arg -> spilled */
459 /* M_LST (argintregs[p], REG_SP, 8 * r); */
461 } else { /* stack arguments */
462 pa = p - rd->intreg_argnum;
463 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
464 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, var->regoff); /* + 4 for return address */
465 } else { /* stack arg -> spilled */
466 if (!IS_2_WORD_TYPE(t)) {
467 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
468 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
471 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
472 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
473 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP1); /* + 4 for return address */
474 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8 + 4);
479 } else { /* floating args */
480 if (p < rd->fltreg_argnum) { /* register arguments */
481 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
482 panic("There are no float argument registers!");
484 } else { /* reg arg -> spilled */
485 panic("There are no float argument registers!");
488 } else { /* stack arguments */
489 pa = p - rd->fltreg_argnum;
490 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
492 i386_flds_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
494 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
498 i386_fldl_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
500 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
504 } else { /* stack-arg -> spilled */
505 /* i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
506 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, r * 8); */
508 i386_flds_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
509 i386_fstps_membase(cd, REG_SP, var->regoff * 8);
512 i386_fldl_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
513 i386_fstpl_membase(cd, REG_SP, var->regoff * 8);
522 /* end of header generation */
524 /* walk through all basic blocks */
525 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
527 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
529 if (bptr->flags >= BBREACHED) {
531 /* branch resolving */
534 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
535 gen_resolvebranch(cd->mcodebase + brefs->branchpos,
540 /* copy interface registers to their destination */
548 while (src != NULL) {
550 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
551 if (!IS_2_WORD_TYPE(src->type)) {
552 if (bptr->type == BBTYPE_SBR) {
553 /* d = reg_of_var(m, src, REG_ITMP1); */
554 if (!(src->flags & INMEMORY))
559 store_reg_to_var_int(src, d);
560 } else if (bptr->type == BBTYPE_EXH) {
561 /* d = reg_of_var(m, src, REG_ITMP1); */
562 if (!(src->flags & INMEMORY))
566 M_INTMOVE(REG_ITMP1, d);
567 store_reg_to_var_int(src, d);
571 panic("copy interface registers(EXH, SBR): longs have to me in memory (begin 1)");
578 while (src != NULL) {
580 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
581 if (!IS_2_WORD_TYPE(src->type)) {
582 if (bptr->type == BBTYPE_SBR) {
583 d = reg_of_var(rd, src, REG_ITMP1);
585 store_reg_to_var_int(src, d);
586 } else if (bptr->type == BBTYPE_EXH) {
587 d = reg_of_var(rd, src, REG_ITMP1);
588 M_INTMOVE(REG_ITMP1, d);
589 store_reg_to_var_int(src, d);
593 panic("copy interface registers: longs have to me in memory (begin 1)");
597 d = reg_of_var(rd, src, REG_ITMP1);
598 if ((src->varkind != STACKVAR)) {
600 if (IS_FLT_DBL_TYPE(s2)) {
601 s1 = rd->interfaces[len][s2].regoff;
602 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
606 if (s2 == TYPE_FLT) {
607 i386_flds_membase(cd, REG_SP, s1 * 8);
610 i386_fldl_membase(cd, REG_SP, s1 * 8);
613 store_reg_to_var_flt(src, d);
616 s1 = rd->interfaces[len][s2].regoff;
617 if (!IS_2_WORD_TYPE(rd->interfaces[len][s2].type)) {
618 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
622 i386_mov_membase_reg(cd, REG_SP, s1 * 8, d);
624 store_reg_to_var_int(src, d);
627 if (rd->interfaces[len][s2].flags & INMEMORY) {
628 M_LNGMEMMOVE(s1, src->regoff);
631 panic("copy interface registers: longs have to be in memory (begin 2)");
643 /* walk through all instructions */
648 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
649 if (iptr->line != currentline) {
650 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
651 currentline = iptr->line;
654 MCODECHECK(64); /* an instruction usually needs < 64 words */
657 case ICMD_NOP: /* ... ==> ... */
660 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
661 if (src->flags & INMEMORY) {
662 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
665 i386_test_reg_reg(cd, src->regoff, src->regoff);
667 i386_jcc(cd, I386_CC_E, 0);
668 codegen_addxnullrefs(cd, cd->mcodeptr);
671 /* constant operations ************************************************/
673 case ICMD_ICONST: /* ... ==> ..., constant */
674 /* op1 = 0, val.i = constant */
676 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
677 if (iptr->dst->flags & INMEMORY) {
678 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
681 if (iptr->val.i == 0) {
682 i386_alu_reg_reg(cd, I386_XOR, d, d);
685 i386_mov_imm_reg(cd, iptr->val.i, d);
690 case ICMD_LCONST: /* ... ==> ..., constant */
691 /* op1 = 0, val.l = constant */
693 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
694 if (iptr->dst->flags & INMEMORY) {
695 i386_mov_imm_membase(cd, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
696 i386_mov_imm_membase(cd, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
699 panic("LCONST: longs have to be in memory");
703 case ICMD_FCONST: /* ... ==> ..., constant */
704 /* op1 = 0, val.f = constant */
706 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
707 if (iptr->val.f == 0.0) {
712 if (iptr->val.i == 0x80000000) {
716 } else if (iptr->val.f == 1.0) {
720 } else if (iptr->val.f == 2.0) {
727 a = dseg_addfloat(cd, iptr->val.f);
728 i386_mov_imm_reg(cd, 0, REG_ITMP1);
729 dseg_adddata(cd, cd->mcodeptr);
730 i386_flds_membase(cd, REG_ITMP1, a);
733 store_reg_to_var_flt(iptr->dst, d);
736 case ICMD_DCONST: /* ... ==> ..., constant */
737 /* op1 = 0, val.d = constant */
739 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
740 if (iptr->val.d == 0.0) {
745 if (iptr->val.l == 0x8000000000000000LL) {
749 } else if (iptr->val.d == 1.0) {
753 } else if (iptr->val.d == 2.0) {
760 a = dseg_adddouble(cd, iptr->val.d);
761 i386_mov_imm_reg(cd, 0, REG_ITMP1);
762 dseg_adddata(cd, cd->mcodeptr);
763 i386_fldl_membase(cd, REG_ITMP1, a);
766 store_reg_to_var_flt(iptr->dst, d);
769 case ICMD_ACONST: /* ... ==> ..., constant */
770 /* op1 = 0, val.a = constant */
772 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
773 if (iptr->dst->flags & INMEMORY) {
774 i386_mov_imm_membase(cd, (s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
777 if ((s4) iptr->val.a == 0) {
778 i386_alu_reg_reg(cd, I386_XOR, d, d);
781 i386_mov_imm_reg(cd, (s4) iptr->val.a, d);
787 /* load/store operations **********************************************/
789 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
790 case ICMD_ALOAD: /* op1 = local variable */
792 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
793 if ((iptr->dst->varkind == LOCALVAR) &&
794 (iptr->dst->varnum == iptr->op1)) {
797 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
798 if (iptr->dst->flags & INMEMORY) {
799 if (var->flags & INMEMORY) {
800 i386_mov_membase_reg(cd, REG_SP, var->regoff * 8, REG_ITMP1);
801 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
804 i386_mov_reg_membase(cd, var->regoff, REG_SP, iptr->dst->regoff * 8);
808 if (var->flags & INMEMORY) {
809 i386_mov_membase_reg(cd, REG_SP, var->regoff * 8, iptr->dst->regoff);
812 M_INTMOVE(var->regoff, iptr->dst->regoff);
817 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
818 /* op1 = local variable */
820 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
821 if ((iptr->dst->varkind == LOCALVAR) &&
822 (iptr->dst->varnum == iptr->op1)) {
825 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
826 if (iptr->dst->flags & INMEMORY) {
827 if (var->flags & INMEMORY) {
828 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
831 panic("LLOAD: longs have to be in memory");
835 panic("LLOAD: longs have to be in memory");
839 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
840 /* op1 = local variable */
842 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
843 if ((iptr->dst->varkind == LOCALVAR) &&
844 (iptr->dst->varnum == iptr->op1)) {
847 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
848 if (var->flags & INMEMORY) {
849 i386_flds_membase(cd, REG_SP, var->regoff * 8);
852 i386_fld_reg(cd, var->regoff + fpu_st_offset);
855 store_reg_to_var_flt(iptr->dst, d);
858 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
859 /* op1 = local variable */
861 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
862 if ((iptr->dst->varkind == LOCALVAR) &&
863 (iptr->dst->varnum == iptr->op1)) {
866 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
867 if (var->flags & INMEMORY) {
868 i386_fldl_membase(cd, REG_SP, var->regoff * 8);
871 i386_fld_reg(cd, var->regoff + fpu_st_offset);
874 store_reg_to_var_flt(iptr->dst, d);
877 case ICMD_ISTORE: /* ..., value ==> ... */
878 case ICMD_ASTORE: /* op1 = local variable */
880 if ((src->varkind == LOCALVAR) &&
881 (src->varnum == iptr->op1)) {
884 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
885 if (var->flags & INMEMORY) {
886 if (src->flags & INMEMORY) {
887 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
888 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
891 i386_mov_reg_membase(cd, src->regoff, REG_SP, var->regoff * 8);
895 var_to_reg_int(s1, src, var->regoff);
896 M_INTMOVE(s1, var->regoff);
900 case ICMD_LSTORE: /* ..., value ==> ... */
901 /* op1 = local variable */
903 if ((src->varkind == LOCALVAR) &&
904 (src->varnum == iptr->op1)) {
907 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
908 if (var->flags & INMEMORY) {
909 if (src->flags & INMEMORY) {
910 M_LNGMEMMOVE(src->regoff, var->regoff);
913 panic("LSTORE: longs have to be in memory");
917 panic("LSTORE: longs have to be in memory");
921 case ICMD_FSTORE: /* ..., value ==> ... */
922 /* op1 = local variable */
924 if ((src->varkind == LOCALVAR) &&
925 (src->varnum == iptr->op1)) {
928 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
929 if (var->flags & INMEMORY) {
930 var_to_reg_flt(s1, src, REG_FTMP1);
931 i386_fstps_membase(cd, REG_SP, var->regoff * 8);
934 var_to_reg_flt(s1, src, var->regoff);
935 /* M_FLTMOVE(s1, var->regoff); */
936 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
941 case ICMD_DSTORE: /* ..., value ==> ... */
942 /* op1 = local variable */
944 if ((src->varkind == LOCALVAR) &&
945 (src->varnum == iptr->op1)) {
948 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
949 if (var->flags & INMEMORY) {
950 var_to_reg_flt(s1, src, REG_FTMP1);
951 i386_fstpl_membase(cd, REG_SP, var->regoff * 8);
954 var_to_reg_flt(s1, src, var->regoff);
955 /* M_FLTMOVE(s1, var->regoff); */
956 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
962 /* pop/dup/swap operations ********************************************/
964 /* attention: double and longs are only one entry in CACAO ICMDs */
966 case ICMD_POP: /* ..., value ==> ... */
967 case ICMD_POP2: /* ..., value, value ==> ... */
970 case ICMD_DUP: /* ..., a ==> ..., a, a */
971 M_COPY(src, iptr->dst);
974 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
976 M_COPY(src, iptr->dst);
977 M_COPY(src->prev, iptr->dst->prev);
980 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
982 M_COPY(src, iptr->dst);
983 M_COPY(src->prev, iptr->dst->prev);
984 M_COPY(iptr->dst, iptr->dst->prev->prev);
987 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
989 M_COPY(src, iptr->dst);
990 M_COPY(src->prev, iptr->dst->prev);
991 M_COPY(src->prev->prev, iptr->dst->prev->prev);
992 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
995 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
997 M_COPY(src, iptr->dst);
998 M_COPY(src->prev, iptr->dst->prev);
999 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1000 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
1001 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev);
1004 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1006 M_COPY(src, iptr->dst);
1007 M_COPY(src->prev, iptr->dst->prev);
1008 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1009 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1010 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
1011 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
1014 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1016 M_COPY(src, iptr->dst->prev);
1017 M_COPY(src->prev, iptr->dst);
1021 /* integer operations *************************************************/
1023 case ICMD_INEG: /* ..., value ==> ..., - value */
1025 d = reg_of_var(rd, iptr->dst, REG_NULL);
1026 if (iptr->dst->flags & INMEMORY) {
1027 if (src->flags & INMEMORY) {
1028 if (src->regoff == iptr->dst->regoff) {
1029 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1032 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1033 i386_neg_reg(cd, REG_ITMP1);
1034 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1038 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1039 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1043 if (src->flags & INMEMORY) {
1044 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1045 i386_neg_reg(cd, iptr->dst->regoff);
1048 M_INTMOVE(src->regoff, iptr->dst->regoff);
1049 i386_neg_reg(cd, iptr->dst->regoff);
1054 case ICMD_LNEG: /* ..., value ==> ..., - value */
1056 d = reg_of_var(rd, iptr->dst, REG_NULL);
1057 if (iptr->dst->flags & INMEMORY) {
1058 if (src->flags & INMEMORY) {
1059 if (src->regoff == iptr->dst->regoff) {
1060 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1061 i386_alu_imm_membase(cd, I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1062 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8 + 4);
1065 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1066 i386_neg_reg(cd, REG_ITMP1);
1067 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1068 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1069 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP1);
1070 i386_neg_reg(cd, REG_ITMP1);
1071 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1077 case ICMD_I2L: /* ..., value ==> ..., value */
1079 d = reg_of_var(rd, iptr->dst, REG_NULL);
1080 if (iptr->dst->flags & INMEMORY) {
1081 if (src->flags & INMEMORY) {
1082 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, EAX);
1084 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1085 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1088 M_INTMOVE(src->regoff, EAX);
1090 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1091 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1096 case ICMD_L2I: /* ..., value ==> ..., value */
1098 d = reg_of_var(rd, iptr->dst, REG_NULL);
1099 if (iptr->dst->flags & INMEMORY) {
1100 if (src->flags & INMEMORY) {
1101 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1102 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1106 if (src->flags & INMEMORY) {
1107 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1112 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1114 d = reg_of_var(rd, iptr->dst, REG_NULL);
1115 if (iptr->dst->flags & INMEMORY) {
1116 if (src->flags & INMEMORY) {
1117 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1118 i386_shift_imm_reg(cd, I386_SHL, 24, REG_ITMP1);
1119 i386_shift_imm_reg(cd, I386_SAR, 24, REG_ITMP1);
1120 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1123 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1124 i386_shift_imm_membase(cd, I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1125 i386_shift_imm_membase(cd, I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1129 if (src->flags & INMEMORY) {
1130 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1131 i386_shift_imm_reg(cd, I386_SHL, 24, iptr->dst->regoff);
1132 i386_shift_imm_reg(cd, I386_SAR, 24, iptr->dst->regoff);
1135 M_INTMOVE(src->regoff, iptr->dst->regoff);
1136 i386_shift_imm_reg(cd, I386_SHL, 24, iptr->dst->regoff);
1137 i386_shift_imm_reg(cd, I386_SAR, 24, iptr->dst->regoff);
1142 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1144 d = reg_of_var(rd, iptr->dst, REG_NULL);
1145 if (iptr->dst->flags & INMEMORY) {
1146 if (src->flags & INMEMORY) {
1147 if (src->regoff == iptr->dst->regoff) {
1148 i386_alu_imm_membase(cd, I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1151 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1152 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, REG_ITMP1);
1153 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1157 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1158 i386_alu_imm_membase(cd, I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1162 if (src->flags & INMEMORY) {
1163 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1164 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, iptr->dst->regoff);
1167 M_INTMOVE(src->regoff, iptr->dst->regoff);
1168 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, iptr->dst->regoff);
1173 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1175 d = reg_of_var(rd, iptr->dst, REG_NULL);
1176 if (iptr->dst->flags & INMEMORY) {
1177 if (src->flags & INMEMORY) {
1178 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1179 i386_shift_imm_reg(cd, I386_SHL, 16, REG_ITMP1);
1180 i386_shift_imm_reg(cd, I386_SAR, 16, REG_ITMP1);
1181 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1184 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1185 i386_shift_imm_membase(cd, I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1186 i386_shift_imm_membase(cd, I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1190 if (src->flags & INMEMORY) {
1191 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1192 i386_shift_imm_reg(cd, I386_SHL, 16, iptr->dst->regoff);
1193 i386_shift_imm_reg(cd, I386_SAR, 16, iptr->dst->regoff);
1196 M_INTMOVE(src->regoff, iptr->dst->regoff);
1197 i386_shift_imm_reg(cd, I386_SHL, 16, iptr->dst->regoff);
1198 i386_shift_imm_reg(cd, I386_SAR, 16, iptr->dst->regoff);
1204 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1206 d = reg_of_var(rd, iptr->dst, REG_NULL);
1207 i386_emit_ialu(cd, I386_ADD, src, iptr);
1210 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1211 /* val.i = constant */
1213 d = reg_of_var(rd, iptr->dst, REG_NULL);
1214 i386_emit_ialuconst(cd, I386_ADD, src, iptr);
1217 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1219 d = reg_of_var(rd, iptr->dst, REG_NULL);
1220 if (iptr->dst->flags & INMEMORY) {
1221 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1222 if (src->regoff == iptr->dst->regoff) {
1223 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1224 i386_alu_reg_membase(cd, I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1225 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1226 i386_alu_reg_membase(cd, I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1228 } else if (src->prev->regoff == iptr->dst->regoff) {
1229 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1230 i386_alu_reg_membase(cd, I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1231 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1232 i386_alu_reg_membase(cd, I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1235 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1236 i386_alu_membase_reg(cd, I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1237 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1238 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1239 i386_alu_membase_reg(cd, I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1240 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1247 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1248 /* val.l = constant */
1250 d = reg_of_var(rd, iptr->dst, REG_NULL);
1251 if (iptr->dst->flags & INMEMORY) {
1252 if (src->flags & INMEMORY) {
1253 if (src->regoff == iptr->dst->regoff) {
1254 i386_alu_imm_membase(cd, I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1255 i386_alu_imm_membase(cd, I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1258 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1259 i386_alu_imm_reg(cd, I386_ADD, iptr->val.l, REG_ITMP1);
1260 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1261 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1262 i386_alu_imm_reg(cd, I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1263 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1269 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1271 d = reg_of_var(rd, iptr->dst, REG_NULL);
1272 if (iptr->dst->flags & INMEMORY) {
1273 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1274 if (src->prev->regoff == iptr->dst->regoff) {
1275 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1276 i386_alu_reg_membase(cd, I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1279 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1280 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1281 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1284 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1285 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1286 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1287 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1289 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1290 if (src->prev->regoff == iptr->dst->regoff) {
1291 i386_alu_reg_membase(cd, I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1294 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1295 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1296 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1300 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1301 i386_alu_reg_membase(cd, I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1305 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1306 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, d);
1307 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, d);
1309 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1310 M_INTMOVE(src->prev->regoff, d);
1311 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, d);
1313 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1314 /* workaround for reg alloc */
1315 if (src->regoff == iptr->dst->regoff) {
1316 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1317 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1318 M_INTMOVE(REG_ITMP1, d);
1321 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, d);
1322 i386_alu_reg_reg(cd, I386_SUB, src->regoff, d);
1326 /* workaround for reg alloc */
1327 if (src->regoff == iptr->dst->regoff) {
1328 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1329 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1330 M_INTMOVE(REG_ITMP1, d);
1333 M_INTMOVE(src->prev->regoff, d);
1334 i386_alu_reg_reg(cd, I386_SUB, src->regoff, d);
1340 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1341 /* val.i = constant */
1343 d = reg_of_var(rd, iptr->dst, REG_NULL);
1344 i386_emit_ialuconst(cd, I386_SUB, src, iptr);
1347 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1349 d = reg_of_var(rd, iptr->dst, REG_NULL);
1350 if (iptr->dst->flags & INMEMORY) {
1351 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1352 if (src->prev->regoff == iptr->dst->regoff) {
1353 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1354 i386_alu_reg_membase(cd, I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1355 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1356 i386_alu_reg_membase(cd, I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1359 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1360 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1361 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1362 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1363 i386_alu_membase_reg(cd, I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1364 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1370 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1371 /* val.l = constant */
1373 d = reg_of_var(rd, iptr->dst, REG_NULL);
1374 if (iptr->dst->flags & INMEMORY) {
1375 if (src->flags & INMEMORY) {
1376 if (src->regoff == iptr->dst->regoff) {
1377 i386_alu_imm_membase(cd, I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1378 i386_alu_imm_membase(cd, I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1381 /* TODO: could be size optimized with lea -- see gcc output */
1382 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1383 i386_alu_imm_reg(cd, I386_SUB, iptr->val.l, REG_ITMP1);
1384 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1385 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1386 i386_alu_imm_reg(cd, I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1387 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1393 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1395 d = reg_of_var(rd, iptr->dst, REG_NULL);
1396 if (iptr->dst->flags & INMEMORY) {
1397 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1398 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1399 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1400 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1402 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1403 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1404 i386_imul_reg_reg(cd, src->prev->regoff, REG_ITMP1);
1405 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1407 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1408 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1409 i386_imul_reg_reg(cd, src->regoff, REG_ITMP1);
1410 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1413 i386_mov_reg_reg(cd, src->prev->regoff, REG_ITMP1);
1414 i386_imul_reg_reg(cd, src->regoff, REG_ITMP1);
1415 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1419 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1420 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1421 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1423 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1424 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1425 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1427 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1428 M_INTMOVE(src->regoff, iptr->dst->regoff);
1429 i386_imul_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1432 if (src->regoff == iptr->dst->regoff) {
1433 i386_imul_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
1436 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1437 i386_imul_reg_reg(cd, src->regoff, iptr->dst->regoff);
1443 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1444 /* val.i = constant */
1446 d = reg_of_var(rd, iptr->dst, REG_NULL);
1447 if (iptr->dst->flags & INMEMORY) {
1448 if (src->flags & INMEMORY) {
1449 i386_imul_imm_membase_reg(cd, iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1450 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1453 i386_imul_imm_reg_reg(cd, iptr->val.i, src->regoff, REG_ITMP1);
1454 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1458 if (src->flags & INMEMORY) {
1459 i386_imul_imm_membase_reg(cd, iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1462 i386_imul_imm_reg_reg(cd, iptr->val.i, src->regoff, iptr->dst->regoff);
1467 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1469 d = reg_of_var(rd, iptr->dst, REG_NULL);
1470 if (iptr->dst->flags & INMEMORY) {
1471 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1472 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX); /* mem -> EAX */
1473 /* optimize move EAX -> REG_ITMP3 is slower??? */
1474 /* i386_mov_reg_reg(cd, EAX, REG_ITMP3); */
1475 i386_mul_membase(cd, REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1477 /* TODO: optimize move EAX -> REG_ITMP3 */
1478 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem -> ITMP3 */
1479 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1480 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1482 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP2); /* mem -> ITMP3 */
1483 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1485 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1486 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1487 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1492 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1493 /* val.l = constant */
1495 d = reg_of_var(rd, iptr->dst, REG_NULL);
1496 if (iptr->dst->flags & INMEMORY) {
1497 if (src->flags & INMEMORY) {
1498 i386_mov_imm_reg(cd, iptr->val.l, EAX); /* imm -> EAX */
1499 i386_mul_membase(cd, REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1500 /* TODO: optimize move EAX -> REG_ITMP3 */
1501 i386_mov_imm_reg(cd, iptr->val.l >> 32, REG_ITMP2); /* imm -> ITMP3 */
1502 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1504 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1505 i386_mov_imm_reg(cd, iptr->val.l, REG_ITMP2); /* imm -> ITMP3 */
1506 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1508 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1509 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1510 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1515 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1517 d = reg_of_var(rd, iptr->dst, REG_NULL);
1518 var_to_reg_int(s1, src, REG_ITMP2);
1520 if (src->prev->flags & INMEMORY) {
1521 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);
1524 M_INTMOVE(src->prev->regoff, EAX);
1527 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1528 i386_jcc(cd, I386_CC_NE, 3 + 6);
1529 i386_alu_imm_reg(cd, I386_CMP, -1, s1);
1530 i386_jcc(cd, I386_CC_E, 1 + 2);
1533 i386_idiv_reg(cd, s1);
1535 if (iptr->dst->flags & INMEMORY) {
1536 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1539 M_INTMOVE(EAX, iptr->dst->regoff);
1543 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1545 d = reg_of_var(rd, iptr->dst, REG_NULL);
1546 var_to_reg_int(s1, src, REG_ITMP2);
1548 if (src->prev->flags & INMEMORY) {
1549 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);
1552 M_INTMOVE(src->prev->regoff, EAX);
1555 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1556 i386_jcc(cd, I386_CC_NE, 2 + 3 + 6);
1557 i386_alu_reg_reg(cd, I386_XOR, EDX, EDX);
1558 i386_alu_imm_reg(cd, I386_CMP, -1, s1);
1559 i386_jcc(cd, I386_CC_E, 1 + 2);
1562 i386_idiv_reg(cd, s1);
1564 if (iptr->dst->flags & INMEMORY) {
1565 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8);
1568 M_INTMOVE(EDX, iptr->dst->regoff);
1572 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1573 /* val.i = constant */
1575 /* TODO: optimize for `/ 2' */
1576 var_to_reg_int(s1, src, REG_ITMP1);
1577 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1580 i386_test_reg_reg(cd, d, d);
1582 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1583 i386_jcc(cd, I386_CC_NS, a);
1584 i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.i) - 1, d);
1586 i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, d);
1587 store_reg_to_var_int(iptr->dst, d);
1590 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1591 /* val.i = constant */
1593 d = reg_of_var(rd, iptr->dst, REG_NULL);
1594 if (iptr->dst->flags & INMEMORY) {
1595 if (src->flags & INMEMORY) {
1597 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1599 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1600 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1602 i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
1603 i386_jcc(cd, I386_CC_NS, a);
1604 i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1605 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1606 i386_shrd_imm_reg_reg(cd, iptr->val.i, REG_ITMP2, REG_ITMP1);
1607 i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, REG_ITMP2);
1609 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1610 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1615 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1616 /* val.i = constant */
1618 var_to_reg_int(s1, src, REG_ITMP1);
1619 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1621 M_INTMOVE(s1, REG_ITMP1);
1628 CALCIMMEDIATEBYTES(a, iptr->val.i);
1631 /* TODO: optimize */
1633 i386_alu_imm_reg(cd, I386_AND, iptr->val.i, d);
1634 i386_test_reg_reg(cd, s1, s1);
1635 i386_jcc(cd, I386_CC_GE, a);
1636 i386_mov_reg_reg(cd, s1, d);
1637 i386_neg_reg(cd, d);
1638 i386_alu_imm_reg(cd, I386_AND, iptr->val.i, d);
1639 i386_neg_reg(cd, d);
1641 /* M_INTMOVE(s1, EAX); */
1642 /* i386_cltd(cd); */
1643 /* i386_alu_reg_reg(cd, I386_XOR, EDX, EAX); */
1644 /* i386_alu_reg_reg(cd, I386_SUB, EDX, EAX); */
1645 /* i386_alu_reg_reg(cd, I386_AND, iptr->val.i, EAX); */
1646 /* i386_alu_reg_reg(cd, I386_XOR, EDX, EAX); */
1647 /* i386_alu_reg_reg(cd, I386_SUB, EDX, EAX); */
1648 /* M_INTMOVE(EAX, d); */
1650 /* i386_alu_reg_reg(cd, I386_XOR, d, d); */
1651 /* i386_mov_imm_reg(cd, iptr->val.i, ECX); */
1652 /* i386_shrd_reg_reg(cd, s1, d); */
1653 /* i386_shift_imm_reg(cd, I386_SHR, 32 - iptr->val.i, d); */
1655 store_reg_to_var_int(iptr->dst, d);
1658 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1659 /* val.l = constant */
1661 d = reg_of_var(rd, iptr->dst, REG_NULL);
1662 if (iptr->dst->flags & INMEMORY) {
1663 if (src->flags & INMEMORY) {
1664 /* Intel algorithm -- does not work, because constant is wrong */
1665 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1); */
1666 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1668 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1669 /* i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3); */
1670 /* i386_jcc(cd, I386_CC_NS, offset); */
1671 /* i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1672 /* i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP3); */
1674 /* i386_shrd_imm_reg_reg(cd, iptr->val.l, REG_ITMP3, REG_ITMP2); */
1675 /* i386_shift_imm_reg(cd, I386_SAR, iptr->val.l, REG_ITMP3); */
1676 /* i386_shld_imm_reg_reg(cd, iptr->val.l, REG_ITMP2, REG_ITMP3); */
1678 /* i386_shift_imm_reg(cd, I386_SHL, iptr->val.l, REG_ITMP2); */
1680 /* i386_alu_reg_reg(cd, I386_SUB, REG_ITMP2, REG_ITMP1); */
1681 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1682 /* i386_alu_reg_reg(cd, I386_SBB, REG_ITMP3, REG_ITMP2); */
1684 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1685 /* i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1687 /* Alpha algorithm */
1689 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1691 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1697 /* TODO: hmm, don't know if this is always correct */
1699 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1701 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1707 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1708 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1710 i386_alu_imm_reg(cd, I386_AND, iptr->val.l, REG_ITMP1);
1711 i386_alu_imm_reg(cd, I386_AND, iptr->val.l >> 32, REG_ITMP2);
1712 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1713 i386_jcc(cd, I386_CC_GE, a);
1715 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1716 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1718 i386_neg_reg(cd, REG_ITMP1);
1719 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1720 i386_neg_reg(cd, REG_ITMP2);
1722 i386_alu_imm_reg(cd, I386_AND, iptr->val.l, REG_ITMP1);
1723 i386_alu_imm_reg(cd, I386_AND, iptr->val.l >> 32, REG_ITMP2);
1725 i386_neg_reg(cd, REG_ITMP1);
1726 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1727 i386_neg_reg(cd, REG_ITMP2);
1729 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1730 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1735 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1737 d = reg_of_var(rd, iptr->dst, REG_NULL);
1738 i386_emit_ishift(cd, I386_SHL, src, iptr);
1741 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1742 /* val.i = constant */
1744 d = reg_of_var(rd, iptr->dst, REG_NULL);
1745 i386_emit_ishiftconst(cd, I386_SHL, src, iptr);
1748 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1750 d = reg_of_var(rd, iptr->dst, REG_NULL);
1751 i386_emit_ishift(cd, I386_SAR, src, iptr);
1754 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1755 /* val.i = constant */
1757 d = reg_of_var(rd, iptr->dst, REG_NULL);
1758 i386_emit_ishiftconst(cd, I386_SAR, src, iptr);
1761 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1763 d = reg_of_var(rd, iptr->dst, REG_NULL);
1764 i386_emit_ishift(cd, I386_SHR, src, iptr);
1767 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1768 /* val.i = constant */
1770 d = reg_of_var(rd, iptr->dst, REG_NULL);
1771 i386_emit_ishiftconst(cd, I386_SHR, src, iptr);
1774 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1776 d = reg_of_var(rd, iptr->dst, REG_NULL);
1777 if (iptr->dst->flags & INMEMORY ){
1778 if (src->prev->flags & INMEMORY) {
1779 /* if (src->prev->regoff == iptr->dst->regoff) { */
1780 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1782 /* if (src->flags & INMEMORY) { */
1783 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1785 /* M_INTMOVE(src->regoff, ECX); */
1788 /* i386_test_imm_reg(cd, 32, ECX); */
1789 /* i386_jcc(cd, I386_CC_E, 2 + 2); */
1790 /* i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP2); */
1791 /* i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1); */
1793 /* i386_shld_reg_membase(cd, REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1794 /* i386_shift_membase(cd, I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1797 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1798 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1800 if (src->flags & INMEMORY) {
1801 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1803 M_INTMOVE(src->regoff, ECX);
1806 i386_test_imm_reg(cd, 32, ECX);
1807 i386_jcc(cd, I386_CC_E, 2 + 2);
1808 i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP3);
1809 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
1811 i386_shld_reg_reg(cd, REG_ITMP1, REG_ITMP3);
1812 i386_shift_reg(cd, I386_SHL, REG_ITMP1);
1813 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1814 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1820 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1821 /* val.i = constant */
1823 d = reg_of_var(rd, iptr->dst, REG_NULL);
1824 if (iptr->dst->flags & INMEMORY ) {
1825 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1826 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1828 if (iptr->val.i & 0x20) {
1829 i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP2);
1830 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
1831 i386_shld_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1834 i386_shld_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1835 i386_shift_imm_reg(cd, I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
1838 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1839 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1843 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1845 d = reg_of_var(rd, iptr->dst, REG_NULL);
1846 if (iptr->dst->flags & INMEMORY ){
1847 if (src->prev->flags & INMEMORY) {
1848 /* if (src->prev->regoff == iptr->dst->regoff) { */
1849 /* TODO: optimize */
1850 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1851 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1853 /* if (src->flags & INMEMORY) { */
1854 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1856 /* M_INTMOVE(src->regoff, ECX); */
1859 /* i386_test_imm_reg(cd, 32, ECX); */
1860 /* i386_jcc(cd, I386_CC_E, 2 + 3); */
1861 /* i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1862 /* i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP2); */
1864 /* i386_shrd_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1865 /* i386_shift_reg(cd, I386_SAR, REG_ITMP2); */
1866 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1867 /* i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1870 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1871 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1873 if (src->flags & INMEMORY) {
1874 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1876 M_INTMOVE(src->regoff, ECX);
1879 i386_test_imm_reg(cd, 32, ECX);
1880 i386_jcc(cd, I386_CC_E, 2 + 3);
1881 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1882 i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP3);
1884 i386_shrd_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1885 i386_shift_reg(cd, I386_SAR, REG_ITMP3);
1886 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1887 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1893 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1894 /* val.i = constant */
1896 d = reg_of_var(rd, iptr->dst, REG_NULL);
1897 if (iptr->dst->flags & INMEMORY ) {
1898 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1899 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1901 if (iptr->val.i & 0x20) {
1902 i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1);
1903 i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP2);
1904 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1907 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1908 i386_shift_imm_reg(cd, I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
1911 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1912 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1916 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1918 d = reg_of_var(rd, iptr->dst, REG_NULL);
1919 if (iptr->dst->flags & INMEMORY ){
1920 if (src->prev->flags & INMEMORY) {
1921 /* if (src->prev->regoff == iptr->dst->regoff) { */
1922 /* TODO: optimize */
1923 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1924 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1926 /* if (src->flags & INMEMORY) { */
1927 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1929 /* M_INTMOVE(src->regoff, ECX); */
1932 /* i386_test_imm_reg(cd, 32, ECX); */
1933 /* i386_jcc(cd, I386_CC_E, 2 + 2); */
1934 /* i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1935 /* i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2); */
1937 /* i386_shrd_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1938 /* i386_shift_reg(cd, I386_SHR, REG_ITMP2); */
1939 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1940 /* i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1943 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1944 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1946 if (src->flags & INMEMORY) {
1947 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1949 M_INTMOVE(src->regoff, ECX);
1952 i386_test_imm_reg(cd, 32, ECX);
1953 i386_jcc(cd, I386_CC_E, 2 + 2);
1954 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1955 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP3, REG_ITMP3);
1957 i386_shrd_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1958 i386_shift_reg(cd, I386_SHR, REG_ITMP3);
1959 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1960 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1966 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1967 /* val.l = constant */
1969 d = reg_of_var(rd, iptr->dst, REG_NULL);
1970 if (iptr->dst->flags & INMEMORY ) {
1971 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1972 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1974 if (iptr->val.i & 0x20) {
1975 i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1);
1976 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
1977 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1980 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1981 i386_shift_imm_reg(cd, I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
1984 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1985 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1989 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1991 d = reg_of_var(rd, iptr->dst, REG_NULL);
1992 i386_emit_ialu(cd, I386_AND, src, iptr);
1995 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1996 /* val.i = constant */
1998 d = reg_of_var(rd, iptr->dst, REG_NULL);
1999 i386_emit_ialuconst(cd, I386_AND, src, iptr);
2002 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2004 d = reg_of_var(rd, iptr->dst, REG_NULL);
2005 i386_emit_lalu(cd, I386_AND, src, iptr);
2008 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2009 /* val.l = constant */
2011 d = reg_of_var(rd, iptr->dst, REG_NULL);
2012 i386_emit_laluconst(cd, I386_AND, src, iptr);
2015 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2017 d = reg_of_var(rd, iptr->dst, REG_NULL);
2018 i386_emit_ialu(cd, I386_OR, src, iptr);
2021 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2022 /* val.i = constant */
2024 d = reg_of_var(rd, iptr->dst, REG_NULL);
2025 i386_emit_ialuconst(cd, I386_OR, src, iptr);
2028 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2030 d = reg_of_var(rd, iptr->dst, REG_NULL);
2031 i386_emit_lalu(cd, I386_OR, src, iptr);
2034 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2035 /* val.l = constant */
2037 d = reg_of_var(rd, iptr->dst, REG_NULL);
2038 i386_emit_laluconst(cd, I386_OR, src, iptr);
2041 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2043 d = reg_of_var(rd, iptr->dst, REG_NULL);
2044 i386_emit_ialu(cd, I386_XOR, src, iptr);
2047 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2048 /* val.i = constant */
2050 d = reg_of_var(rd, iptr->dst, REG_NULL);
2051 i386_emit_ialuconst(cd, I386_XOR, src, iptr);
2054 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2056 d = reg_of_var(rd, iptr->dst, REG_NULL);
2057 i386_emit_lalu(cd, I386_XOR, src, iptr);
2060 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2061 /* val.l = constant */
2063 d = reg_of_var(rd, iptr->dst, REG_NULL);
2064 i386_emit_laluconst(cd, I386_XOR, src, iptr);
2067 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2068 /* op1 = variable, val.i = constant */
2070 var = &(rd->locals[iptr->op1][TYPE_INT]);
2071 if (var->flags & INMEMORY) {
2072 i386_alu_imm_membase(cd, I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2075 /* `inc reg' is slower on p4's (regarding to ia32 */
2076 /* optimization reference manual and benchmarks) and as fast */
2078 i386_alu_imm_reg(cd, I386_ADD, iptr->val.i, var->regoff);
2083 /* floating operations ************************************************/
2085 #define ROUND_TO_SINGLE \
2086 i386_fstps_membase(cd, REG_SP, -8); \
2087 i386_flds_membase(cd, REG_SP, -8);
2089 #define ROUND_TO_DOUBLE \
2090 i386_fstpl_membase(cd, REG_SP, -8); \
2091 i386_fldl_membase(cd, REG_SP, -8);
2093 #define FPU_SET_24BIT_MODE \
2094 if (!fpu_in_24bit_mode) { \
2095 i386_fldcw_mem(cd, &fpu_ctrlwrd_24bit); \
2096 fpu_in_24bit_mode = 1; \
2099 #define FPU_SET_53BIT_MODE \
2100 if (fpu_in_24bit_mode) { \
2101 i386_fldcw_mem(cd, &fpu_ctrlwrd_53bit); \
2102 fpu_in_24bit_mode = 0; \
2105 #define ROUND_TO_SINGLE
2106 #define ROUND_TO_DOUBLE
2107 #define FPU_SET_24BIT_MODE
2108 #define FPU_SET_53BIT_MODE
2110 case ICMD_FNEG: /* ..., value ==> ..., - value */
2113 var_to_reg_flt(s1, src, REG_FTMP1);
2114 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2116 store_reg_to_var_flt(iptr->dst, d);
2119 case ICMD_DNEG: /* ..., value ==> ..., - value */
2122 var_to_reg_flt(s1, src, REG_FTMP1);
2123 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2125 store_reg_to_var_flt(iptr->dst, d);
2128 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2131 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2132 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2133 var_to_reg_flt(s2, src, REG_FTMP2);
2136 store_reg_to_var_flt(iptr->dst, d);
2139 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2142 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2143 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2144 var_to_reg_flt(s2, src, REG_FTMP2);
2147 store_reg_to_var_flt(iptr->dst, d);
2150 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2153 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2154 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2155 var_to_reg_flt(s2, src, REG_FTMP2);
2158 store_reg_to_var_flt(iptr->dst, d);
2161 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2164 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2165 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2166 var_to_reg_flt(s2, src, REG_FTMP2);
2169 store_reg_to_var_flt(iptr->dst, d);
2172 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2175 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2176 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2177 var_to_reg_flt(s2, src, REG_FTMP2);
2181 store_reg_to_var_flt(iptr->dst, d);
2184 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2187 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2188 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2190 /* i386_fldt_mem(cd, subnormal_bias1); */
2191 /* i386_fmulp(cd); */
2193 var_to_reg_flt(s2, src, REG_FTMP2);
2198 /* i386_fldt_mem(cd, subnormal_bias2); */
2199 /* i386_fmulp(cd); */
2201 store_reg_to_var_flt(iptr->dst, d);
2204 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2207 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2208 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2209 var_to_reg_flt(s2, src, REG_FTMP2);
2213 store_reg_to_var_flt(iptr->dst, d);
2216 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2219 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2220 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2222 /* i386_fldt_mem(cd, subnormal_bias1); */
2223 /* i386_fmulp(cd); */
2225 var_to_reg_flt(s2, src, REG_FTMP2);
2230 /* i386_fldt_mem(cd, subnormal_bias2); */
2231 /* i386_fmulp(cd); */
2233 store_reg_to_var_flt(iptr->dst, d);
2236 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2239 /* exchanged to skip fxch */
2240 var_to_reg_flt(s2, src, REG_FTMP2);
2241 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2242 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2243 /* i386_fxch(cd); */
2248 i386_jcc(cd, I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2249 store_reg_to_var_flt(iptr->dst, d);
2250 i386_ffree_reg(cd, 0);
2255 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2258 /* exchanged to skip fxch */
2259 var_to_reg_flt(s2, src, REG_FTMP2);
2260 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2261 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2262 /* i386_fxch(cd); */
2267 i386_jcc(cd, I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2268 store_reg_to_var_flt(iptr->dst, d);
2269 i386_ffree_reg(cd, 0);
2274 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2275 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2277 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2278 if (src->flags & INMEMORY) {
2279 i386_fildl_membase(cd, REG_SP, src->regoff * 8);
2283 a = dseg_adds4(cd, 0);
2284 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2285 dseg_adddata(cd, cd->mcodeptr);
2286 i386_mov_reg_membase(cd, src->regoff, REG_ITMP1, a);
2287 i386_fildl_membase(cd, REG_ITMP1, a);
2290 store_reg_to_var_flt(iptr->dst, d);
2293 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2294 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2296 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2297 if (src->flags & INMEMORY) {
2298 i386_fildll_membase(cd, REG_SP, src->regoff * 8);
2302 panic("L2F: longs have to be in memory");
2304 store_reg_to_var_flt(iptr->dst, d);
2307 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2309 var_to_reg_flt(s1, src, REG_FTMP1);
2310 d = reg_of_var(rd, iptr->dst, REG_NULL);
2312 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2313 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2314 dseg_adddata(cd, cd->mcodeptr);
2315 i386_fldcw_membase(cd, REG_ITMP1, a);
2317 if (iptr->dst->flags & INMEMORY) {
2318 i386_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 8);
2321 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2322 i386_fldcw_membase(cd, REG_ITMP1, a);
2324 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2327 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2329 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2332 a = dseg_adds4(cd, 0);
2333 i386_fistpl_membase(cd, REG_ITMP1, a);
2335 i386_mov_membase_reg(cd, REG_ITMP1, a, iptr->dst->regoff);
2337 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2338 i386_fldcw_membase(cd, REG_ITMP1, a);
2340 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, iptr->dst->regoff);
2343 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2344 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2347 i386_jcc(cd, I386_CC_NE, a);
2349 /* XXX: change this when we use registers */
2350 i386_flds_membase(cd, REG_SP, src->regoff * 8);
2351 i386_mov_imm_reg(cd, (s4) asm_builtin_f2i, REG_ITMP1);
2352 i386_call_reg(cd, REG_ITMP1);
2354 if (iptr->dst->flags & INMEMORY) {
2355 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2358 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2362 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2364 var_to_reg_flt(s1, src, REG_FTMP1);
2365 d = reg_of_var(rd, iptr->dst, REG_NULL);
2367 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2368 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2369 dseg_adddata(cd, cd->mcodeptr);
2370 i386_fldcw_membase(cd, REG_ITMP1, a);
2372 if (iptr->dst->flags & INMEMORY) {
2373 i386_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 8);
2376 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2377 i386_fldcw_membase(cd, REG_ITMP1, a);
2379 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2382 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2384 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2387 a = dseg_adds4(cd, 0);
2388 i386_fistpl_membase(cd, REG_ITMP1, a);
2390 i386_mov_membase_reg(cd, REG_ITMP1, a, iptr->dst->regoff);
2392 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2393 i386_fldcw_membase(cd, REG_ITMP1, a);
2395 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, iptr->dst->regoff);
2398 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2399 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2402 i386_jcc(cd, I386_CC_NE, a);
2404 /* XXX: change this when we use registers */
2405 i386_fldl_membase(cd, REG_SP, src->regoff * 8);
2406 i386_mov_imm_reg(cd, (s4) asm_builtin_d2i, REG_ITMP1);
2407 i386_call_reg(cd, REG_ITMP1);
2409 if (iptr->dst->flags & INMEMORY) {
2410 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2412 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2416 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2418 var_to_reg_flt(s1, src, REG_FTMP1);
2419 d = reg_of_var(rd, iptr->dst, REG_NULL);
2421 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2422 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2423 dseg_adddata(cd, cd->mcodeptr);
2424 i386_fldcw_membase(cd, REG_ITMP1, a);
2426 if (iptr->dst->flags & INMEMORY) {
2427 i386_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 8);
2430 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2431 i386_fldcw_membase(cd, REG_ITMP1, a);
2433 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2436 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2438 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2441 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2443 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2445 i386_jcc(cd, I386_CC_NE, a);
2447 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2450 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2452 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2454 i386_jcc(cd, I386_CC_NE, a);
2456 /* XXX: change this when we use registers */
2457 i386_flds_membase(cd, REG_SP, src->regoff * 8);
2458 i386_mov_imm_reg(cd, (s4) asm_builtin_f2l, REG_ITMP1);
2459 i386_call_reg(cd, REG_ITMP1);
2460 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2461 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2464 panic("F2L: longs have to be in memory");
2468 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2470 var_to_reg_flt(s1, src, REG_FTMP1);
2471 d = reg_of_var(rd, iptr->dst, REG_NULL);
2473 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2474 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2475 dseg_adddata(cd, cd->mcodeptr);
2476 i386_fldcw_membase(cd, REG_ITMP1, a);
2478 if (iptr->dst->flags & INMEMORY) {
2479 i386_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 8);
2482 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2483 i386_fldcw_membase(cd, REG_ITMP1, a);
2485 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2488 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2490 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2493 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2495 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2497 i386_jcc(cd, I386_CC_NE, a);
2499 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2502 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2504 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2506 i386_jcc(cd, I386_CC_NE, a);
2508 /* XXX: change this when we use registers */
2509 i386_fldl_membase(cd, REG_SP, src->regoff * 8);
2510 i386_mov_imm_reg(cd, (s4) asm_builtin_d2l, REG_ITMP1);
2511 i386_call_reg(cd, REG_ITMP1);
2512 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2513 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2516 panic("D2L: longs have to be in memory");
2520 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2522 var_to_reg_flt(s1, src, REG_FTMP1);
2523 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2525 store_reg_to_var_flt(iptr->dst, d);
2528 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2530 var_to_reg_flt(s1, src, REG_FTMP1);
2531 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2533 store_reg_to_var_flt(iptr->dst, d);
2536 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2539 /* exchanged to skip fxch */
2540 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2541 var_to_reg_flt(s1, src, REG_FTMP2);
2542 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2543 /* i386_fxch(cd); */
2547 i386_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
2548 i386_jcc(cd, I386_CC_E, 6);
2549 i386_alu_imm_reg(cd, I386_AND, 0x000000ff, EAX);
2551 i386_mov_imm_reg(cd, 0, d); /* does not affect flags */
2552 i386_jcc(cd, I386_CC_E, 6 + 3 + 5 + 3);
2553 i386_jcc(cd, I386_CC_B, 3 + 5);
2554 i386_alu_imm_reg(cd, I386_SUB, 1, d);
2555 i386_jmp_imm(cd, 3);
2556 i386_alu_imm_reg(cd, I386_ADD, 1, d);
2557 store_reg_to_var_int(iptr->dst, d);
2560 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2563 /* exchanged to skip fxch */
2564 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2565 var_to_reg_flt(s1, src, REG_FTMP2);
2566 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2567 /* i386_fxch(cd); */
2571 i386_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
2572 i386_jcc(cd, I386_CC_E, 3);
2573 i386_movb_imm_reg(cd, 1, I386_AH);
2575 i386_mov_imm_reg(cd, 0, d); /* does not affect flags */
2576 i386_jcc(cd, I386_CC_E, 6 + 3 + 5 + 3);
2577 i386_jcc(cd, I386_CC_B, 3 + 5);
2578 i386_alu_imm_reg(cd, I386_SUB, 1, d);
2579 i386_jmp_imm(cd, 3);
2580 i386_alu_imm_reg(cd, I386_ADD, 1, d);
2581 store_reg_to_var_int(iptr->dst, d);
2585 /* memory operations **************************************************/
2587 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2589 var_to_reg_int(s1, src, REG_ITMP1);
2590 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2591 gen_nullptr_check(s1);
2592 i386_mov_membase_reg(cd, s1, OFFSET(java_arrayheader, size), d);
2593 store_reg_to_var_int(iptr->dst, d);
2596 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2598 var_to_reg_int(s1, src->prev, REG_ITMP1);
2599 var_to_reg_int(s2, src, REG_ITMP2);
2600 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2601 if (iptr->op1 == 0) {
2602 gen_nullptr_check(s1);
2605 i386_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2606 store_reg_to_var_int(iptr->dst, d);
2609 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2611 var_to_reg_int(s1, src->prev, REG_ITMP1);
2612 var_to_reg_int(s2, src, REG_ITMP2);
2613 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2614 if (iptr->op1 == 0) {
2615 gen_nullptr_check(s1);
2619 if (iptr->dst->flags & INMEMORY) {
2620 i386_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2621 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2622 i386_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2623 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2627 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2629 var_to_reg_int(s1, src->prev, REG_ITMP1);
2630 var_to_reg_int(s2, src, REG_ITMP2);
2631 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2632 if (iptr->op1 == 0) {
2633 gen_nullptr_check(s1);
2636 i386_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2637 store_reg_to_var_int(iptr->dst, d);
2640 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2642 var_to_reg_int(s1, src->prev, REG_ITMP1);
2643 var_to_reg_int(s2, src, REG_ITMP2);
2644 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2645 if (iptr->op1 == 0) {
2646 gen_nullptr_check(s1);
2649 i386_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2651 store_reg_to_var_flt(iptr->dst, d);
2654 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2656 var_to_reg_int(s1, src->prev, REG_ITMP1);
2657 var_to_reg_int(s2, src, REG_ITMP2);
2658 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2659 if (iptr->op1 == 0) {
2660 gen_nullptr_check(s1);
2663 i386_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2665 store_reg_to_var_flt(iptr->dst, d);
2668 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2670 var_to_reg_int(s1, src->prev, REG_ITMP1);
2671 var_to_reg_int(s2, src, REG_ITMP2);
2672 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2673 if (iptr->op1 == 0) {
2674 gen_nullptr_check(s1);
2677 i386_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2678 store_reg_to_var_int(iptr->dst, d);
2681 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2683 var_to_reg_int(s1, src->prev, REG_ITMP1);
2684 var_to_reg_int(s2, src, REG_ITMP2);
2685 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2686 if (iptr->op1 == 0) {
2687 gen_nullptr_check(s1);
2690 i386_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2691 store_reg_to_var_int(iptr->dst, d);
2694 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2696 var_to_reg_int(s1, src->prev, REG_ITMP1);
2697 var_to_reg_int(s2, src, REG_ITMP2);
2698 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2699 if (iptr->op1 == 0) {
2700 gen_nullptr_check(s1);
2703 i386_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2704 store_reg_to_var_int(iptr->dst, d);
2708 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2710 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2711 var_to_reg_int(s2, src->prev, REG_ITMP2);
2712 if (iptr->op1 == 0) {
2713 gen_nullptr_check(s1);
2716 var_to_reg_int(s3, src, REG_ITMP3);
2717 i386_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2720 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2722 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2723 var_to_reg_int(s2, src->prev, REG_ITMP2);
2724 if (iptr->op1 == 0) {
2725 gen_nullptr_check(s1);
2729 if (src->flags & INMEMORY) {
2730 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP3);
2731 i386_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2732 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2733 i386_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2737 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2739 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2740 var_to_reg_int(s2, src->prev, REG_ITMP2);
2741 if (iptr->op1 == 0) {
2742 gen_nullptr_check(s1);
2745 var_to_reg_int(s3, src, REG_ITMP3);
2746 i386_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2749 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2751 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2752 var_to_reg_int(s2, src->prev, REG_ITMP2);
2753 if (iptr->op1 == 0) {
2754 gen_nullptr_check(s1);
2757 var_to_reg_flt(s3, src, REG_FTMP1);
2758 i386_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2762 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2764 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2765 var_to_reg_int(s2, src->prev, REG_ITMP2);
2766 if (iptr->op1 == 0) {
2767 gen_nullptr_check(s1);
2770 var_to_reg_flt(s3, src, REG_FTMP1);
2771 i386_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2775 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2777 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2778 var_to_reg_int(s2, src->prev, REG_ITMP2);
2779 if (iptr->op1 == 0) {
2780 gen_nullptr_check(s1);
2783 var_to_reg_int(s3, src, REG_ITMP3);
2784 i386_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2787 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2789 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2790 var_to_reg_int(s2, src->prev, REG_ITMP2);
2791 if (iptr->op1 == 0) {
2792 gen_nullptr_check(s1);
2795 var_to_reg_int(s3, src, REG_ITMP3);
2796 i386_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2799 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2801 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2802 var_to_reg_int(s2, src->prev, REG_ITMP2);
2803 if (iptr->op1 == 0) {
2804 gen_nullptr_check(s1);
2807 var_to_reg_int(s3, src, REG_ITMP3);
2808 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2809 M_INTMOVE(s3, REG_ITMP3);
2812 i386_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2815 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2817 var_to_reg_int(s1, src->prev, REG_ITMP1);
2818 var_to_reg_int(s2, src, REG_ITMP2);
2819 if (iptr->op1 == 0) {
2820 gen_nullptr_check(s1);
2823 i386_mov_imm_memindex(cd, iptr->val.i, OFFSET(java_intarray, data[0]), s1, s2, 2);
2826 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2828 var_to_reg_int(s1, src->prev, REG_ITMP1);
2829 var_to_reg_int(s2, src, REG_ITMP2);
2830 if (iptr->op1 == 0) {
2831 gen_nullptr_check(s1);
2835 i386_mov_imm_memindex(cd, (u4) (iptr->val.l & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2836 i386_mov_imm_memindex(cd, (u4) (iptr->val.l >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2839 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2841 var_to_reg_int(s1, src->prev, REG_ITMP1);
2842 var_to_reg_int(s2, src, REG_ITMP2);
2843 if (iptr->op1 == 0) {
2844 gen_nullptr_check(s1);
2847 i386_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2850 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2852 var_to_reg_int(s1, src->prev, REG_ITMP1);
2853 var_to_reg_int(s2, src, REG_ITMP2);
2854 if (iptr->op1 == 0) {
2855 gen_nullptr_check(s1);
2858 i386_movb_imm_memindex(cd, iptr->val.i, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2861 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2863 var_to_reg_int(s1, src->prev, REG_ITMP1);
2864 var_to_reg_int(s2, src, REG_ITMP2);
2865 if (iptr->op1 == 0) {
2866 gen_nullptr_check(s1);
2869 i386_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_chararray, data[0]), s1, s2, 1);
2872 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2874 var_to_reg_int(s1, src->prev, REG_ITMP1);
2875 var_to_reg_int(s2, src, REG_ITMP2);
2876 if (iptr->op1 == 0) {
2877 gen_nullptr_check(s1);
2880 i386_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2884 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2885 /* op1 = type, val.a = field address */
2887 /* If the static fields' class is not yet initialized, we do it */
2888 /* now. The call code is generated later. */
2889 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2890 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2892 /* This is just for debugging purposes. Is very difficult to */
2893 /* read patched code. Here we patch the following 5 nop's */
2894 /* so that the real code keeps untouched. */
2895 if (showdisassemble) {
2904 a = (u4) &(((fieldinfo *) iptr->val.a)->value);
2905 switch (iptr->op1) {
2908 var_to_reg_int(s2, src, REG_ITMP1);
2909 i386_mov_reg_mem(cd, s2, a);
2912 if (src->flags & INMEMORY) {
2913 /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
2914 /* using REG_ITMP1 alternating. */
2916 i386_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
2917 i386_mov_membase_reg(cd, REG_SP, s2 * 8 + 4, REG_ITMP2);
2918 i386_mov_reg_mem(cd, REG_ITMP1, a);
2919 i386_mov_reg_mem(cd, REG_ITMP2, a + 4);
2921 panic("PUTSTATIC: longs have to be in memory");
2925 var_to_reg_flt(s2, src, REG_FTMP1);
2926 i386_fstps_mem(cd, a);
2930 var_to_reg_flt(s2, src, REG_FTMP1);
2931 i386_fstpl_mem(cd, a);
2935 throw_cacao_exception_exit(string_java_lang_InternalError,
2936 "Unknown PUTSTATIC operand type %d",
2941 case ICMD_GETSTATIC: /* ... ==> ..., value */
2942 /* op1 = type, val.a = field address */
2944 /* If the static fields' class is not yet initialized, we do it */
2945 /* now. The call code is generated later. */
2946 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2947 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2949 /* This is just for debugging purposes. Is very difficult to */
2950 /* read patched code. Here we patch the following 5 nop's */
2951 /* so that the real code keeps untouched. */
2952 if (showdisassemble) {
2961 a = (u4) &(((fieldinfo *) iptr->val.a)->value);
2962 switch (iptr->op1) {
2965 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2966 i386_mov_mem_reg(cd, a, d);
2967 store_reg_to_var_int(iptr->dst, d);
2970 d = reg_of_var(rd, iptr->dst, REG_NULL);
2971 if (iptr->dst->flags & INMEMORY) {
2972 /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
2973 /* using REG_ITMP1 alternating. */
2974 i386_mov_mem_reg(cd, a, REG_ITMP1);
2975 i386_mov_mem_reg(cd, a + 4, REG_ITMP2);
2976 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2977 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2979 panic("GETSTATIC: longs have to be in memory");
2983 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2984 i386_flds_mem(cd, a);
2986 store_reg_to_var_flt(iptr->dst, d);
2989 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2990 i386_fldl_mem(cd, a);
2992 store_reg_to_var_flt(iptr->dst, d);
2995 throw_cacao_exception_exit(string_java_lang_InternalError,
2996 "Unknown GETSTATIC operand type %d",
3001 case ICMD_PUTFIELD: /* ..., value ==> ... */
3002 /* op1 = type, val.i = field offset */
3004 a = ((fieldinfo *) (iptr->val.a))->offset;
3005 switch (iptr->op1) {
3008 var_to_reg_int(s1, src->prev, REG_ITMP1);
3009 var_to_reg_int(s2, src, REG_ITMP2);
3010 gen_nullptr_check(s1);
3011 i386_mov_reg_membase(cd, s2, s1, a);
3014 var_to_reg_int(s1, src->prev, REG_ITMP1);
3015 gen_nullptr_check(s1);
3016 if (src->flags & INMEMORY) {
3017 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);
3018 i386_mov_reg_membase(cd, REG_ITMP2, s1, a);
3019 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3020 i386_mov_reg_membase(cd, REG_ITMP2, s1, a + 4);
3022 panic("PUTFIELD: longs have to be in memory");
3026 var_to_reg_int(s1, src->prev, REG_ITMP1);
3027 var_to_reg_flt(s2, src, REG_FTMP1);
3028 gen_nullptr_check(s1);
3029 i386_fstps_membase(cd, s1, a);
3033 var_to_reg_int(s1, src->prev, REG_ITMP1);
3034 var_to_reg_flt(s2, src, REG_FTMP1);
3035 gen_nullptr_check(s1);
3036 i386_fstpl_membase(cd, s1, a);
3040 throw_cacao_exception_exit(string_java_lang_InternalError,
3041 "Unknown PUTFIELD operand type %d",
3046 case ICMD_GETFIELD: /* ... ==> ..., value */
3047 /* op1 = type, val.i = field offset */
3049 a = ((fieldinfo *) (iptr->val.a))->offset;
3050 switch (iptr->op1) {
3053 var_to_reg_int(s1, src, REG_ITMP1);
3054 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3055 gen_nullptr_check(s1);
3056 i386_mov_membase_reg(cd, s1, a, d);
3057 store_reg_to_var_int(iptr->dst, d);
3060 var_to_reg_int(s1, src, REG_ITMP1);
3061 d = reg_of_var(rd, iptr->dst, REG_NULL);
3062 gen_nullptr_check(s1);
3063 i386_mov_membase_reg(cd, s1, a, REG_ITMP2);
3064 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3065 i386_mov_membase_reg(cd, s1, a + 4, REG_ITMP2);
3066 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3069 var_to_reg_int(s1, src, REG_ITMP1);
3070 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3071 gen_nullptr_check(s1);
3072 i386_flds_membase(cd, s1, a);
3074 store_reg_to_var_flt(iptr->dst, d);
3077 var_to_reg_int(s1, src, REG_ITMP1);
3078 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3079 gen_nullptr_check(s1);
3080 i386_fldl_membase(cd, s1, a);
3082 store_reg_to_var_flt(iptr->dst, d);
3085 throw_cacao_exception_exit(string_java_lang_InternalError,
3086 "Unknown GETFIELD operand type %d",
3092 /* branch operations **************************************************/
3094 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3096 var_to_reg_int(s1, src, REG_ITMP1);
3097 M_INTMOVE(s1, REG_ITMP1_XPTR);
3099 i386_call_imm(cd, 0); /* passing exception pointer */
3100 i386_pop_reg(cd, REG_ITMP2_XPC);
3102 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
3103 i386_jmp_reg(cd, REG_ITMP3);
3107 case ICMD_GOTO: /* ... ==> ... */
3108 /* op1 = target JavaVM pc */
3110 i386_jmp_imm(cd, 0);
3111 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3115 case ICMD_JSR: /* ... ==> ... */
3116 /* op1 = target JavaVM pc */
3118 i386_call_imm(cd, 0);
3119 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3122 case ICMD_RET: /* ... ==> ... */
3123 /* op1 = local variable */
3125 var = &(rd->locals[iptr->op1][TYPE_ADR]);
3126 var_to_reg_int(s1, var, REG_ITMP1);
3127 i386_jmp_reg(cd, s1);
3130 case ICMD_IFNULL: /* ..., value ==> ... */
3131 /* op1 = target JavaVM pc */
3133 if (src->flags & INMEMORY) {
3134 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
3137 i386_test_reg_reg(cd, src->regoff, src->regoff);
3139 i386_jcc(cd, I386_CC_E, 0);
3140 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3143 case ICMD_IFNONNULL: /* ..., value ==> ... */
3144 /* op1 = target JavaVM pc */
3146 if (src->flags & INMEMORY) {
3147 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
3150 i386_test_reg_reg(cd, src->regoff, src->regoff);
3152 i386_jcc(cd, I386_CC_NE, 0);
3153 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3156 case ICMD_IFEQ: /* ..., value ==> ... */
3157 /* op1 = target JavaVM pc, val.i = constant */
3159 if (src->flags & INMEMORY) {
3160 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3163 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3165 i386_jcc(cd, I386_CC_E, 0);
3166 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3169 case ICMD_IFLT: /* ..., value ==> ... */
3170 /* op1 = target JavaVM pc, val.i = constant */
3172 if (src->flags & INMEMORY) {
3173 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3176 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3178 i386_jcc(cd, I386_CC_L, 0);
3179 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3182 case ICMD_IFLE: /* ..., value ==> ... */
3183 /* op1 = target JavaVM pc, val.i = constant */
3185 if (src->flags & INMEMORY) {
3186 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3189 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3191 i386_jcc(cd, I386_CC_LE, 0);
3192 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3195 case ICMD_IFNE: /* ..., value ==> ... */
3196 /* op1 = target JavaVM pc, val.i = constant */
3198 if (src->flags & INMEMORY) {
3199 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3202 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3204 i386_jcc(cd, I386_CC_NE, 0);
3205 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3208 case ICMD_IFGT: /* ..., value ==> ... */
3209 /* op1 = target JavaVM pc, val.i = constant */
3211 if (src->flags & INMEMORY) {
3212 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3215 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3217 i386_jcc(cd, I386_CC_G, 0);
3218 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3221 case ICMD_IFGE: /* ..., value ==> ... */
3222 /* op1 = target JavaVM pc, val.i = constant */
3224 if (src->flags & INMEMORY) {
3225 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3228 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3230 i386_jcc(cd, I386_CC_GE, 0);
3231 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3234 case ICMD_IF_LEQ: /* ..., value ==> ... */
3235 /* op1 = target JavaVM pc, val.l = constant */
3237 if (src->flags & INMEMORY) {
3238 if (iptr->val.l == 0) {
3239 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3240 i386_alu_membase_reg(cd, I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3243 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3244 i386_alu_imm_reg(cd, I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3245 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3246 i386_alu_imm_reg(cd, I386_XOR, iptr->val.l, REG_ITMP1);
3247 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3250 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3251 i386_jcc(cd, I386_CC_E, 0);
3252 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3255 case ICMD_IF_LLT: /* ..., value ==> ... */
3256 /* op1 = target JavaVM pc, val.l = constant */
3258 if (src->flags & INMEMORY) {
3259 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3260 i386_jcc(cd, I386_CC_L, 0);
3261 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3264 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3265 CALCIMMEDIATEBYTES(a, iptr->val.l);
3267 i386_jcc(cd, I386_CC_G, a);
3269 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3270 i386_jcc(cd, I386_CC_B, 0);
3271 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3275 case ICMD_IF_LLE: /* ..., value ==> ... */
3276 /* op1 = target JavaVM pc, val.l = constant */
3278 if (src->flags & INMEMORY) {
3279 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3280 i386_jcc(cd, I386_CC_L, 0);
3281 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3284 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3285 CALCIMMEDIATEBYTES(a, iptr->val.l);
3287 i386_jcc(cd, I386_CC_G, a);
3289 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3290 i386_jcc(cd, I386_CC_BE, 0);
3291 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3295 case ICMD_IF_LNE: /* ..., value ==> ... */
3296 /* op1 = target JavaVM pc, val.l = constant */
3298 if (src->flags & INMEMORY) {
3299 if (iptr->val.l == 0) {
3300 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3301 i386_alu_membase_reg(cd, I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3304 i386_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
3305 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3306 i386_mov_imm_reg(cd, iptr->val.l >> 32, REG_ITMP2);
3307 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3308 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3311 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3312 i386_jcc(cd, I386_CC_NE, 0);
3313 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3316 case ICMD_IF_LGT: /* ..., value ==> ... */
3317 /* op1 = target JavaVM pc, val.l = constant */
3319 if (src->flags & INMEMORY) {
3320 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3321 i386_jcc(cd, I386_CC_G, 0);
3322 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3325 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3326 CALCIMMEDIATEBYTES(a, iptr->val.l);
3328 i386_jcc(cd, I386_CC_L, a);
3330 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3331 i386_jcc(cd, I386_CC_A, 0);
3332 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3336 case ICMD_IF_LGE: /* ..., value ==> ... */
3337 /* op1 = target JavaVM pc, val.l = constant */
3339 if (src->flags & INMEMORY) {
3340 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3341 i386_jcc(cd, I386_CC_G, 0);
3342 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3345 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3346 CALCIMMEDIATEBYTES(a, iptr->val.l);
3348 i386_jcc(cd, I386_CC_L, a);
3350 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3351 i386_jcc(cd, I386_CC_AE, 0);
3352 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3356 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3357 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3359 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3360 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3361 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3363 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3364 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3366 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3367 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3370 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3372 i386_jcc(cd, I386_CC_E, 0);
3373 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3376 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3377 /* op1 = target JavaVM pc */
3379 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3380 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3381 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3382 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3383 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3384 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3385 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3387 i386_jcc(cd, I386_CC_E, 0);
3388 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3391 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3392 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3394 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3395 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3396 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3398 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3399 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3401 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3402 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3405 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3407 i386_jcc(cd, I386_CC_NE, 0);
3408 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3411 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3412 /* op1 = target JavaVM pc */
3414 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3415 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3416 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3417 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3418 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3419 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3420 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3422 i386_jcc(cd, I386_CC_NE, 0);
3423 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3426 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3427 /* op1 = target JavaVM pc */
3429 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3430 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3431 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3433 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3434 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3436 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3437 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3440 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3442 i386_jcc(cd, I386_CC_L, 0);
3443 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3446 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3447 /* op1 = target JavaVM pc */
3449 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3450 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3451 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3452 i386_jcc(cd, I386_CC_L, 0);
3453 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3456 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3457 CALCOFFSETBYTES(a, REG_SP, src->regoff);
3459 i386_jcc(cd, I386_CC_G, a);
3461 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3462 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3463 i386_jcc(cd, I386_CC_B, 0);
3464 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3468 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3469 /* op1 = target JavaVM pc */
3471 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3472 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3473 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3475 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3476 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3478 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3479 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3482 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3484 i386_jcc(cd, I386_CC_G, 0);
3485 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3488 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3489 /* op1 = target JavaVM pc */
3491 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3492 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3493 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3494 i386_jcc(cd, I386_CC_G, 0);
3495 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3498 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3499 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3501 i386_jcc(cd, I386_CC_L, a);
3503 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3504 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3505 i386_jcc(cd, I386_CC_A, 0);
3506 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3510 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3511 /* op1 = target JavaVM pc */
3513 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3514 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3515 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3517 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3518 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3520 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3521 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3524 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3526 i386_jcc(cd, I386_CC_LE, 0);
3527 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3530 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3531 /* op1 = target JavaVM pc */
3533 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3534 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3535 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3536 i386_jcc(cd, I386_CC_L, 0);
3537 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3540 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3541 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3543 i386_jcc(cd, I386_CC_G, a);
3545 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3546 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3547 i386_jcc(cd, I386_CC_BE, 0);
3548 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3552 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3553 /* op1 = target JavaVM pc */
3555 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3556 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3557 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3559 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3560 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3562 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3563 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3566 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3568 i386_jcc(cd, I386_CC_GE, 0);
3569 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3572 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3573 /* op1 = target JavaVM pc */
3575 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3576 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3577 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3578 i386_jcc(cd, I386_CC_G, 0);
3579 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3582 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3583 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3585 i386_jcc(cd, I386_CC_L, a);
3587 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3588 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3589 i386_jcc(cd, I386_CC_AE, 0);
3590 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3594 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3596 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3599 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3600 /* val.i = constant */
3602 d = reg_of_var(rd, iptr->dst, REG_NULL);
3603 i386_emit_ifcc_iconst(cd, I386_CC_NE, src, iptr);
3606 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3607 /* val.i = constant */
3609 d = reg_of_var(rd, iptr->dst, REG_NULL);
3610 i386_emit_ifcc_iconst(cd, I386_CC_E, src, iptr);
3613 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3614 /* val.i = constant */
3616 d = reg_of_var(rd, iptr->dst, REG_NULL);
3617 i386_emit_ifcc_iconst(cd, I386_CC_GE, src, iptr);
3620 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3621 /* val.i = constant */
3623 d = reg_of_var(rd, iptr->dst, REG_NULL);
3624 i386_emit_ifcc_iconst(cd, I386_CC_L, src, iptr);
3627 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3628 /* val.i = constant */
3630 d = reg_of_var(rd, iptr->dst, REG_NULL);
3631 i386_emit_ifcc_iconst(cd, I386_CC_LE, src, iptr);
3634 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3635 /* val.i = constant */
3637 d = reg_of_var(rd, iptr->dst, REG_NULL);
3638 i386_emit_ifcc_iconst(cd, I386_CC_G, src, iptr);
3642 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3645 var_to_reg_int(s1, src, REG_RESULT);
3646 M_INTMOVE(s1, REG_RESULT);
3648 goto nowperformreturn;
3650 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3652 if (src->flags & INMEMORY) {
3653 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_RESULT);
3654 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3657 panic("LRETURN: longs have to be in memory");
3660 goto nowperformreturn;
3662 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3663 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3665 var_to_reg_flt(s1, src, REG_FRESULT);
3666 /* this may be an early return -- keep the offset correct for the
3670 goto nowperformreturn;
3672 case ICMD_RETURN: /* ... ==> ... */
3678 p = parentargs_base;
3680 /* call trace function */
3682 i386_alu_imm_reg(cd, I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3684 i386_mov_imm_membase(cd, (s4) m, REG_SP, 0);
3686 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
3687 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
3689 i386_fstl_membase(cd, REG_SP, 4 + 8);
3690 i386_fsts_membase(cd, REG_SP, 4 + 8 + 8);
3692 i386_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
3693 i386_call_reg(cd, REG_ITMP1);
3695 i386_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
3696 i386_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
3698 i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3701 #if defined(USE_THREADS)
3702 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3703 i386_mov_membase_reg(cd, REG_SP, 8 * rd->maxmemuse, REG_ITMP2);
3705 /* we need to save the proper return value */
3706 switch (iptr->opc) {
3709 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, rd->maxmemuse * 8);
3713 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, rd->maxmemuse * 8);
3714 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, rd->maxmemuse * 8 + 4);
3718 i386_fsts_membase(cd, REG_SP, rd->maxmemuse * 8);
3722 i386_fstl_membase(cd, REG_SP, rd->maxmemuse * 8);
3726 i386_alu_imm_reg(cd, I386_SUB, 4, REG_SP);
3727 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, 0);
3728 i386_mov_imm_reg(cd, (s4) builtin_monitorexit, REG_ITMP1);
3729 i386_call_reg(cd, REG_ITMP1);
3730 i386_alu_imm_reg(cd, I386_ADD, 4, REG_SP);
3732 /* and now restore the proper return value */
3733 switch (iptr->opc) {
3736 i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8, REG_RESULT);
3740 i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8, REG_RESULT);
3741 i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8 + 4, REG_RESULT2);
3745 i386_flds_membase(cd, REG_SP, rd->maxmemuse * 8);
3749 i386_fldl_membase(cd, REG_SP, rd->maxmemuse * 8);
3755 /* restore saved registers */
3756 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
3758 i386_mov_membase_reg(cd, REG_SP, p * 8, rd->savintregs[i]);
3760 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
3762 i386_fldl_membase(cd, REG_SP, p * 8);
3764 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3765 i386_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1);
3767 i386_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset);
3772 /* deallocate stack */
3773 if (parentargs_base) {
3774 i386_alu_imm_reg(cd, I386_ADD, parentargs_base * 8, REG_SP);
3783 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3788 tptr = (void **) iptr->target;
3790 s4ptr = iptr->val.a;
3791 l = s4ptr[1]; /* low */
3792 i = s4ptr[2]; /* high */
3794 var_to_reg_int(s1, src, REG_ITMP1);
3795 M_INTMOVE(s1, REG_ITMP1);
3797 i386_alu_imm_reg(cd, I386_SUB, l, REG_ITMP1);
3803 i386_alu_imm_reg(cd, I386_CMP, i - 1, REG_ITMP1);
3804 i386_jcc(cd, I386_CC_A, 0);
3806 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), cd->mcodeptr); */
3807 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3809 /* build jump table top down and use address of lowest entry */
3811 /* s4ptr += 3 + i; */
3815 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3816 dseg_addtarget(cd, (basicblock *) tptr[0]);
3820 /* length of dataseg after last dseg_addtarget is used by load */
3822 i386_mov_imm_reg(cd, 0, REG_ITMP2);
3823 dseg_adddata(cd, cd->mcodeptr);
3824 i386_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3825 i386_jmp_reg(cd, REG_ITMP1);
3831 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3833 s4 i, l, val, *s4ptr;
3836 tptr = (void **) iptr->target;
3838 s4ptr = iptr->val.a;
3839 l = s4ptr[0]; /* default */
3840 i = s4ptr[1]; /* count */
3842 MCODECHECK((i<<2)+8);
3843 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3849 i386_alu_imm_reg(cd, I386_CMP, val, s1);
3850 i386_jcc(cd, I386_CC_E, 0);
3851 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), cd->mcodeptr); */
3852 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3855 i386_jmp_imm(cd, 0);
3856 /* codegen_addreference(cd, BlockPtrOfPC(l), cd->mcodeptr); */
3858 tptr = (void **) iptr->target;
3859 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3866 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3867 /* op1 = return type, val.a = function pointer*/
3871 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3872 /* op1 = return type, val.a = function pointer*/
3876 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3877 /* op1 = return type, val.a = function pointer*/
3881 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3882 /* op1 = arg count, val.a = method pointer */
3884 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3885 /* op1 = arg count, val.a = method pointer */
3887 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3888 /* op1 = arg count, val.a = method pointer */
3890 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3891 /* op1 = arg count, val.a = method pointer */
3898 MCODECHECK((s3 << 1) + 64);
3900 /* copy arguments to registers or stack location */
3902 for (; --s3 >= 0; src = src->prev) {
3903 if (src->varkind == ARGVAR) {
3907 if (IS_INT_LNG_TYPE(src->type)) {
3908 if (s3 < rd->intreg_argnum) {
3909 panic("No integer argument registers available!");
3912 if (!IS_2_WORD_TYPE(src->type)) {
3913 if (src->flags & INMEMORY) {
3914 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3915 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s3 * 8);
3918 i386_mov_reg_membase(cd, src->regoff, REG_SP, s3 * 8);
3922 if (src->flags & INMEMORY) {
3923 M_LNGMEMMOVE(src->regoff, s3);
3926 panic("copy arguments: longs have to be in memory");
3932 if (s3 < rd->fltreg_argnum) {
3933 panic("No float argument registers available!");
3936 var_to_reg_flt(d, src, REG_FTMP1);
3937 if (src->type == TYPE_FLT) {
3938 i386_fstps_membase(cd, REG_SP, s3 * 8);
3941 i386_fstpl_membase(cd, REG_SP, s3 * 8);
3948 switch (iptr->opc) {
3955 i386_mov_imm_reg(cd, a, REG_ITMP1);
3956 i386_call_reg(cd, REG_ITMP1);
3959 case ICMD_INVOKESTATIC:
3960 a = (u4) lm->stubroutine;
3963 i386_mov_imm_reg(cd, a, REG_ITMP2);
3964 i386_call_reg(cd, REG_ITMP2);
3967 case ICMD_INVOKESPECIAL:
3968 a = (u4) lm->stubroutine;
3971 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3972 gen_nullptr_check(REG_ITMP1);
3973 i386_mov_membase_reg(cd, REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
3975 i386_mov_imm_reg(cd, a, REG_ITMP2);
3976 i386_call_reg(cd, REG_ITMP2);
3979 case ICMD_INVOKEVIRTUAL:
3982 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3983 gen_nullptr_check(REG_ITMP1);
3984 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
3985 i386_mov_membase32_reg(cd, REG_ITMP2, OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex, REG_ITMP1);
3987 i386_call_reg(cd, REG_ITMP1);
3990 case ICMD_INVOKEINTERFACE:
3993 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3994 gen_nullptr_check(REG_ITMP1);
3995 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
3996 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr) * lm->class->index, REG_ITMP2);
3997 i386_mov_membase32_reg(cd, REG_ITMP2, sizeof(methodptr) * (lm - lm->class->methods), REG_ITMP1);
3999 i386_call_reg(cd, REG_ITMP1);
4003 /* d contains return type */
4005 if (d != TYPE_VOID) {
4006 d = reg_of_var(rd, iptr->dst, REG_NULL);
4008 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4009 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4010 if (iptr->dst->flags & INMEMORY) {
4011 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4012 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4015 panic("RETURN: longs have to be in memory");
4019 if (iptr->dst->flags & INMEMORY) {
4020 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4023 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4028 /* fld from called function -- has other fpu_st_offset counter */
4030 store_reg_to_var_flt(iptr->dst, d);
4037 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4039 /* op1: 0 == array, 1 == class */
4040 /* val.a: (classinfo*) superclass */
4042 /* superclass is an interface:
4044 * return (sub != NULL) &&
4045 * (sub->vftbl->interfacetablelength > super->index) &&
4046 * (sub->vftbl->interfacetable[-super->index] != NULL);
4048 * superclass is a class:
4050 * return ((sub != NULL) && (0
4051 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4052 * super->vftbl->diffvall));
4056 classinfo *super = (classinfo*) iptr->val.a;
4058 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4059 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
4061 var_to_reg_int(s1, src, REG_ITMP1);
4062 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
4064 M_INTMOVE(s1, REG_ITMP1);
4067 i386_alu_reg_reg(cd, I386_XOR, d, d);
4068 if (iptr->op1) { /* class/interface */
4069 if (super->flags & ACC_INTERFACE) { /* interface */
4070 i386_test_reg_reg(cd, s1, s1);
4072 /* TODO: clean up this calculation */
4074 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4077 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
4080 /* CALCOFFSETBYTES(a, super->index); */
4081 CALCIMMEDIATEBYTES(a, super->index);
4087 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4094 i386_jcc(cd, I386_CC_E, a);
4096 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4097 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength), REG_ITMP2);
4098 i386_alu_imm_reg(cd, I386_SUB, super->index, REG_ITMP2);
4100 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4102 /* TODO: clean up this calculation */
4105 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4112 i386_jcc(cd, I386_CC_LE, a);
4113 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4115 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP1);
4116 /* i386_setcc_reg(cd, I386_CC_A, d); */
4117 /* i386_jcc(cd, I386_CC_BE, 5); */
4118 i386_jcc(cd, I386_CC_E, 5);
4119 i386_mov_imm_reg(cd, 1, d);
4122 } else { /* class */
4123 i386_test_reg_reg(cd, s1, s1);
4125 /* TODO: clean up this calculation */
4127 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4130 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, baseval));
4132 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4135 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4145 i386_jcc(cd, I386_CC_E, a);
4147 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4148 i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4149 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4150 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4152 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, baseval), REG_ITMP1);
4153 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP3);
4154 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4155 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4156 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4158 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP3, REG_ITMP1);
4159 i386_alu_reg_reg(cd, I386_XOR, d, d);
4161 i386_alu_reg_reg(cd, I386_CMP, REG_ITMP2, REG_ITMP1);
4162 i386_jcc(cd, I386_CC_A, 5);
4163 i386_mov_imm_reg(cd, 1, d);
4167 panic ("internal error: no inlined array instanceof");
4169 store_reg_to_var_int(iptr->dst, d);
4172 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4174 /* op1: 0 == array, 1 == class */
4175 /* val.a: (classinfo*) superclass */
4177 /* superclass is an interface:
4179 * OK if ((sub == NULL) ||
4180 * (sub->vftbl->interfacetablelength > super->index) &&
4181 * (sub->vftbl->interfacetable[-super->index] != NULL));
4183 * superclass is a class:
4185 * OK if ((sub == NULL) || (0
4186 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4187 * super->vftbl->diffvall));
4191 classinfo *super = (classinfo*) iptr->val.a;
4193 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4194 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
4196 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
4197 var_to_reg_int(s1, src, d);
4198 if (iptr->op1) { /* class/interface */
4199 if (super->flags & ACC_INTERFACE) { /* interface */
4200 i386_test_reg_reg(cd, s1, s1);
4202 /* TODO: clean up this calculation */
4204 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4207 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
4210 /* CALCOFFSETBYTES(a, super->index); */
4211 CALCIMMEDIATEBYTES(a, super->index);
4217 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4222 i386_jcc(cd, I386_CC_E, a);
4224 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4225 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength), REG_ITMP2);
4226 i386_alu_imm_reg(cd, I386_SUB, super->index, REG_ITMP2);
4228 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4229 i386_jcc(cd, I386_CC_LE, 0);
4230 codegen_addxcastrefs(cd, cd->mcodeptr);
4231 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4233 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4234 i386_jcc(cd, I386_CC_E, 0);
4235 codegen_addxcastrefs(cd, cd->mcodeptr);
4237 } else { /* class */
4238 i386_test_reg_reg(cd, s1, s1);
4240 /* TODO: clean up this calculation */
4242 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4247 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, baseval));
4249 if (d != REG_ITMP3) {
4251 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4254 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4260 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4267 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4274 i386_jcc(cd, I386_CC_E, a);
4276 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4277 i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4278 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4279 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4281 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, baseval), REG_ITMP1);
4282 if (d != REG_ITMP3) {
4283 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP3);
4284 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4285 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4286 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4288 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP3, REG_ITMP1);
4291 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP2);
4292 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP2, REG_ITMP1);
4293 i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4294 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4295 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4296 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4300 i386_alu_reg_reg(cd, I386_CMP, REG_ITMP2, REG_ITMP1);
4301 i386_jcc(cd, I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4302 codegen_addxcastrefs(cd, cd->mcodeptr);
4306 panic ("internal error: no inlined array checkcast");
4309 store_reg_to_var_int(iptr->dst, d);
4312 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4314 if (src->flags & INMEMORY) {
4315 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
4318 i386_test_reg_reg(cd, src->regoff, src->regoff);
4320 i386_jcc(cd, I386_CC_L, 0);
4321 codegen_addxcheckarefs(cd, cd->mcodeptr);
4324 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
4326 i386_test_reg_reg(cd, REG_RESULT, REG_RESULT);
4327 i386_jcc(cd, I386_CC_E, 0);
4328 codegen_addxexceptionrefs(cd, cd->mcodeptr);
4331 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4332 /* op1 = dimension, val.a = array descriptor */
4334 /* check for negative sizes and copy sizes to stack if necessary */
4336 MCODECHECK((iptr->op1 << 1) + 64);
4338 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4339 if (src->flags & INMEMORY) {
4340 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
4343 i386_test_reg_reg(cd, src->regoff, src->regoff);
4345 i386_jcc(cd, I386_CC_L, 0);
4346 codegen_addxcheckarefs(cd, cd->mcodeptr);
4349 * copy sizes to new stack location, be cause native function
4350 * builtin_nmultianewarray access them as (int *)
4352 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
4353 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4355 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4357 if (src->varkind != ARGVAR) {
4358 if (src->flags & INMEMORY) {
4359 i386_mov_membase_reg(cd, REG_SP, (src->regoff + INT_ARG_CNT) * 8, REG_ITMP1);
4360 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, (s1 + INT_ARG_CNT) * 8);
4363 i386_mov_reg_membase(cd, src->regoff, REG_SP, (s1 + INT_ARG_CNT) * 8);
4367 i386_alu_imm_reg(cd, I386_SUB, iptr->op1 * 4, REG_SP);
4369 /* a0 = dimension count */
4371 /* save stack pointer */
4372 M_INTMOVE(REG_SP, REG_ITMP1);
4374 i386_alu_imm_reg(cd, I386_SUB, 12, REG_SP);
4375 i386_mov_imm_membase(cd, iptr->op1, REG_SP, 0);
4377 /* a1 = arraydescriptor */
4379 i386_mov_imm_membase(cd, (s4) iptr->val.a, REG_SP, 4);
4381 /* a2 = pointer to dimensions = stack pointer */
4383 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 8);
4385 i386_mov_imm_reg(cd, (s4) (builtin_nmultianewarray), REG_ITMP1);
4386 i386_call_reg(cd, REG_ITMP1);
4387 i386_alu_imm_reg(cd, I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4389 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
4390 M_INTMOVE(REG_RESULT, s1);
4391 store_reg_to_var_int(iptr->dst, s1);
4394 case ICMD_INLINE_START:
4395 case ICMD_INLINE_END:
4398 error ("Unknown pseudo command: %d", iptr->opc);
4401 } /* for instruction */
4403 /* copy values to interface registers */
4405 src = bptr->outstack;
4406 len = bptr->outdepth;
4413 if ((src->varkind != STACKVAR)) {
4415 if (IS_FLT_DBL_TYPE(s2)) {
4416 var_to_reg_flt(s1, src, REG_FTMP1);
4417 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4418 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4421 panic("double store");
4422 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4426 var_to_reg_int(s1, src, REG_ITMP1);
4427 if (!IS_2_WORD_TYPE(rd->interfaces[len][s2].type)) {
4428 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4429 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4432 i386_mov_reg_membase(cd, s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
4436 if (rd->interfaces[len][s2].flags & INMEMORY) {
4437 M_LNGMEMMOVE(s1, rd->interfaces[len][s2].regoff);
4440 panic("copy interface registers: longs have to be in memory (end)");
4447 } /* if (bptr -> flags >= BBREACHED) */
4448 } /* for basic block */
4450 codegen_createlinenumbertable(cd);
4454 /* generate bound check stubs */
4456 u1 *xcodeptr = NULL;
4459 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
4460 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4462 cd->mcodeptr - cd->mcodebase);
4466 /* move index register into REG_ITMP1 */
4467 i386_mov_reg_reg(cd, bref->reg, REG_ITMP1); /* 2 bytes */
4469 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4470 dseg_adddata(cd, cd->mcodeptr);
4471 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP3); /* 5 bytes */
4472 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP3, REG_ITMP2_XPC); /* 2 bytes */
4474 if (xcodeptr != NULL) {
4475 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4478 xcodeptr = cd->mcodeptr;
4480 i386_push_reg(cd, REG_ITMP2_XPC);
4482 /*PREPARE_NATIVE_STACKINFO;*/
4483 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4484 i386_push_imm(cd,0);
4485 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4486 i386_call_reg(cd,REG_ITMP3);
4488 i386_alu_imm_reg(cd, I386_SUB, 1 * 4, REG_SP);
4489 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 4);
4490 i386_mov_imm_reg(cd, (u4) new_arrayindexoutofboundsexception, REG_ITMP1);
4491 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4492 i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);
4494 /*REMOVE_NATIVE_STACKINFO;*/
4495 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4496 i386_call_reg(cd,REG_ITMP3);
4498 i386_pop_reg(cd, REG_ITMP2_XPC);
4500 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4501 i386_jmp_reg(cd, REG_ITMP3);
4505 /* generate negative array size check stubs */
4509 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
4510 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4511 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4513 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4517 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4519 cd->mcodeptr - cd->mcodebase);
4523 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4524 dseg_adddata(cd, cd->mcodeptr);
4525 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4526 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4528 if (xcodeptr != NULL) {
4529 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4532 xcodeptr = cd->mcodeptr;
4534 i386_push_reg(cd, REG_ITMP2_XPC);
4536 /*PREPARE_NATIVE_STACKINFO;*/
4537 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4538 i386_push_imm(cd,0);
4539 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4540 i386_call_reg(cd,REG_ITMP3);
4544 i386_mov_imm_reg(cd, (u4) new_negativearraysizeexception, REG_ITMP1);
4545 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4546 /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
4549 /*REMOVE_NATIVE_STACKINFO;*/
4550 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4551 i386_call_reg(cd,REG_ITMP3);
4554 i386_pop_reg(cd, REG_ITMP2_XPC);
4556 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4557 i386_jmp_reg(cd, REG_ITMP3);
4561 /* generate cast check stubs */
4565 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
4566 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4567 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4569 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4573 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4575 cd->mcodeptr - cd->mcodebase);
4579 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4580 dseg_adddata(cd, cd->mcodeptr);
4581 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4582 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4584 if (xcodeptr != NULL) {
4585 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4588 xcodeptr = cd->mcodeptr;
4590 i386_push_reg(cd, REG_ITMP2_XPC);
4592 /*PREPARE_NATIVE_STACKINFO;*/
4593 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4594 i386_push_imm(cd,0);
4595 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4596 i386_call_reg(cd,REG_ITMP3);
4599 i386_mov_imm_reg(cd, (u4) new_classcastexception, REG_ITMP1);
4600 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4601 /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
4604 /*REMOVE_NATIVE_STACKINFO;*/
4605 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4606 i386_call_reg(cd,REG_ITMP3);
4609 i386_pop_reg(cd, REG_ITMP2_XPC);
4611 i386_mov_imm_reg(cd, (u4) asm_handle_exception, REG_ITMP3);
4612 i386_jmp_reg(cd, REG_ITMP3);
4616 /* generate divide by zero check stubs */
4620 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
4621 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4622 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4624 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4628 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4630 cd->mcodeptr - cd->mcodebase);
4634 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4635 dseg_adddata(cd, cd->mcodeptr);
4636 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4637 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4639 if (xcodeptr != NULL) {
4640 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4643 xcodeptr = cd->mcodeptr;
4645 i386_push_reg(cd, REG_ITMP2_XPC);
4647 /*PREPARE_NATIVE_STACKINFO;*/
4648 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4649 i386_push_imm(cd,0);
4650 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4651 i386_call_reg(cd,REG_ITMP3);
4655 i386_mov_imm_reg(cd, (u4) new_arithmeticexception, REG_ITMP1);
4656 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4658 /*REMOVE_NATIVE_STACKINFO;*/
4659 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4660 i386_call_reg(cd,REG_ITMP3);
4663 i386_pop_reg(cd, REG_ITMP2_XPC);
4665 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4666 i386_jmp_reg(cd, REG_ITMP3);
4670 /* generate exception check stubs */
4674 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4675 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4676 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4678 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4682 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4684 cd->mcodeptr - cd->mcodebase);
4688 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4689 dseg_adddata(cd, cd->mcodeptr);
4690 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4691 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4693 if (xcodeptr != NULL) {
4694 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4697 xcodeptr = cd->mcodeptr;
4699 i386_push_reg(cd, REG_ITMP2_XPC);
4701 /*PREPARE_NATIVE_STACKINFO;*/
4702 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4703 i386_push_imm(cd,0);
4704 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4705 i386_call_reg(cd,REG_ITMP3);
4708 i386_mov_imm_reg(cd, (s4) codegen_general_stubcalled, REG_ITMP1);
4709 i386_call_reg(cd, REG_ITMP1);
4711 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4712 i386_mov_imm_reg(cd, (s4) &builtin_get_exceptionptrptr, REG_ITMP1);
4713 i386_call_reg(cd, REG_ITMP1);
4714 i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP3);
4715 i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
4716 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1_XPTR);
4718 i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP3);
4719 i386_mov_membase_reg(cd, REG_ITMP3, 0, REG_ITMP1_XPTR);
4720 i386_mov_imm_membase(cd, 0, REG_ITMP3, 0);
4722 i386_push_imm(cd, 0);
4723 i386_push_reg(cd, REG_ITMP1_XPTR);
4725 /*get the fillInStackTrace Method ID. I simulate a native call here, because I do not want to mess around with the
4726 java stack at this point*/
4727 i386_mov_membase_reg(cd, REG_ITMP1_XPTR, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4728 i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, class), REG_ITMP1);
4729 i386_push_imm(cd, (u4) utf_fillInStackTrace_desc);
4730 i386_push_imm(cd, (u4) utf_fillInStackTrace_name);
4731 i386_push_reg(cd, REG_ITMP1);
4732 i386_mov_imm_reg(cd, (s4) class_resolvemethod, REG_ITMP3);
4733 i386_call_reg(cd, REG_ITMP3);
4734 /*cleanup parameters of class_resolvemethod*/
4735 i386_alu_imm_reg(cd, I386_ADD,3*4 /*class reference + 2x string reference*/,REG_SP);
4736 /*prepare call to asm_calljavafunction2 */
4737 i386_push_imm(cd, 0);
4738 i386_push_imm(cd, TYPE_ADR); /* --> call block (TYPE,Exceptionptr), each 8 byte (make this dynamic) (JOWENN)*/
4739 i386_push_reg(cd, REG_SP);
4740 i386_push_imm(cd, sizeof(jni_callblock));
4741 i386_push_imm(cd, 1);
4742 i386_push_reg(cd, REG_RESULT);
4744 i386_mov_imm_reg(cd, (s4) asm_calljavafunction2, REG_ITMP3);
4745 i386_call_reg(cd, REG_ITMP3);
4747 /* check exceptionptr + fail (JOWENN)*/
4749 i386_alu_imm_reg(cd, I386_ADD,6*4,REG_SP);
4751 i386_pop_reg(cd, REG_ITMP1_XPTR);
4752 i386_pop_reg(cd, REG_ITMP3); /* just remove the no longer needed 0 from the stack*/
4754 /*REMOVE_NATIVE_STACKINFO;*/
4755 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4756 i386_call_reg(cd,REG_ITMP3);
4759 i386_pop_reg(cd, REG_ITMP2_XPC);
4761 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4762 i386_jmp_reg(cd, REG_ITMP3);
4766 /* generate null pointer check stubs */
4770 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
4771 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4772 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4774 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4778 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4780 cd->mcodeptr - cd->mcodebase);
4784 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4785 dseg_adddata(cd, cd->mcodeptr);
4786 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4787 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4789 if (xcodeptr != NULL) {
4790 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4793 xcodeptr = cd->mcodeptr;
4795 i386_push_reg(cd, REG_ITMP2_XPC);
4797 /*PREPARE_NATIVE_STACKINFO;*/
4798 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4799 i386_push_imm(cd,0);
4800 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4801 i386_call_reg(cd,REG_ITMP3);
4806 /* create native call block*/
4807 i386_alu_imm_reg(cd, I386_SUB, 3*4, REG_SP); /* build stack frame (4 * 4 bytes) */
4810 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1);
4811 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/
4813 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1);
4814 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/
4815 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
4816 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/
4817 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */
4818 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */
4819 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */
4822 i386_mov_imm_reg(cd, (u4) new_nullpointerexception, REG_ITMP1);
4823 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4825 /*REMOVE_NATIVE_STACKINFO;*/
4826 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4827 i386_call_reg(cd,REG_ITMP3);
4831 /* restore native call stack */
4832 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2);
4833 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3);
4834 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0);
4835 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
4838 i386_pop_reg(cd, REG_ITMP2_XPC);
4840 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4841 i386_jmp_reg(cd, REG_ITMP3);
4845 /* generate put/getstatic stub call code */
4853 tmpcd = DNEW(codegendata);
4855 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
4856 /* Get machine code which is patched back in later. A */
4857 /* `call rel32' is 5 bytes long. */
4858 xcodeptr = cd->mcodebase + cref->branchpos;
4860 mcode = *((u4 *) (xcodeptr + 1));
4864 /* patch in `call rel32' to call the following code */
4865 tmpcd->mcodeptr = xcodeptr; /* set dummy mcode pointer */
4866 i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
4868 /* Save current stack pointer into a temporary register. */
4869 i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
4871 /* Push machine code bytes to patch onto the stack. */
4872 i386_push_imm(cd, (u4) xmcode);
4873 i386_push_imm(cd, (u4) mcode);
4875 i386_push_imm(cd, (u4) cref->class);
4877 /* Push previously saved stack pointer onto stack. */
4878 i386_push_reg(cd, REG_ITMP1);
4880 i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
4881 i386_jmp_reg(cd, REG_ITMP1);
4886 codegen_finish(m, cd, (u4) (cd->mcodeptr - cd->mcodebase));
4890 /* function createcompilerstub *************************************************
4892 creates a stub routine which calls the compiler
4894 *******************************************************************************/
4896 #define COMPSTUBSIZE 12
4898 u1 *createcompilerstub(methodinfo *m)
4900 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4904 /* mark start of dump memory area */
4906 dumpsize = dump_size();
4908 cd = DNEW(codegendata);
4911 /* code for the stub */
4912 i386_mov_imm_reg(cd, (u4) m, REG_ITMP1);/* pass method pointer to compiler*/
4914 /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching */
4915 i386_mov_imm_reg(cd, (u4) asm_call_jit_compiler, REG_ITMP3);
4916 i386_jmp_reg(cd, REG_ITMP3); /* jump to compiler */
4918 #if defined(STATISTICS)
4920 count_cstub_len += COMPSTUBSIZE;
4923 /* release dump area */
4925 dump_release(dumpsize);
4931 /* function removecompilerstub *************************************************
4933 deletes a compilerstub from memory (simply by freeing it)
4935 *******************************************************************************/
4937 void removecompilerstub(u1 *stub)
4939 CFREE(stub, COMPSTUBSIZE);
4943 /* function: createnativestub **************************************************
4945 creates a stub routine which calls a native method
4947 *******************************************************************************/
4949 #define NATIVESTUBSIZE 370 + 36
4952 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4953 static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
4956 void i386_native_stub_debug(void **p) {
4957 printf("Pos on stack: %p\n",p);
4958 printf("Return adress should be: %p\n",*p);
4961 void i386_native_stub_debug2(void **p) {
4962 printf("Pos on stack: %p\n",p);
4963 printf("Return for lookup is: %p\n",*p);
4966 void traverseStackInfo() {
4967 void **p=builtin_asm_get_stackframeinfo();
4971 printf("base addr:%p, methodinfo:%p\n",*p,(methodinfo*)((*p)+8));
4972 m=*((methodinfo**)((*p)+8));
4973 utf_display(m->name);
4982 u1 *createnativestub(functionptr f, methodinfo *m)
4984 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4987 t_inlining_globals *id;
4993 int stackframesize = 4+16; /* initial 4 bytes is space for jni env,
4994 + 4 byte thread pointer + 4 byte previous pointer + method info + 4 offset native*/
4995 int stackframeoffset = 4;
4999 void** callAddrPatchPos=0;
5001 void** jmpInstrPatchPos=0;
5003 /* mark start of dump memory area */
5005 dumpsize = dump_size();
5007 /* allocate required dump memory */
5009 cd = DNEW(codegendata);
5010 rd = DNEW(registerdata);
5011 id = DNEW(t_inlining_globals);
5013 /* setup registers before using it */
5015 inlining_setup(m, id);
5016 reg_setup(m, rd, id);
5018 /* set some required varibles which are normally set by codegen_setup */
5021 cd->clinitrefs = NULL;
5023 if (m->flags & ACC_STATIC) {
5024 stackframesize += 4;
5025 stackframeoffset += 4;
5028 descriptor2types(m); /* set paramcount and paramtypes */
5031 /* i386_push_reg(cd, REG_SP);
5032 i386_mov_imm_reg(cd, (s4) i386_native_stub_debug, REG_ITMP1);
5033 i386_call_reg(cd, REG_ITMP1);
5034 i386_pop_reg(cd, REG_ITMP1);*/
5037 /* if function is static, check for initialized */
5039 if (m->flags & ACC_STATIC) {
5040 /* if class isn't yet initialized, do it */
5041 if (!m->class->initialized) {
5042 s4 *header = (s4 *) s;
5043 *header = 0;/*extablesize*/
5045 *header = 0;/*line number table start*/
5047 *header = 0;/*line number table size*/
5049 *header = 0;/*fltsave*/
5051 *header = 0;/*intsave*/
5053 *header = 0;/*isleaf*/
5055 *header = 0;/*issync*/
5057 *header = 0;/*framesize*/
5059 *header = (u4) m;/*methodpointer*/
5068 codegen_addclinitref(cd, cd->mcodeptr, m->class);
5073 i386_alu_imm_reg(cd, I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5075 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
5076 t = m->paramtypes[p];
5077 if (IS_INT_LNG_TYPE(t)) {
5078 if (IS_2_WORD_TYPE(t)) {
5079 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5080 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
5081 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5082 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5084 } else if (t == TYPE_ADR) {
5085 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5086 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
5087 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5088 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5091 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
5093 i386_mov_reg_membase(cd, EAX, REG_SP, p * 8);
5094 i386_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4);
5098 if (!IS_2_WORD_TYPE(t)) {
5099 i386_flds_membase(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5100 i386_fstps_membase(cd, REG_SP, p * 8);
5101 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
5102 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5105 i386_fldl_membase(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5106 i386_fstpl_membase(cd, REG_SP, p * 8);
5111 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
5112 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
5113 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5114 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
5117 i386_mov_imm_membase(cd, (s4) m, REG_SP, TRACE_ARGS_NUM * 8);
5119 i386_mov_imm_reg(cd, (s4) builtin_trace_args, REG_ITMP1);
5120 i386_call_reg(cd, REG_ITMP1);
5122 i386_alu_imm_reg(cd, I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5126 * mark the whole fpu stack as free for native functions
5127 * (only for saved register count == 0)
5129 i386_ffree_reg(cd, 0);
5130 i386_ffree_reg(cd, 1);
5131 i386_ffree_reg(cd, 2);
5132 i386_ffree_reg(cd, 3);
5133 i386_ffree_reg(cd, 4);
5134 i386_ffree_reg(cd, 5);
5135 i386_ffree_reg(cd, 6);
5136 i386_ffree_reg(cd, 7);
5138 /* calculate stackframe size for native function */
5139 tptr = m->paramtypes;
5140 for (i = 0; i < m->paramcount; i++) {
5145 stackframesize += 4;
5150 stackframesize += 8;
5154 panic("unknown parameter type in native function");
5158 i386_alu_imm_reg(cd, I386_SUB, stackframesize, REG_SP);
5160 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
5161 i386_mov_imm_membase(cd,0,REG_SP,stackframesize-4);
5162 i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
5163 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
5164 i386_call_reg(cd, REG_ITMP1);
5165 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-12); /*save thread specific pointer*/
5166 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2);
5167 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-16); /*save previous value of memory adress pointed to by thread specific pointer*/
5168 i386_mov_reg_reg(cd, REG_SP,REG_ITMP2);
5169 i386_alu_imm_reg(cd, I386_ADD,stackframesize-16,REG_ITMP2);
5170 i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT,0);
5173 /* i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-4);
5174 i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
5175 i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-12);*/
5177 /* CREATE DYNAMIC STACK INFO -- END*/
5179 /* RESOLVE NATIVE METHOD -- BEGIN*/
5180 #ifndef STATIC_CLASSPATH
5182 /*log_text("Dynamic classpath: preparing for delayed native function resolving");*/
5184 jmpInstrPos=cd->mcodeptr-4;
5186 i386_mov_imm_reg(cd,jmpInstrPos,REG_ITMP1);
5187 i386_push_reg(cd,REG_ITMP1);
5189 i386_mov_imm_reg(cd,0,REG_ITMP1);
5190 jmpInstrPatchPos=cd->mcodeptr-4;
5191 i386_push_reg(cd,REG_ITMP1);
5192 /*position of call address to patch*/
5193 i386_mov_imm_reg(cd,0,REG_ITMP1);
5194 callAddrPatchPos=(cd->mcodeptr-4);
5195 i386_push_reg(cd,REG_ITMP1);
5196 /*method info structure*/
5197 i386_mov_imm_reg(cd,(s4) m, REG_ITMP1);
5198 i386_push_reg(cd,REG_ITMP1);
5199 /*call resolve functions*/
5200 i386_mov_imm_reg(cd, (s4)codegen_resolve_native,REG_ITMP1);
5201 i386_call_reg(cd,REG_ITMP1);
5203 i386_pop_reg(cd,REG_ITMP1);
5204 i386_pop_reg(cd,REG_ITMP1);
5205 i386_pop_reg(cd,REG_ITMP1);
5206 i386_pop_reg(cd,REG_ITMP1);
5207 /*fix jmp offset replacement*/
5208 (*jmpInstrPatchPos)=cd->mcodeptr-jmpInstrPos-4;
5209 } /*else log_text("Dynamic classpath: immediate native function resolution possible");*/
5211 /* RESOLVE NATIVE METHOD -- END*/
5215 tptr = m->paramtypes;
5216 for (i = 0; i < m->paramcount; i++) {
5221 i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5222 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, stackframeoffset);
5223 stackframeoffset += 4;
5228 i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5229 i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5230 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, stackframeoffset);
5231 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, stackframeoffset + 4);
5232 stackframeoffset += 8;
5236 panic("unknown parameter type in native function");
5240 if (m->flags & ACC_STATIC) {
5241 /* put class into second argument */
5242 i386_mov_imm_membase(cd, (s4) m->class, REG_SP, 4);
5245 /* put env into first argument */
5246 i386_mov_imm_membase(cd, (s4) &env, REG_SP, 0);
5248 i386_mov_imm_reg(cd, (s4) f, REG_ITMP1);
5249 #ifndef STATIC_CLASSPATH
5251 (*callAddrPatchPos)=(cd->mcodeptr-4);
5253 i386_call_reg(cd, REG_ITMP1);
5255 /*REMOVE DYNAMIC STACK INFO -BEGIN */
5256 i386_push_reg(cd, REG_RESULT2);
5257 i386_mov_membase_reg(cd, REG_SP,stackframesize-12,REG_ITMP2); /*old value*/
5258 i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_RESULT2); /*pointer*/
5259 i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT2,0);
5260 i386_pop_reg(cd, REG_RESULT2);
5261 /*REMOVE DYNAMIC STACK INFO -END */
5263 i386_alu_imm_reg(cd, I386_ADD, stackframesize, REG_SP);
5267 i386_alu_imm_reg(cd, I386_SUB, 4 + 8 + 8 + 4, REG_SP);
5269 i386_mov_imm_membase(cd, (u4) m, REG_SP, 0);
5271 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
5272 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
5274 i386_fstl_membase(cd, REG_SP, 4 + 8);
5275 i386_fsts_membase(cd, REG_SP, 4 + 8 + 8);
5277 i386_mov_imm_reg(cd, (u4) builtin_displaymethodstop, REG_ITMP1);
5278 i386_call_reg(cd, REG_ITMP1);
5280 i386_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
5281 i386_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
5283 i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
5286 /* we can't use REG_ITMP3 == REG_RESULT2 */
5287 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5288 i386_push_reg(cd, REG_RESULT);
5289 i386_push_reg(cd, REG_RESULT2);
5290 i386_call_mem(cd, (s4) &callgetexceptionptrptr);
5291 i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP2);
5292 i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
5293 i386_pop_reg(cd, REG_RESULT2);
5294 i386_pop_reg(cd, REG_RESULT);
5296 i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP2);
5297 i386_mov_membase_reg(cd, REG_ITMP2, 0, REG_ITMP2);
5298 i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
5300 i386_jcc(cd, I386_CC_NE, 1);
5304 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5305 i386_push_reg(cd, REG_ITMP2);
5306 i386_call_mem(cd, (s4) &callgetexceptionptrptr);
5307 i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
5308 i386_pop_reg(cd, REG_ITMP1_XPTR);
5310 i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1_XPTR);
5311 i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP2);
5312 i386_mov_imm_membase(cd, 0, REG_ITMP2, 0);
5314 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP2_XPC);
5315 i386_alu_imm_reg(cd, I386_SUB, 2, REG_ITMP2_XPC);
5317 i386_mov_imm_reg(cd, (s4) asm_handle_nat_exception, REG_ITMP3);
5318 i386_jmp_reg(cd, REG_ITMP3);
5321 codegen_insertmethod(s, cd->mcodeptr);
5331 tmpcd = DNEW(codegendata);
5333 /* there can only be one clinit ref entry */
5334 cref = cd->clinitrefs;
5337 /* Get machine code which is patched back in later. A */
5338 /* `call rel32' is 5 bytes long. */
5339 xcodeptr = cd->mcodebase + cref->branchpos;
5341 mcode = *((u4 *) (xcodeptr + 1));
5343 /* patch in `call rel32' to call the following code */
5344 tmpcd->mcodeptr = xcodeptr; /* set dummy mcode pointer */
5345 i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
5347 /* Save current stack pointer into a temporary register. */
5348 i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
5350 /* Push machine code bytes to patch onto the stack. */
5351 i386_push_imm(cd, (u4) xmcode);
5352 i386_push_imm(cd, (u4) mcode);
5354 i386_push_imm(cd, (u4) cref->class);
5356 /* Push previously saved stack pointer onto stack. */
5357 i386_push_reg(cd, REG_ITMP1);
5359 i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
5360 i386_jmp_reg(cd, REG_ITMP1);
5365 dolog_plain("native stubentry: %p, stubsize: %d (for %d params) --", (s4)s,(s4) (cd->mcodeptr - s), m->paramcount);
5366 utf_display(m->name);
5370 #if defined(STATISTICS)
5372 count_nstub_len += NATIVESTUBSIZE;
5375 /* release dump area */
5377 dump_release(dumpsize);
5383 /* function: removenativestub **************************************************
5385 removes a previously created native-stub from memory
5387 *******************************************************************************/
5389 void removenativestub(u1 *stub)
5391 CFREE(stub, NATIVESTUBSIZE);
5396 * These are local overrides for various environment variables in Emacs.
5397 * Please do not remove this and leave it at the end of the file, where
5398 * Emacs will automagically detect them.
5399 * ---------------------------------------------------------------------
5402 * indent-tabs-mode: t