1 /* vm/jit/i386/codegen.c - machine code generator for i386
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
32 $Id: codegen.c 1735 2004-12-07 14:33:27Z twisti $
42 #include <machine/signal.h>
46 #include "native/jni.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
51 #include "vm/loader.h"
52 #include "vm/tables.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/jit.h"
55 #include "vm/jit/parse.h"
56 #include "vm/jit/reg.h"
57 #include "vm/jit/i386/codegen.h"
58 #include "vm/jit/i386/emitfuncs.h"
59 #include "vm/jit/i386/types.h"
60 #include "vm/jit/i386/asmoffsets.h"
63 /* register descripton - array ************************************************/
65 /* #define REG_RES 0 reserved register for OS or code generator */
66 /* #define REG_RET 1 return value register */
67 /* #define REG_EXC 2 exception value register (only old jit) */
68 /* #define REG_SAV 3 (callee) saved register */
69 /* #define REG_TMP 4 scratch temporary register (caller saved) */
70 /* #define REG_ARG 5 argument register (caller saved) */
72 /* #define REG_END -1 last entry in tables */
74 static int nregdescint[] = {
75 REG_RET, REG_RES, REG_RES, REG_TMP, REG_RES, REG_SAV, REG_SAV, REG_SAV,
80 static int nregdescfloat[] = {
81 /* rounding problems with callee saved registers */
82 /* REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_TMP, REG_TMP, REG_RES, REG_RES, */
83 /* REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_RES, REG_RES, */
84 REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES,
89 /*******************************************************************************
91 include independent code generation stuff -- include after register
92 descriptions to avoid extern definitions
94 *******************************************************************************/
96 #include "vm/jit/codegen.inc"
97 #include "vm/jit/reg.inc"
99 #include "vm/jit/lsra.inc"
102 void codegen_stubcalled() {
103 log_text("Stub has been called");
106 void codegen_general_stubcalled() {
107 log_text("general exception stub has been called");
111 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
112 void thread_restartcriticalsection(ucontext_t *uc)
116 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.mc_eip)) != NULL)
117 uc->uc_mcontext.mc_eip = (u4) critical;
119 if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[REG_EIP])) != NULL)
120 uc->uc_mcontext.gregs[REG_EIP] = (u4) critical;
128 /* NullPointerException signal handler for hardware null pointer check */
130 void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
133 /* long faultaddr; */
136 ucontext_t *_uc = (ucontext_t *) _p;
137 mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
139 struct ucontext *_uc = (struct ucontext *) _p;
140 struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
142 struct sigaction act;
144 /* Reset signal handler - necessary for SysV, does no harm for BSD */
146 /* instr = *((int*)(sigctx->eip)); */
147 /* faultaddr = sigctx->sc_regs[(instr >> 16) & 0x1f]; */
149 /* fprintf(stderr, "null=%d %p addr=%p\n", sig, sigctx, sigctx->eip);*/
151 /* if (faultaddr == 0) { */
152 /* signal(sig, (void *) catch_NullPointerException); */
153 act.sa_sigaction = (functionptr) catch_NullPointerException;
154 act.sa_flags = SA_SIGINFO;
155 sigaction(sig, &act, NULL); /* reinstall handler */
158 sigaddset(&nsig, sig);
159 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
162 sigctx->mc_ecx = sigctx->mc_eip; /* REG_ITMP2_XPC*/
163 sigctx->mc_eax = (u4) string_java_lang_NullPointerException;
164 sigctx->mc_eip = (u4) asm_throw_and_handle_exception;
166 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
167 sigctx->eax = (u4) string_java_lang_NullPointerException;
168 sigctx->eip = (u4) asm_throw_and_handle_exception;
173 /* faultaddr += (long) ((instr << 16) >> 16); */
174 /* fprintf(stderr, "faulting address: 0x%08x\n", faultaddr); */
175 /* panic("Stack overflow"); */
180 /* ArithmeticException signal handler for hardware divide by zero check */
182 void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
186 /* void **_p = (void **) &sig; */
187 /* struct sigcontext *sigctx = (struct sigcontext *) ++_p; */
190 ucontext_t *_uc = (ucontext_t *) _p;
191 mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
193 struct ucontext *_uc = (struct ucontext *) _p;
194 struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
197 struct sigaction act;
199 /* Reset signal handler - necessary for SysV, does no harm for BSD */
201 /* signal(sig, (void *) catch_ArithmeticException); */
202 act.sa_sigaction = (functionptr) catch_ArithmeticException;
203 act.sa_flags = SA_SIGINFO;
204 sigaction(sig, &act, NULL); /* reinstall handler */
207 sigaddset(&nsig, sig);
208 sigprocmask(SIG_UNBLOCK, &nsig, NULL); /* unblock signal */
211 sigctx->mc_ecx = sigctx->mc_eip; /* REG_ITMP2_XPC */
212 sigctx->mc_eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
214 sigctx->ecx = sigctx->eip; /* REG_ITMP2_XPC */
215 sigctx->eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
221 void init_exceptions(void)
223 struct sigaction act;
225 /* install signal handlers we need to convert to exceptions */
226 sigemptyset(&act.sa_mask);
230 /* signal(SIGSEGV, (void *) catch_NullPointerException); */
231 act.sa_sigaction = (functionptr) catch_NullPointerException;
232 act.sa_flags = SA_SIGINFO;
233 sigaction(SIGSEGV, &act, NULL);
237 /* signal(SIGBUS, (void *) catch_NullPointerException); */
238 act.sa_sigaction = (functionptr) catch_NullPointerException;
239 act.sa_flags = SA_SIGINFO;
240 sigaction(SIGBUS, &act, NULL);
244 /* signal(SIGFPE, (void *) catch_ArithmeticException); */
245 act.sa_sigaction = (functionptr) catch_ArithmeticException;
246 act.sa_flags = SA_SIGINFO;
247 sigaction(SIGFPE, &act, NULL);
251 /* function codegen ************************************************************
253 generates machine code
255 *******************************************************************************/
257 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
259 s4 len, s1, s2, s3, d;
267 s4 fpu_st_offset = 0;
273 s4 savedregs_num = 0;
275 /* space to save used callee saved registers */
277 savedregs_num += (rd->savintregcnt - rd->maxsavintreguse);
278 savedregs_num += (rd->savfltregcnt - rd->maxsavfltreguse);
280 parentargs_base = rd->maxmemuse + savedregs_num;
283 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
285 if (checksync && (m->flags & ACC_SYNCHRONIZED))
290 /* create method header */
292 (void) dseg_addaddress(cd, m); /* MethodPointer */
293 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
295 #if defined(USE_THREADS)
297 /* IsSync contains the offset relative to the stack pointer for the
298 argument of monitor_exit used in the exception handler. Since the
299 offset could be zero and give a wrong meaning of the flag it is
303 if (checksync && (m->flags & ACC_SYNCHRONIZED))
304 (void) dseg_adds4(cd, (rd->maxmemuse + 1) * 8); /* IsSync */
309 (void) dseg_adds4(cd, 0); /* IsSync */
311 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
312 (void) dseg_adds4(cd, rd->savintregcnt - rd->maxsavintreguse); /* IntSave */
313 (void) dseg_adds4(cd, rd->savfltregcnt - rd->maxsavfltreguse); /* FltSave */
315 /* adds a reference for the length of the line number counter. We don't
316 know the size yet, since we evaluate the information during code
317 generation, to save one additional iteration over the whole
318 instructions. During code optimization the position could have changed
319 to the information gotten from the class file */
320 (void) dseg_addlinenumbertablesize(cd);
322 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
324 /* create exception table */
326 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
327 dseg_addtarget(cd, ex->start);
328 dseg_addtarget(cd, ex->end);
329 dseg_addtarget(cd, ex->handler);
330 (void) dseg_addaddress(cd, ex->catchtype);
334 /* initialize mcode variables */
336 cd->mcodeptr = cd->mcodebase;
337 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
338 MCODECHECK(128 + m->paramcount);
340 /* create stack frame (if necessary) */
342 if (parentargs_base) {
343 i386_alu_imm_reg(cd, I386_SUB, parentargs_base * 8, REG_SP);
346 /* save return address and used callee saved registers */
349 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
350 p--; i386_mov_reg_membase(cd, rd->savintregs[i], REG_SP, p * 8);
352 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
353 p--; i386_fld_reg(cd, rd->savfltregs[i]); i386_fstpl_membase(cd, REG_SP, p * 8);
356 /* save monitorenter argument */
358 #if defined(USE_THREADS)
359 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
360 s4 func_enter = (m->flags & ACC_STATIC) ?
361 (s4) builtin_staticmonitorenter : (s4) builtin_monitorenter;
363 if (m->flags & ACC_STATIC) {
364 i386_mov_imm_reg(cd, (s4) m->class, REG_ITMP1);
365 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
368 i386_mov_membase_reg(cd, REG_SP, parentargs_base * 8 + 4, REG_ITMP1);
369 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, rd->maxmemuse * 8);
372 /* call monitorenter function */
374 i386_alu_imm_reg(cd, I386_SUB, 4, REG_SP);
375 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0);
376 i386_mov_imm_reg(cd, func_enter, REG_ITMP1);
377 i386_call_reg(cd, REG_ITMP1);
378 i386_alu_imm_reg(cd, I386_ADD, 4, REG_SP);
382 /* copy argument registers to stack and call trace function with pointer
383 to arguments on stack.
387 i386_alu_imm_reg(cd, I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
389 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
390 t = m->paramtypes[p];
392 if (IS_INT_LNG_TYPE(t)) {
393 if (IS_2_WORD_TYPE(t)) {
394 i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
395 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
396 i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP1);
397 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
399 /* } else if (t == TYPE_ADR) { */
401 i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
402 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
403 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
404 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
407 /* i386_mov_membase_reg(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4, EAX); */
409 /* i386_mov_reg_membase(cd, EAX, REG_SP, p * 8); */
410 /* i386_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4); */
414 if (!IS_2_WORD_TYPE(t)) {
415 i386_flds_membase(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
416 i386_fstps_membase(cd, REG_SP, p * 8);
417 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
418 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
421 i386_fldl_membase(cd, REG_SP, 4 + (parentargs_base + TRACE_ARGS_NUM + p) * 8 + 4);
422 i386_fstpl_membase(cd, REG_SP, p * 8);
427 /* fill up the remaining arguments */
428 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
429 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
430 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
431 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
434 i386_mov_imm_membase(cd, (s4) m, REG_SP, TRACE_ARGS_NUM * 8);
435 i386_mov_imm_reg(cd, (s4) builtin_trace_args, REG_ITMP1);
436 i386_call_reg(cd, REG_ITMP1);
438 i386_alu_imm_reg(cd, I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
441 /* take arguments out of register or stack frame */
443 for (p = 0, l = 0; p < m->paramcount; p++) {
444 t = m->paramtypes[p];
445 var = &(rd->locals[l][t]);
447 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
451 if (IS_INT_LNG_TYPE(t)) { /* integer args */
452 if (p < rd->intreg_argnum) { /* register arguments */
453 panic("integer register argument");
454 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
455 /* M_INTMOVE (argintregs[p], r); */
457 } else { /* reg arg -> spilled */
458 /* M_LST (argintregs[p], REG_SP, 8 * r); */
460 } else { /* stack arguments */
461 pa = p - rd->intreg_argnum;
462 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
463 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, var->regoff); /* + 4 for return address */
464 } else { /* stack arg -> spilled */
465 if (!IS_2_WORD_TYPE(t)) {
466 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
467 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
470 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); /* + 4 for return address */
471 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
472 i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4 + 4, REG_ITMP1); /* + 4 for return address */
473 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8 + 4);
478 } else { /* floating args */
479 if (p < rd->fltreg_argnum) { /* register arguments */
480 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
481 panic("There are no float argument registers!");
483 } else { /* reg arg -> spilled */
484 panic("There are no float argument registers!");
487 } else { /* stack arguments */
488 pa = p - rd->fltreg_argnum;
489 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
491 i386_flds_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
493 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
497 i386_fldl_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
499 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
503 } else { /* stack-arg -> spilled */
504 /* i386_mov_membase_reg(cd, REG_SP, (parentargs_base + pa) * 8 + 4, REG_ITMP1); */
505 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, r * 8); */
507 i386_flds_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
508 i386_fstps_membase(cd, REG_SP, var->regoff * 8);
511 i386_fldl_membase(cd, REG_SP, (parentargs_base + pa) * 8 + 4);
512 i386_fstpl_membase(cd, REG_SP, var->regoff * 8);
521 /* end of header generation */
523 /* walk through all basic blocks */
524 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
526 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
528 if (bptr->flags >= BBREACHED) {
530 /* branch resolving */
533 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
534 gen_resolvebranch(cd->mcodebase + brefs->branchpos,
539 /* copy interface registers to their destination */
547 while (src != NULL) {
549 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
550 if (!IS_2_WORD_TYPE(src->type)) {
551 if (bptr->type == BBTYPE_SBR) {
552 /* d = reg_of_var(m, src, REG_ITMP1); */
553 if (!(src->flags & INMEMORY))
558 store_reg_to_var_int(src, d);
559 } else if (bptr->type == BBTYPE_EXH) {
560 /* d = reg_of_var(m, src, REG_ITMP1); */
561 if (!(src->flags & INMEMORY))
565 M_INTMOVE(REG_ITMP1, d);
566 store_reg_to_var_int(src, d);
570 panic("copy interface registers(EXH, SBR): longs have to me in memory (begin 1)");
577 while (src != NULL) {
579 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
580 if (!IS_2_WORD_TYPE(src->type)) {
581 if (bptr->type == BBTYPE_SBR) {
582 d = reg_of_var(rd, src, REG_ITMP1);
584 store_reg_to_var_int(src, d);
585 } else if (bptr->type == BBTYPE_EXH) {
586 d = reg_of_var(rd, src, REG_ITMP1);
587 M_INTMOVE(REG_ITMP1, d);
588 store_reg_to_var_int(src, d);
592 panic("copy interface registers: longs have to me in memory (begin 1)");
596 d = reg_of_var(rd, src, REG_ITMP1);
597 if ((src->varkind != STACKVAR)) {
599 if (IS_FLT_DBL_TYPE(s2)) {
600 s1 = rd->interfaces[len][s2].regoff;
601 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
605 if (s2 == TYPE_FLT) {
606 i386_flds_membase(cd, REG_SP, s1 * 8);
609 i386_fldl_membase(cd, REG_SP, s1 * 8);
612 store_reg_to_var_flt(src, d);
615 s1 = rd->interfaces[len][s2].regoff;
616 if (!IS_2_WORD_TYPE(rd->interfaces[len][s2].type)) {
617 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
621 i386_mov_membase_reg(cd, REG_SP, s1 * 8, d);
623 store_reg_to_var_int(src, d);
626 if (rd->interfaces[len][s2].flags & INMEMORY) {
627 M_LNGMEMMOVE(s1, src->regoff);
630 panic("copy interface registers: longs have to be in memory (begin 2)");
642 /* walk through all instructions */
647 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
648 if (iptr->line != currentline) {
649 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
650 currentline = iptr->line;
653 MCODECHECK(64); /* an instruction usually needs < 64 words */
656 case ICMD_NOP: /* ... ==> ... */
659 case ICMD_NULLCHECKPOP: /* ..., objectref ==> ... */
660 if (src->flags & INMEMORY) {
661 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
664 i386_test_reg_reg(cd, src->regoff, src->regoff);
666 i386_jcc(cd, I386_CC_E, 0);
667 codegen_addxnullrefs(cd, cd->mcodeptr);
670 /* constant operations ************************************************/
672 case ICMD_ICONST: /* ... ==> ..., constant */
673 /* op1 = 0, val.i = constant */
675 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
676 if (iptr->dst->flags & INMEMORY) {
677 i386_mov_imm_membase(cd, iptr->val.i, REG_SP, iptr->dst->regoff * 8);
680 if (iptr->val.i == 0) {
681 i386_alu_reg_reg(cd, I386_XOR, d, d);
684 i386_mov_imm_reg(cd, iptr->val.i, d);
689 case ICMD_LCONST: /* ... ==> ..., constant */
690 /* op1 = 0, val.l = constant */
692 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
693 if (iptr->dst->flags & INMEMORY) {
694 i386_mov_imm_membase(cd, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
695 i386_mov_imm_membase(cd, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
698 panic("LCONST: longs have to be in memory");
702 case ICMD_FCONST: /* ... ==> ..., constant */
703 /* op1 = 0, val.f = constant */
705 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
706 if (iptr->val.f == 0.0) {
711 if (iptr->val.i == 0x80000000) {
715 } else if (iptr->val.f == 1.0) {
719 } else if (iptr->val.f == 2.0) {
726 a = dseg_addfloat(cd, iptr->val.f);
727 i386_mov_imm_reg(cd, 0, REG_ITMP1);
728 dseg_adddata(cd, cd->mcodeptr);
729 i386_flds_membase(cd, REG_ITMP1, a);
732 store_reg_to_var_flt(iptr->dst, d);
735 case ICMD_DCONST: /* ... ==> ..., constant */
736 /* op1 = 0, val.d = constant */
738 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
739 if (iptr->val.d == 0.0) {
744 if (iptr->val.l == 0x8000000000000000LL) {
748 } else if (iptr->val.d == 1.0) {
752 } else if (iptr->val.d == 2.0) {
759 a = dseg_adddouble(cd, iptr->val.d);
760 i386_mov_imm_reg(cd, 0, REG_ITMP1);
761 dseg_adddata(cd, cd->mcodeptr);
762 i386_fldl_membase(cd, REG_ITMP1, a);
765 store_reg_to_var_flt(iptr->dst, d);
768 case ICMD_ACONST: /* ... ==> ..., constant */
769 /* op1 = 0, val.a = constant */
771 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
772 if (iptr->dst->flags & INMEMORY) {
773 i386_mov_imm_membase(cd, (s4) iptr->val.a, REG_SP, iptr->dst->regoff * 8);
776 if ((s4) iptr->val.a == 0) {
777 i386_alu_reg_reg(cd, I386_XOR, d, d);
780 i386_mov_imm_reg(cd, (s4) iptr->val.a, d);
786 /* load/store operations **********************************************/
788 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
789 case ICMD_ALOAD: /* op1 = local variable */
791 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
792 if ((iptr->dst->varkind == LOCALVAR) &&
793 (iptr->dst->varnum == iptr->op1)) {
796 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
797 if (iptr->dst->flags & INMEMORY) {
798 if (var->flags & INMEMORY) {
799 i386_mov_membase_reg(cd, REG_SP, var->regoff * 8, REG_ITMP1);
800 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
803 i386_mov_reg_membase(cd, var->regoff, REG_SP, iptr->dst->regoff * 8);
807 if (var->flags & INMEMORY) {
808 i386_mov_membase_reg(cd, REG_SP, var->regoff * 8, iptr->dst->regoff);
811 M_INTMOVE(var->regoff, iptr->dst->regoff);
816 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
817 /* op1 = local variable */
819 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
820 if ((iptr->dst->varkind == LOCALVAR) &&
821 (iptr->dst->varnum == iptr->op1)) {
824 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
825 if (iptr->dst->flags & INMEMORY) {
826 if (var->flags & INMEMORY) {
827 M_LNGMEMMOVE(var->regoff, iptr->dst->regoff);
830 panic("LLOAD: longs have to be in memory");
834 panic("LLOAD: longs have to be in memory");
838 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
839 /* op1 = local variable */
841 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
842 if ((iptr->dst->varkind == LOCALVAR) &&
843 (iptr->dst->varnum == iptr->op1)) {
846 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
847 if (var->flags & INMEMORY) {
848 i386_flds_membase(cd, REG_SP, var->regoff * 8);
851 i386_fld_reg(cd, var->regoff + fpu_st_offset);
854 store_reg_to_var_flt(iptr->dst, d);
857 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
858 /* op1 = local variable */
860 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
861 if ((iptr->dst->varkind == LOCALVAR) &&
862 (iptr->dst->varnum == iptr->op1)) {
865 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
866 if (var->flags & INMEMORY) {
867 i386_fldl_membase(cd, REG_SP, var->regoff * 8);
870 i386_fld_reg(cd, var->regoff + fpu_st_offset);
873 store_reg_to_var_flt(iptr->dst, d);
876 case ICMD_ISTORE: /* ..., value ==> ... */
877 case ICMD_ASTORE: /* op1 = local variable */
879 if ((src->varkind == LOCALVAR) &&
880 (src->varnum == iptr->op1)) {
883 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
884 if (var->flags & INMEMORY) {
885 if (src->flags & INMEMORY) {
886 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
887 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, var->regoff * 8);
890 i386_mov_reg_membase(cd, src->regoff, REG_SP, var->regoff * 8);
894 var_to_reg_int(s1, src, var->regoff);
895 M_INTMOVE(s1, var->regoff);
899 case ICMD_LSTORE: /* ..., value ==> ... */
900 /* op1 = local variable */
902 if ((src->varkind == LOCALVAR) &&
903 (src->varnum == iptr->op1)) {
906 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
907 if (var->flags & INMEMORY) {
908 if (src->flags & INMEMORY) {
909 M_LNGMEMMOVE(src->regoff, var->regoff);
912 panic("LSTORE: longs have to be in memory");
916 panic("LSTORE: longs have to be in memory");
920 case ICMD_FSTORE: /* ..., value ==> ... */
921 /* op1 = local variable */
923 if ((src->varkind == LOCALVAR) &&
924 (src->varnum == iptr->op1)) {
927 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
928 if (var->flags & INMEMORY) {
929 var_to_reg_flt(s1, src, REG_FTMP1);
930 i386_fstps_membase(cd, REG_SP, var->regoff * 8);
933 var_to_reg_flt(s1, src, var->regoff);
934 /* M_FLTMOVE(s1, var->regoff); */
935 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
940 case ICMD_DSTORE: /* ..., value ==> ... */
941 /* op1 = local variable */
943 if ((src->varkind == LOCALVAR) &&
944 (src->varnum == iptr->op1)) {
947 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
948 if (var->flags & INMEMORY) {
949 var_to_reg_flt(s1, src, REG_FTMP1);
950 i386_fstpl_membase(cd, REG_SP, var->regoff * 8);
953 var_to_reg_flt(s1, src, var->regoff);
954 /* M_FLTMOVE(s1, var->regoff); */
955 i386_fstp_reg(cd, var->regoff + fpu_st_offset);
961 /* pop/dup/swap operations ********************************************/
963 /* attention: double and longs are only one entry in CACAO ICMDs */
965 case ICMD_POP: /* ..., value ==> ... */
966 case ICMD_POP2: /* ..., value, value ==> ... */
969 case ICMD_DUP: /* ..., a ==> ..., a, a */
970 M_COPY(src, iptr->dst);
973 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
975 M_COPY(src, iptr->dst);
976 M_COPY(src->prev, iptr->dst->prev);
979 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
981 M_COPY(src, iptr->dst);
982 M_COPY(src->prev, iptr->dst->prev);
983 M_COPY(iptr->dst, iptr->dst->prev->prev);
986 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
988 M_COPY(src, iptr->dst);
989 M_COPY(src->prev, iptr->dst->prev);
990 M_COPY(src->prev->prev, iptr->dst->prev->prev);
991 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
994 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
996 M_COPY(src, iptr->dst);
997 M_COPY(src->prev, iptr->dst->prev);
998 M_COPY(src->prev->prev, iptr->dst->prev->prev);
999 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
1000 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev);
1003 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1005 M_COPY(src, iptr->dst);
1006 M_COPY(src->prev, iptr->dst->prev);
1007 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1008 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1009 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
1010 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
1013 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1015 M_COPY(src, iptr->dst->prev);
1016 M_COPY(src->prev, iptr->dst);
1020 /* integer operations *************************************************/
1022 case ICMD_INEG: /* ..., value ==> ..., - value */
1024 d = reg_of_var(rd, iptr->dst, REG_NULL);
1025 if (iptr->dst->flags & INMEMORY) {
1026 if (src->flags & INMEMORY) {
1027 if (src->regoff == iptr->dst->regoff) {
1028 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1031 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1032 i386_neg_reg(cd, REG_ITMP1);
1033 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1037 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1038 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1042 if (src->flags & INMEMORY) {
1043 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1044 i386_neg_reg(cd, iptr->dst->regoff);
1047 M_INTMOVE(src->regoff, iptr->dst->regoff);
1048 i386_neg_reg(cd, iptr->dst->regoff);
1053 case ICMD_LNEG: /* ..., value ==> ..., - value */
1055 d = reg_of_var(rd, iptr->dst, REG_NULL);
1056 if (iptr->dst->flags & INMEMORY) {
1057 if (src->flags & INMEMORY) {
1058 if (src->regoff == iptr->dst->regoff) {
1059 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8);
1060 i386_alu_imm_membase(cd, I386_ADC, 0, REG_SP, iptr->dst->regoff * 8 + 4);
1061 i386_neg_membase(cd, REG_SP, iptr->dst->regoff * 8 + 4);
1064 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1065 i386_neg_reg(cd, REG_ITMP1);
1066 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1067 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1068 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP1);
1069 i386_neg_reg(cd, REG_ITMP1);
1070 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1076 case ICMD_I2L: /* ..., value ==> ..., value */
1078 d = reg_of_var(rd, iptr->dst, REG_NULL);
1079 if (iptr->dst->flags & INMEMORY) {
1080 if (src->flags & INMEMORY) {
1081 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, EAX);
1083 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1084 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1087 M_INTMOVE(src->regoff, EAX);
1089 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1090 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1095 case ICMD_L2I: /* ..., value ==> ..., value */
1097 d = reg_of_var(rd, iptr->dst, REG_NULL);
1098 if (iptr->dst->flags & INMEMORY) {
1099 if (src->flags & INMEMORY) {
1100 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1101 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1105 if (src->flags & INMEMORY) {
1106 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1111 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1113 d = reg_of_var(rd, iptr->dst, REG_NULL);
1114 if (iptr->dst->flags & INMEMORY) {
1115 if (src->flags & INMEMORY) {
1116 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1117 i386_shift_imm_reg(cd, I386_SHL, 24, REG_ITMP1);
1118 i386_shift_imm_reg(cd, I386_SAR, 24, REG_ITMP1);
1119 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1122 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1123 i386_shift_imm_membase(cd, I386_SHL, 24, REG_SP, iptr->dst->regoff * 8);
1124 i386_shift_imm_membase(cd, I386_SAR, 24, REG_SP, iptr->dst->regoff * 8);
1128 if (src->flags & INMEMORY) {
1129 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1130 i386_shift_imm_reg(cd, I386_SHL, 24, iptr->dst->regoff);
1131 i386_shift_imm_reg(cd, I386_SAR, 24, iptr->dst->regoff);
1134 M_INTMOVE(src->regoff, iptr->dst->regoff);
1135 i386_shift_imm_reg(cd, I386_SHL, 24, iptr->dst->regoff);
1136 i386_shift_imm_reg(cd, I386_SAR, 24, iptr->dst->regoff);
1141 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1143 d = reg_of_var(rd, iptr->dst, REG_NULL);
1144 if (iptr->dst->flags & INMEMORY) {
1145 if (src->flags & INMEMORY) {
1146 if (src->regoff == iptr->dst->regoff) {
1147 i386_alu_imm_membase(cd, I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1150 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1151 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, REG_ITMP1);
1152 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1156 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1157 i386_alu_imm_membase(cd, I386_AND, 0x0000ffff, REG_SP, iptr->dst->regoff * 8);
1161 if (src->flags & INMEMORY) {
1162 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1163 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, iptr->dst->regoff);
1166 M_INTMOVE(src->regoff, iptr->dst->regoff);
1167 i386_alu_imm_reg(cd, I386_AND, 0x0000ffff, iptr->dst->regoff);
1172 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1174 d = reg_of_var(rd, iptr->dst, REG_NULL);
1175 if (iptr->dst->flags & INMEMORY) {
1176 if (src->flags & INMEMORY) {
1177 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1178 i386_shift_imm_reg(cd, I386_SHL, 16, REG_ITMP1);
1179 i386_shift_imm_reg(cd, I386_SAR, 16, REG_ITMP1);
1180 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1183 i386_mov_reg_membase(cd, src->regoff, REG_SP, iptr->dst->regoff * 8);
1184 i386_shift_imm_membase(cd, I386_SHL, 16, REG_SP, iptr->dst->regoff * 8);
1185 i386_shift_imm_membase(cd, I386_SAR, 16, REG_SP, iptr->dst->regoff * 8);
1189 if (src->flags & INMEMORY) {
1190 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1191 i386_shift_imm_reg(cd, I386_SHL, 16, iptr->dst->regoff);
1192 i386_shift_imm_reg(cd, I386_SAR, 16, iptr->dst->regoff);
1195 M_INTMOVE(src->regoff, iptr->dst->regoff);
1196 i386_shift_imm_reg(cd, I386_SHL, 16, iptr->dst->regoff);
1197 i386_shift_imm_reg(cd, I386_SAR, 16, iptr->dst->regoff);
1203 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1205 d = reg_of_var(rd, iptr->dst, REG_NULL);
1206 i386_emit_ialu(cd, I386_ADD, src, iptr);
1209 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1210 /* val.i = constant */
1212 d = reg_of_var(rd, iptr->dst, REG_NULL);
1213 i386_emit_ialuconst(cd, I386_ADD, src, iptr);
1216 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1218 d = reg_of_var(rd, iptr->dst, REG_NULL);
1219 if (iptr->dst->flags & INMEMORY) {
1220 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1221 if (src->regoff == iptr->dst->regoff) {
1222 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1223 i386_alu_reg_membase(cd, I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1224 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1225 i386_alu_reg_membase(cd, I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1227 } else if (src->prev->regoff == iptr->dst->regoff) {
1228 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1229 i386_alu_reg_membase(cd, I386_ADD, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1230 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1231 i386_alu_reg_membase(cd, I386_ADC, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1234 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1235 i386_alu_membase_reg(cd, I386_ADD, REG_SP, src->regoff * 8, REG_ITMP1);
1236 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1237 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1238 i386_alu_membase_reg(cd, I386_ADC, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1239 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1246 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1247 /* val.l = constant */
1249 d = reg_of_var(rd, iptr->dst, REG_NULL);
1250 if (iptr->dst->flags & INMEMORY) {
1251 if (src->flags & INMEMORY) {
1252 if (src->regoff == iptr->dst->regoff) {
1253 i386_alu_imm_membase(cd, I386_ADD, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1254 i386_alu_imm_membase(cd, I386_ADC, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1257 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1258 i386_alu_imm_reg(cd, I386_ADD, iptr->val.l, REG_ITMP1);
1259 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1260 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1261 i386_alu_imm_reg(cd, I386_ADC, iptr->val.l >> 32, REG_ITMP1);
1262 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1268 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1270 d = reg_of_var(rd, iptr->dst, REG_NULL);
1271 if (iptr->dst->flags & INMEMORY) {
1272 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1273 if (src->prev->regoff == iptr->dst->regoff) {
1274 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1275 i386_alu_reg_membase(cd, I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1278 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1279 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1280 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1283 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1284 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1285 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1286 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1288 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1289 if (src->prev->regoff == iptr->dst->regoff) {
1290 i386_alu_reg_membase(cd, I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1293 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1294 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1295 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1299 i386_mov_reg_membase(cd, src->prev->regoff, REG_SP, iptr->dst->regoff * 8);
1300 i386_alu_reg_membase(cd, I386_SUB, src->regoff, REG_SP, iptr->dst->regoff * 8);
1304 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1305 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, d);
1306 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, d);
1308 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1309 M_INTMOVE(src->prev->regoff, d);
1310 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, d);
1312 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1313 /* workaround for reg alloc */
1314 if (src->regoff == iptr->dst->regoff) {
1315 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1316 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1317 M_INTMOVE(REG_ITMP1, d);
1320 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, d);
1321 i386_alu_reg_reg(cd, I386_SUB, src->regoff, d);
1325 /* workaround for reg alloc */
1326 if (src->regoff == iptr->dst->regoff) {
1327 M_INTMOVE(src->prev->regoff, REG_ITMP1);
1328 i386_alu_reg_reg(cd, I386_SUB, src->regoff, REG_ITMP1);
1329 M_INTMOVE(REG_ITMP1, d);
1332 M_INTMOVE(src->prev->regoff, d);
1333 i386_alu_reg_reg(cd, I386_SUB, src->regoff, d);
1339 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1340 /* val.i = constant */
1342 d = reg_of_var(rd, iptr->dst, REG_NULL);
1343 i386_emit_ialuconst(cd, I386_SUB, src, iptr);
1346 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1348 d = reg_of_var(rd, iptr->dst, REG_NULL);
1349 if (iptr->dst->flags & INMEMORY) {
1350 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1351 if (src->prev->regoff == iptr->dst->regoff) {
1352 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1353 i386_alu_reg_membase(cd, I386_SUB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1354 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1355 i386_alu_reg_membase(cd, I386_SBB, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1358 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1359 i386_alu_membase_reg(cd, I386_SUB, REG_SP, src->regoff * 8, REG_ITMP1);
1360 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1361 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
1362 i386_alu_membase_reg(cd, I386_SBB, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1363 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1369 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1370 /* val.l = constant */
1372 d = reg_of_var(rd, iptr->dst, REG_NULL);
1373 if (iptr->dst->flags & INMEMORY) {
1374 if (src->flags & INMEMORY) {
1375 if (src->regoff == iptr->dst->regoff) {
1376 i386_alu_imm_membase(cd, I386_SUB, iptr->val.l, REG_SP, iptr->dst->regoff * 8);
1377 i386_alu_imm_membase(cd, I386_SBB, iptr->val.l >> 32, REG_SP, iptr->dst->regoff * 8 + 4);
1380 /* TODO: could be size optimized with lea -- see gcc output */
1381 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1382 i386_alu_imm_reg(cd, I386_SUB, iptr->val.l, REG_ITMP1);
1383 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1384 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
1385 i386_alu_imm_reg(cd, I386_SBB, iptr->val.l >> 32, REG_ITMP1);
1386 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8 + 4);
1392 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1394 d = reg_of_var(rd, iptr->dst, REG_NULL);
1395 if (iptr->dst->flags & INMEMORY) {
1396 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1397 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1398 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1399 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1401 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1402 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1403 i386_imul_reg_reg(cd, src->prev->regoff, REG_ITMP1);
1404 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1406 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1407 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1408 i386_imul_reg_reg(cd, src->regoff, REG_ITMP1);
1409 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1412 i386_mov_reg_reg(cd, src->prev->regoff, REG_ITMP1);
1413 i386_imul_reg_reg(cd, src->regoff, REG_ITMP1);
1414 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1418 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1419 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1420 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1422 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
1423 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1424 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, iptr->dst->regoff);
1426 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1427 M_INTMOVE(src->regoff, iptr->dst->regoff);
1428 i386_imul_membase_reg(cd, REG_SP, src->prev->regoff * 8, iptr->dst->regoff);
1431 if (src->regoff == iptr->dst->regoff) {
1432 i386_imul_reg_reg(cd, src->prev->regoff, iptr->dst->regoff);
1435 M_INTMOVE(src->prev->regoff, iptr->dst->regoff);
1436 i386_imul_reg_reg(cd, src->regoff, iptr->dst->regoff);
1442 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1443 /* val.i = constant */
1445 d = reg_of_var(rd, iptr->dst, REG_NULL);
1446 if (iptr->dst->flags & INMEMORY) {
1447 if (src->flags & INMEMORY) {
1448 i386_imul_imm_membase_reg(cd, iptr->val.i, REG_SP, src->regoff * 8, REG_ITMP1);
1449 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1452 i386_imul_imm_reg_reg(cd, iptr->val.i, src->regoff, REG_ITMP1);
1453 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1457 if (src->flags & INMEMORY) {
1458 i386_imul_imm_membase_reg(cd, iptr->val.i, REG_SP, src->regoff * 8, iptr->dst->regoff);
1461 i386_imul_imm_reg_reg(cd, iptr->val.i, src->regoff, iptr->dst->regoff);
1466 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1468 d = reg_of_var(rd, iptr->dst, REG_NULL);
1469 if (iptr->dst->flags & INMEMORY) {
1470 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
1471 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX); /* mem -> EAX */
1472 /* optimize move EAX -> REG_ITMP3 is slower??? */
1473 /* i386_mov_reg_reg(cd, EAX, REG_ITMP3); */
1474 i386_mul_membase(cd, REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1476 /* TODO: optimize move EAX -> REG_ITMP3 */
1477 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); /* mem -> ITMP3 */
1478 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1479 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1481 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP2); /* mem -> ITMP3 */
1482 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1484 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1485 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1486 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1491 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1492 /* val.l = constant */
1494 d = reg_of_var(rd, iptr->dst, REG_NULL);
1495 if (iptr->dst->flags & INMEMORY) {
1496 if (src->flags & INMEMORY) {
1497 i386_mov_imm_reg(cd, iptr->val.l, EAX); /* imm -> EAX */
1498 i386_mul_membase(cd, REG_SP, src->regoff * 8); /* mem * EAX -> EDX:EAX */
1499 /* TODO: optimize move EAX -> REG_ITMP3 */
1500 i386_mov_imm_reg(cd, iptr->val.l >> 32, REG_ITMP2); /* imm -> ITMP3 */
1501 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1503 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1504 i386_mov_imm_reg(cd, iptr->val.l, REG_ITMP2); /* imm -> ITMP3 */
1505 i386_imul_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); /* mem * ITMP3 -> ITMP3 */
1507 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP2, EDX); /* ITMP3 + EDX -> EDX */
1508 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1509 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8 + 4);
1514 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1516 d = reg_of_var(rd, iptr->dst, REG_NULL);
1517 var_to_reg_int(s1, src, REG_ITMP2);
1519 if (src->prev->flags & INMEMORY) {
1520 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);
1523 M_INTMOVE(src->prev->regoff, EAX);
1526 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1527 i386_jcc(cd, I386_CC_NE, 3 + 6);
1528 i386_alu_imm_reg(cd, I386_CMP, -1, s1);
1529 i386_jcc(cd, I386_CC_E, 1 + 2);
1532 i386_idiv_reg(cd, s1);
1534 if (iptr->dst->flags & INMEMORY) {
1535 i386_mov_reg_membase(cd, EAX, REG_SP, iptr->dst->regoff * 8);
1538 M_INTMOVE(EAX, iptr->dst->regoff);
1542 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1544 d = reg_of_var(rd, iptr->dst, REG_NULL);
1545 var_to_reg_int(s1, src, REG_ITMP2);
1547 if (src->prev->flags & INMEMORY) {
1548 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, EAX);
1551 M_INTMOVE(src->prev->regoff, EAX);
1554 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, EAX); /* check as described in jvm spec */
1555 i386_jcc(cd, I386_CC_NE, 2 + 3 + 6);
1556 i386_alu_reg_reg(cd, I386_XOR, EDX, EDX);
1557 i386_alu_imm_reg(cd, I386_CMP, -1, s1);
1558 i386_jcc(cd, I386_CC_E, 1 + 2);
1561 i386_idiv_reg(cd, s1);
1563 if (iptr->dst->flags & INMEMORY) {
1564 i386_mov_reg_membase(cd, EDX, REG_SP, iptr->dst->regoff * 8);
1567 M_INTMOVE(EDX, iptr->dst->regoff);
1571 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1572 /* val.i = constant */
1574 /* TODO: optimize for `/ 2' */
1575 var_to_reg_int(s1, src, REG_ITMP1);
1576 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
1579 i386_test_reg_reg(cd, d, d);
1581 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1582 i386_jcc(cd, I386_CC_NS, a);
1583 i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.i) - 1, d);
1585 i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, d);
1586 store_reg_to_var_int(iptr->dst, d);
1589 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1590 /* val.i = constant */
1592 d = reg_of_var(rd, iptr->dst, REG_NULL);
1593 if (iptr->dst->flags & INMEMORY) {
1594 if (src->flags & INMEMORY) {
1596 CALCIMMEDIATEBYTES(a, (1 << iptr->val.i) - 1);
1598 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1599 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1601 i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
1602 i386_jcc(cd, I386_CC_NS, a);
1603 i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.i) - 1, REG_ITMP1);
1604 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1605 i386_shrd_imm_reg_reg(cd, iptr->val.i, REG_ITMP2, REG_ITMP1);
1606 i386_shift_imm_reg(cd, I386_SAR, iptr->val.i, REG_ITMP2);
1608 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1609 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1614 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1615 /* val.i = constant */
1617 var_to_reg_int(s1, src, REG_ITMP1);
1618 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1620 M_INTMOVE(s1, REG_ITMP1);
1627 CALCIMMEDIATEBYTES(a, iptr->val.i);
1630 /* TODO: optimize */
1632 i386_alu_imm_reg(cd, I386_AND, iptr->val.i, d);
1633 i386_test_reg_reg(cd, s1, s1);
1634 i386_jcc(cd, I386_CC_GE, a);
1635 i386_mov_reg_reg(cd, s1, d);
1636 i386_neg_reg(cd, d);
1637 i386_alu_imm_reg(cd, I386_AND, iptr->val.i, d);
1638 i386_neg_reg(cd, d);
1640 /* M_INTMOVE(s1, EAX); */
1641 /* i386_cltd(cd); */
1642 /* i386_alu_reg_reg(cd, I386_XOR, EDX, EAX); */
1643 /* i386_alu_reg_reg(cd, I386_SUB, EDX, EAX); */
1644 /* i386_alu_reg_reg(cd, I386_AND, iptr->val.i, EAX); */
1645 /* i386_alu_reg_reg(cd, I386_XOR, EDX, EAX); */
1646 /* i386_alu_reg_reg(cd, I386_SUB, EDX, EAX); */
1647 /* M_INTMOVE(EAX, d); */
1649 /* i386_alu_reg_reg(cd, I386_XOR, d, d); */
1650 /* i386_mov_imm_reg(cd, iptr->val.i, ECX); */
1651 /* i386_shrd_reg_reg(cd, s1, d); */
1652 /* i386_shift_imm_reg(cd, I386_SHR, 32 - iptr->val.i, d); */
1654 store_reg_to_var_int(iptr->dst, d);
1657 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1658 /* val.l = constant */
1660 d = reg_of_var(rd, iptr->dst, REG_NULL);
1661 if (iptr->dst->flags & INMEMORY) {
1662 if (src->flags & INMEMORY) {
1663 /* Intel algorithm -- does not work, because constant is wrong */
1664 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1); */
1665 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP3); */
1667 /* M_INTMOVE(REG_ITMP1, REG_ITMP2); */
1668 /* i386_test_reg_reg(cd, REG_ITMP3, REG_ITMP3); */
1669 /* i386_jcc(cd, I386_CC_NS, offset); */
1670 /* i386_alu_imm_reg(cd, I386_ADD, (1 << iptr->val.l) - 1, REG_ITMP2); */
1671 /* i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP3); */
1673 /* i386_shrd_imm_reg_reg(cd, iptr->val.l, REG_ITMP3, REG_ITMP2); */
1674 /* i386_shift_imm_reg(cd, I386_SAR, iptr->val.l, REG_ITMP3); */
1675 /* i386_shld_imm_reg_reg(cd, iptr->val.l, REG_ITMP2, REG_ITMP3); */
1677 /* i386_shift_imm_reg(cd, I386_SHL, iptr->val.l, REG_ITMP2); */
1679 /* i386_alu_reg_reg(cd, I386_SUB, REG_ITMP2, REG_ITMP1); */
1680 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2); */
1681 /* i386_alu_reg_reg(cd, I386_SBB, REG_ITMP3, REG_ITMP2); */
1683 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1684 /* i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1686 /* Alpha algorithm */
1688 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
1690 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8 + 4);
1696 /* TODO: hmm, don't know if this is always correct */
1698 CALCIMMEDIATEBYTES(a, iptr->val.l & 0x00000000ffffffff);
1700 CALCIMMEDIATEBYTES(a, iptr->val.l >> 32);
1706 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1707 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1709 i386_alu_imm_reg(cd, I386_AND, iptr->val.l, REG_ITMP1);
1710 i386_alu_imm_reg(cd, I386_AND, iptr->val.l >> 32, REG_ITMP2);
1711 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8 + 4);
1712 i386_jcc(cd, I386_CC_GE, a);
1714 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1715 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1717 i386_neg_reg(cd, REG_ITMP1);
1718 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1719 i386_neg_reg(cd, REG_ITMP2);
1721 i386_alu_imm_reg(cd, I386_AND, iptr->val.l, REG_ITMP1);
1722 i386_alu_imm_reg(cd, I386_AND, iptr->val.l >> 32, REG_ITMP2);
1724 i386_neg_reg(cd, REG_ITMP1);
1725 i386_alu_imm_reg(cd, I386_ADC, 0, REG_ITMP2);
1726 i386_neg_reg(cd, REG_ITMP2);
1728 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1729 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1734 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1736 d = reg_of_var(rd, iptr->dst, REG_NULL);
1737 i386_emit_ishift(cd, I386_SHL, src, iptr);
1740 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1741 /* val.i = constant */
1743 d = reg_of_var(rd, iptr->dst, REG_NULL);
1744 i386_emit_ishiftconst(cd, I386_SHL, src, iptr);
1747 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1749 d = reg_of_var(rd, iptr->dst, REG_NULL);
1750 i386_emit_ishift(cd, I386_SAR, src, iptr);
1753 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1754 /* val.i = constant */
1756 d = reg_of_var(rd, iptr->dst, REG_NULL);
1757 i386_emit_ishiftconst(cd, I386_SAR, src, iptr);
1760 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1762 d = reg_of_var(rd, iptr->dst, REG_NULL);
1763 i386_emit_ishift(cd, I386_SHR, src, iptr);
1766 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1767 /* val.i = constant */
1769 d = reg_of_var(rd, iptr->dst, REG_NULL);
1770 i386_emit_ishiftconst(cd, I386_SHR, src, iptr);
1773 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1775 d = reg_of_var(rd, iptr->dst, REG_NULL);
1776 if (iptr->dst->flags & INMEMORY ){
1777 if (src->prev->flags & INMEMORY) {
1778 /* if (src->prev->regoff == iptr->dst->regoff) { */
1779 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1781 /* if (src->flags & INMEMORY) { */
1782 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1784 /* M_INTMOVE(src->regoff, ECX); */
1787 /* i386_test_imm_reg(cd, 32, ECX); */
1788 /* i386_jcc(cd, I386_CC_E, 2 + 2); */
1789 /* i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP2); */
1790 /* i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1); */
1792 /* i386_shld_reg_membase(cd, REG_ITMP1, REG_SP, src->prev->regoff * 8 + 4); */
1793 /* i386_shift_membase(cd, I386_SHL, REG_SP, iptr->dst->regoff * 8); */
1796 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1797 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1799 if (src->flags & INMEMORY) {
1800 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1802 M_INTMOVE(src->regoff, ECX);
1805 i386_test_imm_reg(cd, 32, ECX);
1806 i386_jcc(cd, I386_CC_E, 2 + 2);
1807 i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP3);
1808 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
1810 i386_shld_reg_reg(cd, REG_ITMP1, REG_ITMP3);
1811 i386_shift_reg(cd, I386_SHL, REG_ITMP1);
1812 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1813 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1819 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1820 /* val.i = constant */
1822 d = reg_of_var(rd, iptr->dst, REG_NULL);
1823 if (iptr->dst->flags & INMEMORY ) {
1824 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1825 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1827 if (iptr->val.i & 0x20) {
1828 i386_mov_reg_reg(cd, REG_ITMP1, REG_ITMP2);
1829 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
1830 i386_shld_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1833 i386_shld_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP1, REG_ITMP2);
1834 i386_shift_imm_reg(cd, I386_SHL, iptr->val.i & 0x3f, REG_ITMP1);
1837 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1838 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1842 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1844 d = reg_of_var(rd, iptr->dst, REG_NULL);
1845 if (iptr->dst->flags & INMEMORY ){
1846 if (src->prev->flags & INMEMORY) {
1847 /* if (src->prev->regoff == iptr->dst->regoff) { */
1848 /* TODO: optimize */
1849 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1850 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1852 /* if (src->flags & INMEMORY) { */
1853 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1855 /* M_INTMOVE(src->regoff, ECX); */
1858 /* i386_test_imm_reg(cd, 32, ECX); */
1859 /* i386_jcc(cd, I386_CC_E, 2 + 3); */
1860 /* i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1861 /* i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP2); */
1863 /* i386_shrd_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1864 /* i386_shift_reg(cd, I386_SAR, REG_ITMP2); */
1865 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1866 /* i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1869 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1870 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1872 if (src->flags & INMEMORY) {
1873 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1875 M_INTMOVE(src->regoff, ECX);
1878 i386_test_imm_reg(cd, 32, ECX);
1879 i386_jcc(cd, I386_CC_E, 2 + 3);
1880 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1881 i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP3);
1883 i386_shrd_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1884 i386_shift_reg(cd, I386_SAR, REG_ITMP3);
1885 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1886 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1892 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1893 /* val.i = constant */
1895 d = reg_of_var(rd, iptr->dst, REG_NULL);
1896 if (iptr->dst->flags & INMEMORY ) {
1897 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1898 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1900 if (iptr->val.i & 0x20) {
1901 i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1);
1902 i386_shift_imm_reg(cd, I386_SAR, 31, REG_ITMP2);
1903 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1906 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1907 i386_shift_imm_reg(cd, I386_SAR, iptr->val.i & 0x3f, REG_ITMP2);
1910 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1911 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1915 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1917 d = reg_of_var(rd, iptr->dst, REG_NULL);
1918 if (iptr->dst->flags & INMEMORY ){
1919 if (src->prev->flags & INMEMORY) {
1920 /* if (src->prev->regoff == iptr->dst->regoff) { */
1921 /* TODO: optimize */
1922 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1); */
1923 /* i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2); */
1925 /* if (src->flags & INMEMORY) { */
1926 /* i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX); */
1928 /* M_INTMOVE(src->regoff, ECX); */
1931 /* i386_test_imm_reg(cd, 32, ECX); */
1932 /* i386_jcc(cd, I386_CC_E, 2 + 2); */
1933 /* i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1934 /* i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2); */
1936 /* i386_shrd_reg_reg(cd, REG_ITMP2, REG_ITMP1); */
1937 /* i386_shift_reg(cd, I386_SHR, REG_ITMP2); */
1938 /* i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8); */
1939 /* i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4); */
1942 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
1943 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP3);
1945 if (src->flags & INMEMORY) {
1946 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, ECX);
1948 M_INTMOVE(src->regoff, ECX);
1951 i386_test_imm_reg(cd, 32, ECX);
1952 i386_jcc(cd, I386_CC_E, 2 + 2);
1953 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1954 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP3, REG_ITMP3);
1956 i386_shrd_reg_reg(cd, REG_ITMP3, REG_ITMP1);
1957 i386_shift_reg(cd, I386_SHR, REG_ITMP3);
1958 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1959 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
1965 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1966 /* val.l = constant */
1968 d = reg_of_var(rd, iptr->dst, REG_NULL);
1969 if (iptr->dst->flags & INMEMORY ) {
1970 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
1971 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
1973 if (iptr->val.i & 0x20) {
1974 i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1);
1975 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
1976 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1979 i386_shrd_imm_reg_reg(cd, iptr->val.i & 0x3f, REG_ITMP2, REG_ITMP1);
1980 i386_shift_imm_reg(cd, I386_SHR, iptr->val.i & 0x3f, REG_ITMP2);
1983 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
1984 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
1988 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1990 d = reg_of_var(rd, iptr->dst, REG_NULL);
1991 i386_emit_ialu(cd, I386_AND, src, iptr);
1994 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1995 /* val.i = constant */
1997 d = reg_of_var(rd, iptr->dst, REG_NULL);
1998 i386_emit_ialuconst(cd, I386_AND, src, iptr);
2001 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
2003 d = reg_of_var(rd, iptr->dst, REG_NULL);
2004 i386_emit_lalu(cd, I386_AND, src, iptr);
2007 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
2008 /* val.l = constant */
2010 d = reg_of_var(rd, iptr->dst, REG_NULL);
2011 i386_emit_laluconst(cd, I386_AND, src, iptr);
2014 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2016 d = reg_of_var(rd, iptr->dst, REG_NULL);
2017 i386_emit_ialu(cd, I386_OR, src, iptr);
2020 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
2021 /* val.i = constant */
2023 d = reg_of_var(rd, iptr->dst, REG_NULL);
2024 i386_emit_ialuconst(cd, I386_OR, src, iptr);
2027 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
2029 d = reg_of_var(rd, iptr->dst, REG_NULL);
2030 i386_emit_lalu(cd, I386_OR, src, iptr);
2033 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
2034 /* val.l = constant */
2036 d = reg_of_var(rd, iptr->dst, REG_NULL);
2037 i386_emit_laluconst(cd, I386_OR, src, iptr);
2040 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2042 d = reg_of_var(rd, iptr->dst, REG_NULL);
2043 i386_emit_ialu(cd, I386_XOR, src, iptr);
2046 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
2047 /* val.i = constant */
2049 d = reg_of_var(rd, iptr->dst, REG_NULL);
2050 i386_emit_ialuconst(cd, I386_XOR, src, iptr);
2053 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
2055 d = reg_of_var(rd, iptr->dst, REG_NULL);
2056 i386_emit_lalu(cd, I386_XOR, src, iptr);
2059 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
2060 /* val.l = constant */
2062 d = reg_of_var(rd, iptr->dst, REG_NULL);
2063 i386_emit_laluconst(cd, I386_XOR, src, iptr);
2066 case ICMD_IINC: /* ..., value ==> ..., value + constant */
2067 /* op1 = variable, val.i = constant */
2069 var = &(rd->locals[iptr->op1][TYPE_INT]);
2070 if (var->flags & INMEMORY) {
2071 i386_alu_imm_membase(cd, I386_ADD, iptr->val.i, REG_SP, var->regoff * 8);
2074 /* `inc reg' is slower on p4's (regarding to ia32 */
2075 /* optimization reference manual and benchmarks) and as fast */
2077 i386_alu_imm_reg(cd, I386_ADD, iptr->val.i, var->regoff);
2082 /* floating operations ************************************************/
2084 #define ROUND_TO_SINGLE \
2085 i386_fstps_membase(cd, REG_SP, -8); \
2086 i386_flds_membase(cd, REG_SP, -8);
2088 #define ROUND_TO_DOUBLE \
2089 i386_fstpl_membase(cd, REG_SP, -8); \
2090 i386_fldl_membase(cd, REG_SP, -8);
2092 #define FPU_SET_24BIT_MODE \
2093 if (!fpu_in_24bit_mode) { \
2094 i386_fldcw_mem(cd, &fpu_ctrlwrd_24bit); \
2095 fpu_in_24bit_mode = 1; \
2098 #define FPU_SET_53BIT_MODE \
2099 if (fpu_in_24bit_mode) { \
2100 i386_fldcw_mem(cd, &fpu_ctrlwrd_53bit); \
2101 fpu_in_24bit_mode = 0; \
2104 #define ROUND_TO_SINGLE
2105 #define ROUND_TO_DOUBLE
2106 #define FPU_SET_24BIT_MODE
2107 #define FPU_SET_53BIT_MODE
2109 case ICMD_FNEG: /* ..., value ==> ..., - value */
2112 var_to_reg_flt(s1, src, REG_FTMP1);
2113 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2115 store_reg_to_var_flt(iptr->dst, d);
2118 case ICMD_DNEG: /* ..., value ==> ..., - value */
2121 var_to_reg_flt(s1, src, REG_FTMP1);
2122 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2124 store_reg_to_var_flt(iptr->dst, d);
2127 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2130 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2131 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2132 var_to_reg_flt(s2, src, REG_FTMP2);
2135 store_reg_to_var_flt(iptr->dst, d);
2138 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
2141 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2142 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2143 var_to_reg_flt(s2, src, REG_FTMP2);
2146 store_reg_to_var_flt(iptr->dst, d);
2149 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2152 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2153 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2154 var_to_reg_flt(s2, src, REG_FTMP2);
2157 store_reg_to_var_flt(iptr->dst, d);
2160 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
2163 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2164 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2165 var_to_reg_flt(s2, src, REG_FTMP2);
2168 store_reg_to_var_flt(iptr->dst, d);
2171 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2174 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2175 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2176 var_to_reg_flt(s2, src, REG_FTMP2);
2180 store_reg_to_var_flt(iptr->dst, d);
2183 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
2186 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2187 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2189 /* i386_fldt_mem(cd, subnormal_bias1); */
2190 /* i386_fmulp(cd); */
2192 var_to_reg_flt(s2, src, REG_FTMP2);
2197 /* i386_fldt_mem(cd, subnormal_bias2); */
2198 /* i386_fmulp(cd); */
2200 store_reg_to_var_flt(iptr->dst, d);
2203 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2206 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2207 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2208 var_to_reg_flt(s2, src, REG_FTMP2);
2212 store_reg_to_var_flt(iptr->dst, d);
2215 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
2218 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2219 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2221 /* i386_fldt_mem(cd, subnormal_bias1); */
2222 /* i386_fmulp(cd); */
2224 var_to_reg_flt(s2, src, REG_FTMP2);
2229 /* i386_fldt_mem(cd, subnormal_bias2); */
2230 /* i386_fmulp(cd); */
2232 store_reg_to_var_flt(iptr->dst, d);
2235 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2238 /* exchanged to skip fxch */
2239 var_to_reg_flt(s2, src, REG_FTMP2);
2240 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2241 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2242 /* i386_fxch(cd); */
2247 i386_jcc(cd, I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2248 store_reg_to_var_flt(iptr->dst, d);
2249 i386_ffree_reg(cd, 0);
2254 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
2257 /* exchanged to skip fxch */
2258 var_to_reg_flt(s2, src, REG_FTMP2);
2259 var_to_reg_flt(s1, src->prev, REG_FTMP1);
2260 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2261 /* i386_fxch(cd); */
2266 i386_jcc(cd, I386_CC_P, -(2 + 1 + 2 + 1 + 6));
2267 store_reg_to_var_flt(iptr->dst, d);
2268 i386_ffree_reg(cd, 0);
2273 case ICMD_I2F: /* ..., value ==> ..., (float) value */
2274 case ICMD_I2D: /* ..., value ==> ..., (double) value */
2276 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2277 if (src->flags & INMEMORY) {
2278 i386_fildl_membase(cd, REG_SP, src->regoff * 8);
2282 a = dseg_adds4(cd, 0);
2283 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2284 dseg_adddata(cd, cd->mcodeptr);
2285 i386_mov_reg_membase(cd, src->regoff, REG_ITMP1, a);
2286 i386_fildl_membase(cd, REG_ITMP1, a);
2289 store_reg_to_var_flt(iptr->dst, d);
2292 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2293 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2295 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2296 if (src->flags & INMEMORY) {
2297 i386_fildll_membase(cd, REG_SP, src->regoff * 8);
2301 panic("L2F: longs have to be in memory");
2303 store_reg_to_var_flt(iptr->dst, d);
2306 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2308 var_to_reg_flt(s1, src, REG_FTMP1);
2309 d = reg_of_var(rd, iptr->dst, REG_NULL);
2311 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2312 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2313 dseg_adddata(cd, cd->mcodeptr);
2314 i386_fldcw_membase(cd, REG_ITMP1, a);
2316 if (iptr->dst->flags & INMEMORY) {
2317 i386_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 8);
2320 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2321 i386_fldcw_membase(cd, REG_ITMP1, a);
2323 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2326 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2328 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2331 a = dseg_adds4(cd, 0);
2332 i386_fistpl_membase(cd, REG_ITMP1, a);
2334 i386_mov_membase_reg(cd, REG_ITMP1, a, iptr->dst->regoff);
2336 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2337 i386_fldcw_membase(cd, REG_ITMP1, a);
2339 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, iptr->dst->regoff);
2342 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2343 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2346 i386_jcc(cd, I386_CC_NE, a);
2348 /* XXX: change this when we use registers */
2349 i386_flds_membase(cd, REG_SP, src->regoff * 8);
2350 i386_mov_imm_reg(cd, (s4) asm_builtin_f2i, REG_ITMP1);
2351 i386_call_reg(cd, REG_ITMP1);
2353 if (iptr->dst->flags & INMEMORY) {
2354 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2357 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2361 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2363 var_to_reg_flt(s1, src, REG_FTMP1);
2364 d = reg_of_var(rd, iptr->dst, REG_NULL);
2366 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2367 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2368 dseg_adddata(cd, cd->mcodeptr);
2369 i386_fldcw_membase(cd, REG_ITMP1, a);
2371 if (iptr->dst->flags & INMEMORY) {
2372 i386_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 8);
2375 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2376 i386_fldcw_membase(cd, REG_ITMP1, a);
2378 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8);
2381 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2383 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2386 a = dseg_adds4(cd, 0);
2387 i386_fistpl_membase(cd, REG_ITMP1, a);
2389 i386_mov_membase_reg(cd, REG_ITMP1, a, iptr->dst->regoff);
2391 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2392 i386_fldcw_membase(cd, REG_ITMP1, a);
2394 i386_alu_imm_reg(cd, I386_CMP, 0x80000000, iptr->dst->regoff);
2397 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2398 a += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2401 i386_jcc(cd, I386_CC_NE, a);
2403 /* XXX: change this when we use registers */
2404 i386_fldl_membase(cd, REG_SP, src->regoff * 8);
2405 i386_mov_imm_reg(cd, (s4) asm_builtin_d2i, REG_ITMP1);
2406 i386_call_reg(cd, REG_ITMP1);
2408 if (iptr->dst->flags & INMEMORY) {
2409 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2411 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2415 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2417 var_to_reg_flt(s1, src, REG_FTMP1);
2418 d = reg_of_var(rd, iptr->dst, REG_NULL);
2420 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2421 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2422 dseg_adddata(cd, cd->mcodeptr);
2423 i386_fldcw_membase(cd, REG_ITMP1, a);
2425 if (iptr->dst->flags & INMEMORY) {
2426 i386_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 8);
2429 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2430 i386_fldcw_membase(cd, REG_ITMP1, a);
2432 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2435 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2437 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2440 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2442 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2444 i386_jcc(cd, I386_CC_NE, a);
2446 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2449 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2451 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2453 i386_jcc(cd, I386_CC_NE, a);
2455 /* XXX: change this when we use registers */
2456 i386_flds_membase(cd, REG_SP, src->regoff * 8);
2457 i386_mov_imm_reg(cd, (s4) asm_builtin_f2l, REG_ITMP1);
2458 i386_call_reg(cd, REG_ITMP1);
2459 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2460 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2463 panic("F2L: longs have to be in memory");
2467 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2469 var_to_reg_flt(s1, src, REG_FTMP1);
2470 d = reg_of_var(rd, iptr->dst, REG_NULL);
2472 a = dseg_adds4(cd, 0x0e7f); /* Round to zero, 53-bit mode, exception masked */
2473 i386_mov_imm_reg(cd, 0, REG_ITMP1);
2474 dseg_adddata(cd, cd->mcodeptr);
2475 i386_fldcw_membase(cd, REG_ITMP1, a);
2477 if (iptr->dst->flags & INMEMORY) {
2478 i386_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 8);
2481 a = dseg_adds4(cd, 0x027f); /* Round to nearest, 53-bit mode, exceptions masked */
2482 i386_fldcw_membase(cd, REG_ITMP1, a);
2484 i386_alu_imm_membase(cd, I386_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 8 + 4);
2487 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2489 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2492 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2494 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8 + 4);
2496 i386_jcc(cd, I386_CC_NE, a);
2498 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, iptr->dst->regoff * 8);
2501 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
2503 CALCOFFSETBYTES(a, REG_SP, iptr->dst->regoff * 8);
2505 i386_jcc(cd, I386_CC_NE, a);
2507 /* XXX: change this when we use registers */
2508 i386_fldl_membase(cd, REG_SP, src->regoff * 8);
2509 i386_mov_imm_reg(cd, (s4) asm_builtin_d2l, REG_ITMP1);
2510 i386_call_reg(cd, REG_ITMP1);
2511 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
2512 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
2515 panic("D2L: longs have to be in memory");
2519 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2521 var_to_reg_flt(s1, src, REG_FTMP1);
2522 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2524 store_reg_to_var_flt(iptr->dst, d);
2527 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2529 var_to_reg_flt(s1, src, REG_FTMP1);
2530 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2532 store_reg_to_var_flt(iptr->dst, d);
2535 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2538 /* exchanged to skip fxch */
2539 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2540 var_to_reg_flt(s1, src, REG_FTMP2);
2541 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2542 /* i386_fxch(cd); */
2546 i386_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
2547 i386_jcc(cd, I386_CC_E, 6);
2548 i386_alu_imm_reg(cd, I386_AND, 0x000000ff, EAX);
2550 i386_mov_imm_reg(cd, 0, d); /* does not affect flags */
2551 i386_jcc(cd, I386_CC_E, 6 + 3 + 5 + 3);
2552 i386_jcc(cd, I386_CC_B, 3 + 5);
2553 i386_alu_imm_reg(cd, I386_SUB, 1, d);
2554 i386_jmp_imm(cd, 3);
2555 i386_alu_imm_reg(cd, I386_ADD, 1, d);
2556 store_reg_to_var_int(iptr->dst, d);
2559 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2562 /* exchanged to skip fxch */
2563 var_to_reg_flt(s2, src->prev, REG_FTMP1);
2564 var_to_reg_flt(s1, src, REG_FTMP2);
2565 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2566 /* i386_fxch(cd); */
2570 i386_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
2571 i386_jcc(cd, I386_CC_E, 3);
2572 i386_movb_imm_reg(cd, 1, I386_AH);
2574 i386_mov_imm_reg(cd, 0, d); /* does not affect flags */
2575 i386_jcc(cd, I386_CC_E, 6 + 3 + 5 + 3);
2576 i386_jcc(cd, I386_CC_B, 3 + 5);
2577 i386_alu_imm_reg(cd, I386_SUB, 1, d);
2578 i386_jmp_imm(cd, 3);
2579 i386_alu_imm_reg(cd, I386_ADD, 1, d);
2580 store_reg_to_var_int(iptr->dst, d);
2584 /* memory operations **************************************************/
2586 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2588 var_to_reg_int(s1, src, REG_ITMP1);
2589 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2590 gen_nullptr_check(s1);
2591 i386_mov_membase_reg(cd, s1, OFFSET(java_arrayheader, size), d);
2592 store_reg_to_var_int(iptr->dst, d);
2595 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2597 var_to_reg_int(s1, src->prev, REG_ITMP1);
2598 var_to_reg_int(s2, src, REG_ITMP2);
2599 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2600 if (iptr->op1 == 0) {
2601 gen_nullptr_check(s1);
2604 i386_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2605 store_reg_to_var_int(iptr->dst, d);
2608 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2610 var_to_reg_int(s1, src->prev, REG_ITMP1);
2611 var_to_reg_int(s2, src, REG_ITMP2);
2612 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2613 if (iptr->op1 == 0) {
2614 gen_nullptr_check(s1);
2618 if (iptr->dst->flags & INMEMORY) {
2619 i386_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2620 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8);
2621 i386_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2622 i386_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 8 + 4);
2626 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2628 var_to_reg_int(s1, src->prev, REG_ITMP1);
2629 var_to_reg_int(s2, src, REG_ITMP2);
2630 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2631 if (iptr->op1 == 0) {
2632 gen_nullptr_check(s1);
2635 i386_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2636 store_reg_to_var_int(iptr->dst, d);
2639 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2641 var_to_reg_int(s1, src->prev, REG_ITMP1);
2642 var_to_reg_int(s2, src, REG_ITMP2);
2643 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2644 if (iptr->op1 == 0) {
2645 gen_nullptr_check(s1);
2648 i386_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2650 store_reg_to_var_flt(iptr->dst, d);
2653 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2655 var_to_reg_int(s1, src->prev, REG_ITMP1);
2656 var_to_reg_int(s2, src, REG_ITMP2);
2657 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2658 if (iptr->op1 == 0) {
2659 gen_nullptr_check(s1);
2662 i386_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2664 store_reg_to_var_flt(iptr->dst, d);
2667 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2669 var_to_reg_int(s1, src->prev, REG_ITMP1);
2670 var_to_reg_int(s2, src, REG_ITMP2);
2671 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2672 if (iptr->op1 == 0) {
2673 gen_nullptr_check(s1);
2676 i386_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2677 store_reg_to_var_int(iptr->dst, d);
2680 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2682 var_to_reg_int(s1, src->prev, REG_ITMP1);
2683 var_to_reg_int(s2, src, REG_ITMP2);
2684 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2685 if (iptr->op1 == 0) {
2686 gen_nullptr_check(s1);
2689 i386_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2690 store_reg_to_var_int(iptr->dst, d);
2693 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2695 var_to_reg_int(s1, src->prev, REG_ITMP1);
2696 var_to_reg_int(s2, src, REG_ITMP2);
2697 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2698 if (iptr->op1 == 0) {
2699 gen_nullptr_check(s1);
2702 i386_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2703 store_reg_to_var_int(iptr->dst, d);
2707 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2709 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2710 var_to_reg_int(s2, src->prev, REG_ITMP2);
2711 if (iptr->op1 == 0) {
2712 gen_nullptr_check(s1);
2715 var_to_reg_int(s3, src, REG_ITMP3);
2716 i386_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2719 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2721 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2722 var_to_reg_int(s2, src->prev, REG_ITMP2);
2723 if (iptr->op1 == 0) {
2724 gen_nullptr_check(s1);
2728 if (src->flags & INMEMORY) {
2729 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP3);
2730 i386_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2731 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP3);
2732 i386_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2736 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2738 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2739 var_to_reg_int(s2, src->prev, REG_ITMP2);
2740 if (iptr->op1 == 0) {
2741 gen_nullptr_check(s1);
2744 var_to_reg_int(s3, src, REG_ITMP3);
2745 i386_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2748 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2750 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2751 var_to_reg_int(s2, src->prev, REG_ITMP2);
2752 if (iptr->op1 == 0) {
2753 gen_nullptr_check(s1);
2756 var_to_reg_flt(s3, src, REG_FTMP1);
2757 i386_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2761 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2763 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2764 var_to_reg_int(s2, src->prev, REG_ITMP2);
2765 if (iptr->op1 == 0) {
2766 gen_nullptr_check(s1);
2769 var_to_reg_flt(s3, src, REG_FTMP1);
2770 i386_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2774 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2776 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2777 var_to_reg_int(s2, src->prev, REG_ITMP2);
2778 if (iptr->op1 == 0) {
2779 gen_nullptr_check(s1);
2782 var_to_reg_int(s3, src, REG_ITMP3);
2783 i386_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2786 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2788 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2789 var_to_reg_int(s2, src->prev, REG_ITMP2);
2790 if (iptr->op1 == 0) {
2791 gen_nullptr_check(s1);
2794 var_to_reg_int(s3, src, REG_ITMP3);
2795 i386_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2798 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2800 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
2801 var_to_reg_int(s2, src->prev, REG_ITMP2);
2802 if (iptr->op1 == 0) {
2803 gen_nullptr_check(s1);
2806 var_to_reg_int(s3, src, REG_ITMP3);
2807 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2808 M_INTMOVE(s3, REG_ITMP3);
2811 i386_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2814 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2816 var_to_reg_int(s1, src->prev, REG_ITMP1);
2817 var_to_reg_int(s2, src, REG_ITMP2);
2818 if (iptr->op1 == 0) {
2819 gen_nullptr_check(s1);
2822 i386_mov_imm_memindex(cd, iptr->val.i, OFFSET(java_intarray, data[0]), s1, s2, 2);
2825 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2827 var_to_reg_int(s1, src->prev, REG_ITMP1);
2828 var_to_reg_int(s2, src, REG_ITMP2);
2829 if (iptr->op1 == 0) {
2830 gen_nullptr_check(s1);
2834 i386_mov_imm_memindex(cd, (u4) (iptr->val.l & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2835 i386_mov_imm_memindex(cd, (u4) (iptr->val.l >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2838 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2840 var_to_reg_int(s1, src->prev, REG_ITMP1);
2841 var_to_reg_int(s2, src, REG_ITMP2);
2842 if (iptr->op1 == 0) {
2843 gen_nullptr_check(s1);
2846 i386_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2849 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2851 var_to_reg_int(s1, src->prev, REG_ITMP1);
2852 var_to_reg_int(s2, src, REG_ITMP2);
2853 if (iptr->op1 == 0) {
2854 gen_nullptr_check(s1);
2857 i386_movb_imm_memindex(cd, iptr->val.i, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2860 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2862 var_to_reg_int(s1, src->prev, REG_ITMP1);
2863 var_to_reg_int(s2, src, REG_ITMP2);
2864 if (iptr->op1 == 0) {
2865 gen_nullptr_check(s1);
2868 i386_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_chararray, data[0]), s1, s2, 1);
2871 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2873 var_to_reg_int(s1, src->prev, REG_ITMP1);
2874 var_to_reg_int(s2, src, REG_ITMP2);
2875 if (iptr->op1 == 0) {
2876 gen_nullptr_check(s1);
2879 i386_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2883 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2884 /* op1 = type, val.a = field address */
2886 /* If the static fields' class is not yet initialized, we do it */
2887 /* now. The call code is generated later. */
2888 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2889 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2891 /* This is just for debugging purposes. Is very difficult to */
2892 /* read patched code. Here we patch the following 5 nop's */
2893 /* so that the real code keeps untouched. */
2894 if (showdisassemble) {
2903 a = (u4) &(((fieldinfo *) iptr->val.a)->value);
2904 switch (iptr->op1) {
2907 var_to_reg_int(s2, src, REG_ITMP1);
2908 i386_mov_reg_mem(cd, s2, a);
2911 if (src->flags & INMEMORY) {
2912 /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
2913 /* using REG_ITMP1 alternating. */
2915 i386_mov_membase_reg(cd, REG_SP, s2 * 8, REG_ITMP1);
2916 i386_mov_membase_reg(cd, REG_SP, s2 * 8 + 4, REG_ITMP2);
2917 i386_mov_reg_mem(cd, REG_ITMP1, a);
2918 i386_mov_reg_mem(cd, REG_ITMP2, a + 4);
2920 panic("PUTSTATIC: longs have to be in memory");
2924 var_to_reg_flt(s2, src, REG_FTMP1);
2925 i386_fstps_mem(cd, a);
2929 var_to_reg_flt(s2, src, REG_FTMP1);
2930 i386_fstpl_mem(cd, a);
2934 throw_cacao_exception_exit(string_java_lang_InternalError,
2935 "Unknown PUTSTATIC operand type %d",
2940 case ICMD_GETSTATIC: /* ... ==> ..., value */
2941 /* op1 = type, val.a = field address */
2943 /* If the static fields' class is not yet initialized, we do it */
2944 /* now. The call code is generated later. */
2945 if (!((fieldinfo *) iptr->val.a)->class->initialized) {
2946 codegen_addclinitref(cd, cd->mcodeptr, ((fieldinfo *) iptr->val.a)->class);
2948 /* This is just for debugging purposes. Is very difficult to */
2949 /* read patched code. Here we patch the following 5 nop's */
2950 /* so that the real code keeps untouched. */
2951 if (showdisassemble) {
2960 a = (u4) &(((fieldinfo *) iptr->val.a)->value);
2961 switch (iptr->op1) {
2964 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
2965 i386_mov_mem_reg(cd, a, d);
2966 store_reg_to_var_int(iptr->dst, d);
2969 d = reg_of_var(rd, iptr->dst, REG_NULL);
2970 if (iptr->dst->flags & INMEMORY) {
2971 /* Using both REG_ITMP1 and REG_ITMP2 is faster than only */
2972 /* using REG_ITMP1 alternating. */
2973 i386_mov_mem_reg(cd, a, REG_ITMP1);
2974 i386_mov_mem_reg(cd, a + 4, REG_ITMP2);
2975 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 8);
2976 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
2978 panic("GETSTATIC: longs have to be in memory");
2982 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2983 i386_flds_mem(cd, a);
2985 store_reg_to_var_flt(iptr->dst, d);
2988 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2989 i386_fldl_mem(cd, a);
2991 store_reg_to_var_flt(iptr->dst, d);
2994 throw_cacao_exception_exit(string_java_lang_InternalError,
2995 "Unknown GETSTATIC operand type %d",
3000 case ICMD_PUTFIELD: /* ..., value ==> ... */
3001 /* op1 = type, val.i = field offset */
3003 a = ((fieldinfo *) (iptr->val.a))->offset;
3004 switch (iptr->op1) {
3007 var_to_reg_int(s1, src->prev, REG_ITMP1);
3008 var_to_reg_int(s2, src, REG_ITMP2);
3009 gen_nullptr_check(s1);
3010 i386_mov_reg_membase(cd, s2, s1, a);
3013 var_to_reg_int(s1, src->prev, REG_ITMP1);
3014 gen_nullptr_check(s1);
3015 if (src->flags & INMEMORY) {
3016 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP2);
3017 i386_mov_reg_membase(cd, REG_ITMP2, s1, a);
3018 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3019 i386_mov_reg_membase(cd, REG_ITMP2, s1, a + 4);
3021 panic("PUTFIELD: longs have to be in memory");
3025 var_to_reg_int(s1, src->prev, REG_ITMP1);
3026 var_to_reg_flt(s2, src, REG_FTMP1);
3027 gen_nullptr_check(s1);
3028 i386_fstps_membase(cd, s1, a);
3032 var_to_reg_int(s1, src->prev, REG_ITMP1);
3033 var_to_reg_flt(s2, src, REG_FTMP1);
3034 gen_nullptr_check(s1);
3035 i386_fstpl_membase(cd, s1, a);
3039 throw_cacao_exception_exit(string_java_lang_InternalError,
3040 "Unknown PUTFIELD operand type %d",
3045 case ICMD_GETFIELD: /* ... ==> ..., value */
3046 /* op1 = type, val.i = field offset */
3048 a = ((fieldinfo *) (iptr->val.a))->offset;
3049 switch (iptr->op1) {
3052 var_to_reg_int(s1, src, REG_ITMP1);
3053 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3054 gen_nullptr_check(s1);
3055 i386_mov_membase_reg(cd, s1, a, d);
3056 store_reg_to_var_int(iptr->dst, d);
3059 var_to_reg_int(s1, src, REG_ITMP1);
3060 d = reg_of_var(rd, iptr->dst, REG_NULL);
3061 gen_nullptr_check(s1);
3062 i386_mov_membase_reg(cd, s1, a, REG_ITMP2);
3063 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8);
3064 i386_mov_membase_reg(cd, s1, a + 4, REG_ITMP2);
3065 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 8 + 4);
3068 var_to_reg_int(s1, src, REG_ITMP1);
3069 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3070 gen_nullptr_check(s1);
3071 i386_flds_membase(cd, s1, a);
3073 store_reg_to_var_flt(iptr->dst, d);
3076 var_to_reg_int(s1, src, REG_ITMP1);
3077 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
3078 gen_nullptr_check(s1);
3079 i386_fldl_membase(cd, s1, a);
3081 store_reg_to_var_flt(iptr->dst, d);
3084 throw_cacao_exception_exit(string_java_lang_InternalError,
3085 "Unknown GETFIELD operand type %d",
3091 /* branch operations **************************************************/
3093 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
3095 var_to_reg_int(s1, src, REG_ITMP1);
3096 M_INTMOVE(s1, REG_ITMP1_XPTR);
3098 i386_call_imm(cd, 0); /* passing exception pointer */
3099 i386_pop_reg(cd, REG_ITMP2_XPC);
3101 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
3102 i386_jmp_reg(cd, REG_ITMP3);
3106 case ICMD_GOTO: /* ... ==> ... */
3107 /* op1 = target JavaVM pc */
3109 i386_jmp_imm(cd, 0);
3110 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3114 case ICMD_JSR: /* ... ==> ... */
3115 /* op1 = target JavaVM pc */
3117 i386_call_imm(cd, 0);
3118 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3121 case ICMD_RET: /* ... ==> ... */
3122 /* op1 = local variable */
3124 var = &(rd->locals[iptr->op1][TYPE_ADR]);
3125 var_to_reg_int(s1, var, REG_ITMP1);
3126 i386_jmp_reg(cd, s1);
3129 case ICMD_IFNULL: /* ..., value ==> ... */
3130 /* op1 = target JavaVM pc */
3132 if (src->flags & INMEMORY) {
3133 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
3136 i386_test_reg_reg(cd, src->regoff, src->regoff);
3138 i386_jcc(cd, I386_CC_E, 0);
3139 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3142 case ICMD_IFNONNULL: /* ..., value ==> ... */
3143 /* op1 = target JavaVM pc */
3145 if (src->flags & INMEMORY) {
3146 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
3149 i386_test_reg_reg(cd, src->regoff, src->regoff);
3151 i386_jcc(cd, I386_CC_NE, 0);
3152 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3155 case ICMD_IFEQ: /* ..., value ==> ... */
3156 /* op1 = target JavaVM pc, val.i = constant */
3158 if (src->flags & INMEMORY) {
3159 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3162 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3164 i386_jcc(cd, I386_CC_E, 0);
3165 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3168 case ICMD_IFLT: /* ..., value ==> ... */
3169 /* op1 = target JavaVM pc, val.i = constant */
3171 if (src->flags & INMEMORY) {
3172 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3175 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3177 i386_jcc(cd, I386_CC_L, 0);
3178 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3181 case ICMD_IFLE: /* ..., value ==> ... */
3182 /* op1 = target JavaVM pc, val.i = constant */
3184 if (src->flags & INMEMORY) {
3185 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3188 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3190 i386_jcc(cd, I386_CC_LE, 0);
3191 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3194 case ICMD_IFNE: /* ..., value ==> ... */
3195 /* op1 = target JavaVM pc, val.i = constant */
3197 if (src->flags & INMEMORY) {
3198 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3201 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3203 i386_jcc(cd, I386_CC_NE, 0);
3204 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3207 case ICMD_IFGT: /* ..., value ==> ... */
3208 /* op1 = target JavaVM pc, val.i = constant */
3210 if (src->flags & INMEMORY) {
3211 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3214 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3216 i386_jcc(cd, I386_CC_G, 0);
3217 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3220 case ICMD_IFGE: /* ..., value ==> ... */
3221 /* op1 = target JavaVM pc, val.i = constant */
3223 if (src->flags & INMEMORY) {
3224 i386_alu_imm_membase(cd, I386_CMP, iptr->val.i, REG_SP, src->regoff * 8);
3227 i386_alu_imm_reg(cd, I386_CMP, iptr->val.i, src->regoff);
3229 i386_jcc(cd, I386_CC_GE, 0);
3230 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3233 case ICMD_IF_LEQ: /* ..., value ==> ... */
3234 /* op1 = target JavaVM pc, val.l = constant */
3236 if (src->flags & INMEMORY) {
3237 if (iptr->val.l == 0) {
3238 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3239 i386_alu_membase_reg(cd, I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3242 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3243 i386_alu_imm_reg(cd, I386_XOR, iptr->val.l >> 32, REG_ITMP2);
3244 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3245 i386_alu_imm_reg(cd, I386_XOR, iptr->val.l, REG_ITMP1);
3246 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3249 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3250 i386_jcc(cd, I386_CC_E, 0);
3251 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3254 case ICMD_IF_LLT: /* ..., value ==> ... */
3255 /* op1 = target JavaVM pc, val.l = constant */
3257 if (src->flags & INMEMORY) {
3258 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3259 i386_jcc(cd, I386_CC_L, 0);
3260 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3263 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3264 CALCIMMEDIATEBYTES(a, iptr->val.l);
3266 i386_jcc(cd, I386_CC_G, a);
3268 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3269 i386_jcc(cd, I386_CC_B, 0);
3270 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3274 case ICMD_IF_LLE: /* ..., value ==> ... */
3275 /* op1 = target JavaVM pc, val.l = constant */
3277 if (src->flags & INMEMORY) {
3278 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3279 i386_jcc(cd, I386_CC_L, 0);
3280 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3283 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3284 CALCIMMEDIATEBYTES(a, iptr->val.l);
3286 i386_jcc(cd, I386_CC_G, a);
3288 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3289 i386_jcc(cd, I386_CC_BE, 0);
3290 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3294 case ICMD_IF_LNE: /* ..., value ==> ... */
3295 /* op1 = target JavaVM pc, val.l = constant */
3297 if (src->flags & INMEMORY) {
3298 if (iptr->val.l == 0) {
3299 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3300 i386_alu_membase_reg(cd, I386_OR, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3303 i386_mov_imm_reg(cd, iptr->val.l, REG_ITMP1);
3304 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3305 i386_mov_imm_reg(cd, iptr->val.l >> 32, REG_ITMP2);
3306 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3307 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3310 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3311 i386_jcc(cd, I386_CC_NE, 0);
3312 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3315 case ICMD_IF_LGT: /* ..., value ==> ... */
3316 /* op1 = target JavaVM pc, val.l = constant */
3318 if (src->flags & INMEMORY) {
3319 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3320 i386_jcc(cd, I386_CC_G, 0);
3321 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3324 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3325 CALCIMMEDIATEBYTES(a, iptr->val.l);
3327 i386_jcc(cd, I386_CC_L, a);
3329 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3330 i386_jcc(cd, I386_CC_A, 0);
3331 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3335 case ICMD_IF_LGE: /* ..., value ==> ... */
3336 /* op1 = target JavaVM pc, val.l = constant */
3338 if (src->flags & INMEMORY) {
3339 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l >> 32, REG_SP, src->regoff * 8 + 4);
3340 i386_jcc(cd, I386_CC_G, 0);
3341 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3344 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3345 CALCIMMEDIATEBYTES(a, iptr->val.l);
3347 i386_jcc(cd, I386_CC_L, a);
3349 i386_alu_imm_membase(cd, I386_CMP, iptr->val.l, REG_SP, src->regoff * 8);
3350 i386_jcc(cd, I386_CC_AE, 0);
3351 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3355 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3356 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3358 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3359 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3360 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3362 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3363 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3365 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3366 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3369 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3371 i386_jcc(cd, I386_CC_E, 0);
3372 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3375 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3376 /* op1 = target JavaVM pc */
3378 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3379 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3380 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3381 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3382 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3383 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3384 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3386 i386_jcc(cd, I386_CC_E, 0);
3387 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3390 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3391 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3393 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3394 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3395 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3397 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3398 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3400 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3401 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3404 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3406 i386_jcc(cd, I386_CC_NE, 0);
3407 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3410 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3411 /* op1 = target JavaVM pc */
3413 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3414 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3415 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP2);
3416 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8, REG_ITMP1);
3417 i386_alu_membase_reg(cd, I386_XOR, REG_SP, src->regoff * 8 + 4, REG_ITMP2);
3418 i386_alu_reg_reg(cd, I386_OR, REG_ITMP2, REG_ITMP1);
3419 i386_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3421 i386_jcc(cd, I386_CC_NE, 0);
3422 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3425 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3426 /* op1 = target JavaVM pc */
3428 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3429 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3430 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3432 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3433 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3435 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3436 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3439 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3441 i386_jcc(cd, I386_CC_L, 0);
3442 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3445 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3446 /* op1 = target JavaVM pc */
3448 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3449 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3450 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3451 i386_jcc(cd, I386_CC_L, 0);
3452 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3455 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3456 CALCOFFSETBYTES(a, REG_SP, src->regoff);
3458 i386_jcc(cd, I386_CC_G, a);
3460 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3461 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3462 i386_jcc(cd, I386_CC_B, 0);
3463 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3467 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3468 /* op1 = target JavaVM pc */
3470 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3471 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3472 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3474 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3475 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3477 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3478 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3481 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3483 i386_jcc(cd, I386_CC_G, 0);
3484 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3487 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3488 /* op1 = target JavaVM pc */
3490 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3491 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3492 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3493 i386_jcc(cd, I386_CC_G, 0);
3494 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3497 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3498 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3500 i386_jcc(cd, I386_CC_L, a);
3502 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3503 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3504 i386_jcc(cd, I386_CC_A, 0);
3505 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3509 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3510 /* op1 = target JavaVM pc */
3512 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3513 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3514 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3516 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3517 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3519 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3520 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3523 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3525 i386_jcc(cd, I386_CC_LE, 0);
3526 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3529 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3530 /* op1 = target JavaVM pc */
3532 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3533 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3534 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3535 i386_jcc(cd, I386_CC_L, 0);
3536 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3539 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3540 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3542 i386_jcc(cd, I386_CC_G, a);
3544 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3545 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3546 i386_jcc(cd, I386_CC_BE, 0);
3547 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3551 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3552 /* op1 = target JavaVM pc */
3554 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3555 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3556 i386_alu_reg_membase(cd, I386_CMP, REG_ITMP1, REG_SP, src->prev->regoff * 8);
3558 } else if ((src->flags & INMEMORY) && !(src->prev->flags & INMEMORY)) {
3559 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, src->prev->regoff);
3561 } else if (!(src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3562 i386_alu_reg_membase(cd, I386_CMP, src->regoff, REG_SP, src->prev->regoff * 8);
3565 i386_alu_reg_reg(cd, I386_CMP, src->regoff, src->prev->regoff);
3567 i386_jcc(cd, I386_CC_GE, 0);
3568 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3571 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3572 /* op1 = target JavaVM pc */
3574 if ((src->flags & INMEMORY) && (src->prev->flags & INMEMORY)) {
3575 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8 + 4, REG_ITMP1);
3576 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8 + 4, REG_ITMP1);
3577 i386_jcc(cd, I386_CC_G, 0);
3578 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3581 CALCOFFSETBYTES(a, REG_SP, src->prev->regoff * 8);
3582 CALCOFFSETBYTES(a, REG_SP, src->regoff * 8);
3584 i386_jcc(cd, I386_CC_L, a);
3586 i386_mov_membase_reg(cd, REG_SP, src->prev->regoff * 8, REG_ITMP1);
3587 i386_alu_membase_reg(cd, I386_CMP, REG_SP, src->regoff * 8, REG_ITMP1);
3588 i386_jcc(cd, I386_CC_AE, 0);
3589 codegen_addreference(cd, BlockPtrOfPC(iptr->op1), cd->mcodeptr);
3593 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
3595 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
3598 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
3599 /* val.i = constant */
3601 d = reg_of_var(rd, iptr->dst, REG_NULL);
3602 i386_emit_ifcc_iconst(cd, I386_CC_NE, src, iptr);
3605 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
3606 /* val.i = constant */
3608 d = reg_of_var(rd, iptr->dst, REG_NULL);
3609 i386_emit_ifcc_iconst(cd, I386_CC_E, src, iptr);
3612 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
3613 /* val.i = constant */
3615 d = reg_of_var(rd, iptr->dst, REG_NULL);
3616 i386_emit_ifcc_iconst(cd, I386_CC_GE, src, iptr);
3619 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
3620 /* val.i = constant */
3622 d = reg_of_var(rd, iptr->dst, REG_NULL);
3623 i386_emit_ifcc_iconst(cd, I386_CC_L, src, iptr);
3626 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
3627 /* val.i = constant */
3629 d = reg_of_var(rd, iptr->dst, REG_NULL);
3630 i386_emit_ifcc_iconst(cd, I386_CC_LE, src, iptr);
3633 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
3634 /* val.i = constant */
3636 d = reg_of_var(rd, iptr->dst, REG_NULL);
3637 i386_emit_ifcc_iconst(cd, I386_CC_G, src, iptr);
3641 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3644 var_to_reg_int(s1, src, REG_RESULT);
3645 M_INTMOVE(s1, REG_RESULT);
3647 goto nowperformreturn;
3649 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3651 if (src->flags & INMEMORY) {
3652 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_RESULT);
3653 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8 + 4, REG_RESULT2);
3656 panic("LRETURN: longs have to be in memory");
3659 goto nowperformreturn;
3661 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3662 case ICMD_DRETURN: /* ..., retvalue ==> ... */
3664 var_to_reg_flt(s1, src, REG_FRESULT);
3665 /* this may be an early return -- keep the offset correct for the
3669 goto nowperformreturn;
3671 case ICMD_RETURN: /* ... ==> ... */
3677 p = parentargs_base;
3679 /* call trace function */
3681 i386_alu_imm_reg(cd, I386_SUB, 4 + 8 + 8 + 4, REG_SP);
3683 i386_mov_imm_membase(cd, (s4) m, REG_SP, 0);
3685 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
3686 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
3688 i386_fstl_membase(cd, REG_SP, 4 + 8);
3689 i386_fsts_membase(cd, REG_SP, 4 + 8 + 8);
3691 i386_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
3692 i386_call_reg(cd, REG_ITMP1);
3694 i386_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
3695 i386_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
3697 i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
3700 #if defined(USE_THREADS)
3701 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3702 i386_mov_membase_reg(cd, REG_SP, 8 * rd->maxmemuse, REG_ITMP2);
3704 /* we need to save the proper return value */
3705 switch (iptr->opc) {
3708 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, rd->maxmemuse * 8);
3712 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, rd->maxmemuse * 8);
3713 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, rd->maxmemuse * 8 + 4);
3717 i386_fsts_membase(cd, REG_SP, rd->maxmemuse * 8);
3721 i386_fstl_membase(cd, REG_SP, rd->maxmemuse * 8);
3725 i386_alu_imm_reg(cd, I386_SUB, 4, REG_SP);
3726 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, 0);
3727 i386_mov_imm_reg(cd, (s4) builtin_monitorexit, REG_ITMP1);
3728 i386_call_reg(cd, REG_ITMP1);
3729 i386_alu_imm_reg(cd, I386_ADD, 4, REG_SP);
3731 /* and now restore the proper return value */
3732 switch (iptr->opc) {
3735 i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8, REG_RESULT);
3739 i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8, REG_RESULT);
3740 i386_mov_membase_reg(cd, REG_SP, rd->maxmemuse * 8 + 4, REG_RESULT2);
3744 i386_flds_membase(cd, REG_SP, rd->maxmemuse * 8);
3748 i386_fldl_membase(cd, REG_SP, rd->maxmemuse * 8);
3754 /* restore saved registers */
3755 for (i = rd->savintregcnt - 1; i >= rd->maxsavintreguse; i--) {
3757 i386_mov_membase_reg(cd, REG_SP, p * 8, rd->savintregs[i]);
3759 for (i = rd->savfltregcnt - 1; i >= rd->maxsavfltreguse; i--) {
3761 i386_fldl_membase(cd, REG_SP, p * 8);
3763 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3764 i386_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1);
3766 i386_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset);
3771 /* deallocate stack */
3772 if (parentargs_base) {
3773 i386_alu_imm_reg(cd, I386_ADD, parentargs_base * 8, REG_SP);
3782 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3787 tptr = (void **) iptr->target;
3789 s4ptr = iptr->val.a;
3790 l = s4ptr[1]; /* low */
3791 i = s4ptr[2]; /* high */
3793 var_to_reg_int(s1, src, REG_ITMP1);
3794 M_INTMOVE(s1, REG_ITMP1);
3796 i386_alu_imm_reg(cd, I386_SUB, l, REG_ITMP1);
3802 i386_alu_imm_reg(cd, I386_CMP, i - 1, REG_ITMP1);
3803 i386_jcc(cd, I386_CC_A, 0);
3805 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), cd->mcodeptr); */
3806 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3808 /* build jump table top down and use address of lowest entry */
3810 /* s4ptr += 3 + i; */
3814 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3815 dseg_addtarget(cd, (basicblock *) tptr[0]);
3819 /* length of dataseg after last dseg_addtarget is used by load */
3821 i386_mov_imm_reg(cd, 0, REG_ITMP2);
3822 dseg_adddata(cd, cd->mcodeptr);
3823 i386_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3824 i386_jmp_reg(cd, REG_ITMP1);
3830 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3832 s4 i, l, val, *s4ptr;
3835 tptr = (void **) iptr->target;
3837 s4ptr = iptr->val.a;
3838 l = s4ptr[0]; /* default */
3839 i = s4ptr[1]; /* count */
3841 MCODECHECK((i<<2)+8);
3842 var_to_reg_int(s1, src, REG_ITMP1); /* reg compare should always be faster */
3848 i386_alu_imm_reg(cd, I386_CMP, val, s1);
3849 i386_jcc(cd, I386_CC_E, 0);
3850 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), cd->mcodeptr); */
3851 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3854 i386_jmp_imm(cd, 0);
3855 /* codegen_addreference(cd, BlockPtrOfPC(l), cd->mcodeptr); */
3857 tptr = (void **) iptr->target;
3858 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
3865 case ICMD_BUILTIN3: /* ..., arg1, arg2, arg3 ==> ... */
3866 /* op1 = return type, val.a = function pointer*/
3870 case ICMD_BUILTIN2: /* ..., arg1, arg2 ==> ... */
3871 /* op1 = return type, val.a = function pointer*/
3875 case ICMD_BUILTIN1: /* ..., arg1 ==> ... */
3876 /* op1 = return type, val.a = function pointer*/
3880 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3881 /* op1 = arg count, val.a = method pointer */
3883 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3884 /* op1 = arg count, val.a = method pointer */
3886 case ICMD_INVOKEVIRTUAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3887 /* op1 = arg count, val.a = method pointer */
3889 case ICMD_INVOKEINTERFACE:/*.., objectref, [arg1, [arg2 ...]] ==> ... */
3890 /* op1 = arg count, val.a = method pointer */
3897 MCODECHECK((s3 << 1) + 64);
3899 /* copy arguments to registers or stack location */
3901 for (; --s3 >= 0; src = src->prev) {
3902 if (src->varkind == ARGVAR) {
3906 if (IS_INT_LNG_TYPE(src->type)) {
3907 if (s3 < rd->intreg_argnum) {
3908 panic("No integer argument registers available!");
3911 if (!IS_2_WORD_TYPE(src->type)) {
3912 if (src->flags & INMEMORY) {
3913 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
3914 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, s3 * 8);
3917 i386_mov_reg_membase(cd, src->regoff, REG_SP, s3 * 8);
3921 if (src->flags & INMEMORY) {
3922 M_LNGMEMMOVE(src->regoff, s3);
3925 panic("copy arguments: longs have to be in memory");
3931 if (s3 < rd->fltreg_argnum) {
3932 panic("No float argument registers available!");
3935 var_to_reg_flt(d, src, REG_FTMP1);
3936 if (src->type == TYPE_FLT) {
3937 i386_fstps_membase(cd, REG_SP, s3 * 8);
3940 i386_fstpl_membase(cd, REG_SP, s3 * 8);
3947 switch (iptr->opc) {
3954 i386_mov_imm_reg(cd, a, REG_ITMP1);
3955 i386_call_reg(cd, REG_ITMP1);
3958 case ICMD_INVOKESTATIC:
3959 a = (u4) lm->stubroutine;
3962 i386_mov_imm_reg(cd, a, REG_ITMP2);
3963 i386_call_reg(cd, REG_ITMP2);
3966 case ICMD_INVOKESPECIAL:
3967 a = (u4) lm->stubroutine;
3970 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3971 gen_nullptr_check(REG_ITMP1);
3972 i386_mov_membase_reg(cd, REG_ITMP1, 0, REG_ITMP1); /* access memory for hardware nullptr */
3974 i386_mov_imm_reg(cd, a, REG_ITMP2);
3975 i386_call_reg(cd, REG_ITMP2);
3978 case ICMD_INVOKEVIRTUAL:
3981 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3982 gen_nullptr_check(REG_ITMP1);
3983 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP2);
3984 i386_mov_membase32_reg(cd, REG_ITMP2, OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex, REG_ITMP1);
3986 i386_call_reg(cd, REG_ITMP1);
3989 case ICMD_INVOKEINTERFACE:
3992 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP1);
3993 gen_nullptr_check(REG_ITMP1);
3994 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
3995 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr) * lm->class->index, REG_ITMP2);
3996 i386_mov_membase32_reg(cd, REG_ITMP2, sizeof(methodptr) * (lm - lm->class->methods), REG_ITMP1);
3998 i386_call_reg(cd, REG_ITMP1);
4002 /* d contains return type */
4004 if (d != TYPE_VOID) {
4005 d = reg_of_var(rd, iptr->dst, REG_NULL);
4007 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
4008 if (IS_2_WORD_TYPE(iptr->dst->type)) {
4009 if (iptr->dst->flags & INMEMORY) {
4010 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4011 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 8 + 4);
4014 panic("RETURN: longs have to be in memory");
4018 if (iptr->dst->flags & INMEMORY) {
4019 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 8);
4022 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
4027 /* fld from called function -- has other fpu_st_offset counter */
4029 store_reg_to_var_flt(iptr->dst, d);
4036 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
4038 /* op1: 0 == array, 1 == class */
4039 /* val.a: (classinfo*) superclass */
4041 /* superclass is an interface:
4043 * return (sub != NULL) &&
4044 * (sub->vftbl->interfacetablelength > super->index) &&
4045 * (sub->vftbl->interfacetable[-super->index] != NULL);
4047 * superclass is a class:
4049 * return ((sub != NULL) && (0
4050 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4051 * super->vftbl->diffvall));
4055 classinfo *super = (classinfo*) iptr->val.a;
4057 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4058 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
4060 var_to_reg_int(s1, src, REG_ITMP1);
4061 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
4063 M_INTMOVE(s1, REG_ITMP1);
4066 i386_alu_reg_reg(cd, I386_XOR, d, d);
4067 if (iptr->op1) { /* class/interface */
4068 if (super->flags & ACC_INTERFACE) { /* interface */
4069 i386_test_reg_reg(cd, s1, s1);
4071 /* TODO: clean up this calculation */
4073 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4076 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
4079 /* CALCOFFSETBYTES(a, super->index); */
4080 CALCIMMEDIATEBYTES(a, super->index);
4086 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4093 i386_jcc(cd, I386_CC_E, a);
4095 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4096 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength), REG_ITMP2);
4097 i386_alu_imm_reg(cd, I386_SUB, super->index, REG_ITMP2);
4099 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4101 /* TODO: clean up this calculation */
4104 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4111 i386_jcc(cd, I386_CC_LE, a);
4112 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP1);
4114 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP1);
4115 /* i386_setcc_reg(cd, I386_CC_A, d); */
4116 /* i386_jcc(cd, I386_CC_BE, 5); */
4117 i386_jcc(cd, I386_CC_E, 5);
4118 i386_mov_imm_reg(cd, 1, d);
4121 } else { /* class */
4122 i386_test_reg_reg(cd, s1, s1);
4124 /* TODO: clean up this calculation */
4126 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4129 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, baseval));
4131 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4134 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4144 i386_jcc(cd, I386_CC_E, a);
4146 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4147 i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4148 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4149 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4151 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, baseval), REG_ITMP1);
4152 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP3);
4153 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4154 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4155 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4157 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP3, REG_ITMP1);
4158 i386_alu_reg_reg(cd, I386_XOR, d, d);
4160 i386_alu_reg_reg(cd, I386_CMP, REG_ITMP2, REG_ITMP1);
4161 i386_jcc(cd, I386_CC_A, 5);
4162 i386_mov_imm_reg(cd, 1, d);
4166 panic ("internal error: no inlined array instanceof");
4168 store_reg_to_var_int(iptr->dst, d);
4171 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
4173 /* op1: 0 == array, 1 == class */
4174 /* val.a: (classinfo*) superclass */
4176 /* superclass is an interface:
4178 * OK if ((sub == NULL) ||
4179 * (sub->vftbl->interfacetablelength > super->index) &&
4180 * (sub->vftbl->interfacetable[-super->index] != NULL));
4182 * superclass is a class:
4184 * OK if ((sub == NULL) || (0
4185 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
4186 * super->vftbl->diffvall));
4190 classinfo *super = (classinfo*) iptr->val.a;
4192 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4193 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
4195 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
4196 var_to_reg_int(s1, src, d);
4197 if (iptr->op1) { /* class/interface */
4198 if (super->flags & ACC_INTERFACE) { /* interface */
4199 i386_test_reg_reg(cd, s1, s1);
4201 /* TODO: clean up this calculation */
4203 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4206 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
4209 /* CALCOFFSETBYTES(a, super->index); */
4210 CALCIMMEDIATEBYTES(a, super->index);
4216 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*));
4221 i386_jcc(cd, I386_CC_E, a);
4223 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4224 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength), REG_ITMP2);
4225 i386_alu_imm_reg(cd, I386_SUB, super->index, REG_ITMP2);
4227 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4228 i386_jcc(cd, I386_CC_LE, 0);
4229 codegen_addxcastrefs(cd, cd->mcodeptr);
4230 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, interfacetable[0]) - super->index * sizeof(methodptr*), REG_ITMP2);
4232 i386_alu_imm_reg(cd, I386_CMP, 0, REG_ITMP2);
4233 i386_jcc(cd, I386_CC_E, 0);
4234 codegen_addxcastrefs(cd, cd->mcodeptr);
4236 } else { /* class */
4237 i386_test_reg_reg(cd, s1, s1);
4239 /* TODO: clean up this calculation */
4241 CALCOFFSETBYTES(a, s1, OFFSET(java_objectheader, vftbl));
4246 CALCOFFSETBYTES(a, REG_ITMP1, OFFSET(vftbl_t, baseval));
4248 if (d != REG_ITMP3) {
4250 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4253 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4259 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, baseval));
4266 CALCOFFSETBYTES(a, REG_ITMP2, OFFSET(vftbl_t, diffval));
4273 i386_jcc(cd, I386_CC_E, a);
4275 i386_mov_membase_reg(cd, s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
4276 i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4277 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4278 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4280 i386_mov_membase_reg(cd, REG_ITMP1, OFFSET(vftbl_t, baseval), REG_ITMP1);
4281 if (d != REG_ITMP3) {
4282 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP3);
4283 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4284 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4285 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4287 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP3, REG_ITMP1);
4290 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, baseval), REG_ITMP2);
4291 i386_alu_reg_reg(cd, I386_SUB, REG_ITMP2, REG_ITMP1);
4292 i386_mov_imm_reg(cd, (s4) super->vftbl, REG_ITMP2);
4293 i386_mov_membase_reg(cd, REG_ITMP2, OFFSET(vftbl_t, diffval), REG_ITMP2);
4294 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4295 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4299 i386_alu_reg_reg(cd, I386_CMP, REG_ITMP2, REG_ITMP1);
4300 i386_jcc(cd, I386_CC_A, 0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
4301 codegen_addxcastrefs(cd, cd->mcodeptr);
4305 panic ("internal error: no inlined array checkcast");
4308 store_reg_to_var_int(iptr->dst, d);
4311 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
4313 if (src->flags & INMEMORY) {
4314 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
4317 i386_test_reg_reg(cd, src->regoff, src->regoff);
4319 i386_jcc(cd, I386_CC_L, 0);
4320 codegen_addxcheckarefs(cd, cd->mcodeptr);
4323 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
4325 i386_test_reg_reg(cd, REG_RESULT, REG_RESULT);
4326 i386_jcc(cd, I386_CC_E, 0);
4327 codegen_addxexceptionrefs(cd, cd->mcodeptr);
4330 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4331 /* op1 = dimension, val.a = array descriptor */
4333 /* check for negative sizes and copy sizes to stack if necessary */
4335 MCODECHECK((iptr->op1 << 1) + 64);
4337 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4338 if (src->flags & INMEMORY) {
4339 i386_alu_imm_membase(cd, I386_CMP, 0, REG_SP, src->regoff * 8);
4342 i386_test_reg_reg(cd, src->regoff, src->regoff);
4344 i386_jcc(cd, I386_CC_L, 0);
4345 codegen_addxcheckarefs(cd, cd->mcodeptr);
4348 * copy sizes to new stack location, be cause native function
4349 * builtin_nmultianewarray access them as (int *)
4351 i386_mov_membase_reg(cd, REG_SP, src->regoff * 8, REG_ITMP1);
4352 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, -(iptr->op1 - s1) * 4);
4354 /* copy sizes to stack (argument numbers >= INT_ARG_CNT) */
4356 if (src->varkind != ARGVAR) {
4357 if (src->flags & INMEMORY) {
4358 i386_mov_membase_reg(cd, REG_SP, (src->regoff + INT_ARG_CNT) * 8, REG_ITMP1);
4359 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, (s1 + INT_ARG_CNT) * 8);
4362 i386_mov_reg_membase(cd, src->regoff, REG_SP, (s1 + INT_ARG_CNT) * 8);
4366 i386_alu_imm_reg(cd, I386_SUB, iptr->op1 * 4, REG_SP);
4368 /* a0 = dimension count */
4370 /* save stack pointer */
4371 M_INTMOVE(REG_SP, REG_ITMP1);
4373 i386_alu_imm_reg(cd, I386_SUB, 12, REG_SP);
4374 i386_mov_imm_membase(cd, iptr->op1, REG_SP, 0);
4376 /* a1 = arraydescriptor */
4378 i386_mov_imm_membase(cd, (s4) iptr->val.a, REG_SP, 4);
4380 /* a2 = pointer to dimensions = stack pointer */
4382 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 8);
4384 i386_mov_imm_reg(cd, (s4) (builtin_nmultianewarray), REG_ITMP1);
4385 i386_call_reg(cd, REG_ITMP1);
4386 i386_alu_imm_reg(cd, I386_ADD, 12 + iptr->op1 * 4, REG_SP);
4388 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
4389 M_INTMOVE(REG_RESULT, s1);
4390 store_reg_to_var_int(iptr->dst, s1);
4393 case ICMD_INLINE_START:
4394 case ICMD_INLINE_END:
4397 error ("Unknown pseudo command: %d", iptr->opc);
4400 } /* for instruction */
4402 /* copy values to interface registers */
4404 src = bptr->outstack;
4405 len = bptr->outdepth;
4412 if ((src->varkind != STACKVAR)) {
4414 if (IS_FLT_DBL_TYPE(s2)) {
4415 var_to_reg_flt(s1, src, REG_FTMP1);
4416 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4417 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4420 panic("double store");
4421 /* M_DST(s1, REG_SP, 8 * interfaces[len][s2].regoff); */
4425 var_to_reg_int(s1, src, REG_ITMP1);
4426 if (!IS_2_WORD_TYPE(rd->interfaces[len][s2].type)) {
4427 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4428 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4431 i386_mov_reg_membase(cd, s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
4435 if (rd->interfaces[len][s2].flags & INMEMORY) {
4436 M_LNGMEMMOVE(s1, rd->interfaces[len][s2].regoff);
4439 panic("copy interface registers: longs have to be in memory (end)");
4446 } /* if (bptr -> flags >= BBREACHED) */
4447 } /* for basic block */
4449 codegen_createlinenumbertable(cd);
4453 /* generate bound check stubs */
4455 u1 *xcodeptr = NULL;
4458 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
4459 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4461 cd->mcodeptr - cd->mcodebase);
4465 /* move index register into REG_ITMP1 */
4466 i386_mov_reg_reg(cd, bref->reg, REG_ITMP1); /* 2 bytes */
4468 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4469 dseg_adddata(cd, cd->mcodeptr);
4470 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP3); /* 5 bytes */
4471 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP3, REG_ITMP2_XPC); /* 2 bytes */
4473 if (xcodeptr != NULL) {
4474 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4477 xcodeptr = cd->mcodeptr;
4479 i386_push_reg(cd, REG_ITMP2_XPC);
4481 /*PREPARE_NATIVE_STACKINFO;*/
4482 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4483 i386_push_imm(cd,0);
4484 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4485 i386_call_reg(cd,REG_ITMP3);
4487 i386_alu_imm_reg(cd, I386_SUB, 1 * 4, REG_SP);
4488 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 4);
4489 i386_mov_imm_reg(cd, (u4) new_arrayindexoutofboundsexception, REG_ITMP1);
4490 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4491 i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);
4493 /*REMOVE_NATIVE_STACKINFO;*/
4494 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4495 i386_call_reg(cd,REG_ITMP3);
4497 i386_pop_reg(cd, REG_ITMP2_XPC);
4499 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4500 i386_jmp_reg(cd, REG_ITMP3);
4504 /* generate negative array size check stubs */
4508 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
4509 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4510 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4512 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4516 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4518 cd->mcodeptr - cd->mcodebase);
4522 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4523 dseg_adddata(cd, cd->mcodeptr);
4524 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4525 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4527 if (xcodeptr != NULL) {
4528 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4531 xcodeptr = cd->mcodeptr;
4533 i386_push_reg(cd, REG_ITMP2_XPC);
4535 /*PREPARE_NATIVE_STACKINFO;*/
4536 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4537 i386_push_imm(cd,0);
4538 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4539 i386_call_reg(cd,REG_ITMP3);
4543 i386_mov_imm_reg(cd, (u4) new_negativearraysizeexception, REG_ITMP1);
4544 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4545 /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
4548 /*REMOVE_NATIVE_STACKINFO;*/
4549 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4550 i386_call_reg(cd,REG_ITMP3);
4553 i386_pop_reg(cd, REG_ITMP2_XPC);
4555 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4556 i386_jmp_reg(cd, REG_ITMP3);
4560 /* generate cast check stubs */
4564 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
4565 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4566 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4568 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4572 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4574 cd->mcodeptr - cd->mcodebase);
4578 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4579 dseg_adddata(cd, cd->mcodeptr);
4580 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4581 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4583 if (xcodeptr != NULL) {
4584 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4587 xcodeptr = cd->mcodeptr;
4589 i386_push_reg(cd, REG_ITMP2_XPC);
4591 /*PREPARE_NATIVE_STACKINFO;*/
4592 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4593 i386_push_imm(cd,0);
4594 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4595 i386_call_reg(cd,REG_ITMP3);
4598 i386_mov_imm_reg(cd, (u4) new_classcastexception, REG_ITMP1);
4599 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4600 /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
4603 /*REMOVE_NATIVE_STACKINFO;*/
4604 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4605 i386_call_reg(cd,REG_ITMP3);
4608 i386_pop_reg(cd, REG_ITMP2_XPC);
4610 i386_mov_imm_reg(cd, (u4) asm_handle_exception, REG_ITMP3);
4611 i386_jmp_reg(cd, REG_ITMP3);
4615 /* generate divide by zero check stubs */
4619 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
4620 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4621 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4623 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4627 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4629 cd->mcodeptr - cd->mcodebase);
4633 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4634 dseg_adddata(cd, cd->mcodeptr);
4635 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4636 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4638 if (xcodeptr != NULL) {
4639 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4642 xcodeptr = cd->mcodeptr;
4644 i386_push_reg(cd, REG_ITMP2_XPC);
4646 /*PREPARE_NATIVE_STACKINFO;*/
4647 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4648 i386_push_imm(cd,0);
4649 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4650 i386_call_reg(cd,REG_ITMP3);
4654 i386_mov_imm_reg(cd, (u4) new_arithmeticexception, REG_ITMP1);
4655 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4657 /*REMOVE_NATIVE_STACKINFO;*/
4658 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4659 i386_call_reg(cd,REG_ITMP3);
4662 i386_pop_reg(cd, REG_ITMP2_XPC);
4664 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4665 i386_jmp_reg(cd, REG_ITMP3);
4669 /* generate exception check stubs */
4673 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4674 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4675 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4677 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4681 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4683 cd->mcodeptr - cd->mcodebase);
4687 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4688 dseg_adddata(cd, cd->mcodeptr);
4689 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4690 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4692 if (xcodeptr != NULL) {
4693 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4696 xcodeptr = cd->mcodeptr;
4698 i386_push_reg(cd, REG_ITMP2_XPC);
4700 /*PREPARE_NATIVE_STACKINFO;*/
4701 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4702 i386_push_imm(cd,0);
4703 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4704 i386_call_reg(cd,REG_ITMP3);
4707 i386_mov_imm_reg(cd, (s4) codegen_general_stubcalled, REG_ITMP1);
4708 i386_call_reg(cd, REG_ITMP1);
4710 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4711 i386_mov_imm_reg(cd, (s4) &builtin_get_exceptionptrptr, REG_ITMP1);
4712 i386_call_reg(cd, REG_ITMP1);
4713 i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP3);
4714 i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
4715 i386_mov_reg_reg(cd, REG_ITMP3, REG_ITMP1_XPTR);
4717 i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP3);
4718 i386_mov_membase_reg(cd, REG_ITMP3, 0, REG_ITMP1_XPTR);
4719 i386_mov_imm_membase(cd, 0, REG_ITMP3, 0);
4721 i386_push_imm(cd, 0);
4722 i386_push_reg(cd, REG_ITMP1_XPTR);
4724 /*get the fillInStackTrace Method ID. I simulate a native call here, because I do not want to mess around with the
4725 java stack at this point*/
4726 i386_mov_membase_reg(cd, REG_ITMP1_XPTR, OFFSET(java_objectheader, vftbl), REG_ITMP3);
4727 i386_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, class), REG_ITMP1);
4728 i386_push_imm(cd, (u4) utf_fillInStackTrace_desc);
4729 i386_push_imm(cd, (u4) utf_fillInStackTrace_name);
4730 i386_push_reg(cd, REG_ITMP1);
4731 i386_mov_imm_reg(cd, (s4) class_resolvemethod, REG_ITMP3);
4732 i386_call_reg(cd, REG_ITMP3);
4733 /*cleanup parameters of class_resolvemethod*/
4734 i386_alu_imm_reg(cd, I386_ADD,3*4 /*class reference + 2x string reference*/,REG_SP);
4735 /*prepare call to asm_calljavafunction2 */
4736 i386_push_imm(cd, 0);
4737 i386_push_imm(cd, TYPE_ADR); /* --> call block (TYPE,Exceptionptr), each 8 byte (make this dynamic) (JOWENN)*/
4738 i386_push_reg(cd, REG_SP);
4739 i386_push_imm(cd, sizeof(jni_callblock));
4740 i386_push_imm(cd, 1);
4741 i386_push_reg(cd, REG_RESULT);
4743 i386_mov_imm_reg(cd, (s4) asm_calljavafunction2, REG_ITMP3);
4744 i386_call_reg(cd, REG_ITMP3);
4746 /* check exceptionptr + fail (JOWENN)*/
4748 i386_alu_imm_reg(cd, I386_ADD,6*4,REG_SP);
4750 i386_pop_reg(cd, REG_ITMP1_XPTR);
4751 i386_pop_reg(cd, REG_ITMP3); /* just remove the no longer needed 0 from the stack*/
4753 /*REMOVE_NATIVE_STACKINFO;*/
4754 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4755 i386_call_reg(cd,REG_ITMP3);
4758 i386_pop_reg(cd, REG_ITMP2_XPC);
4760 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4761 i386_jmp_reg(cd, REG_ITMP3);
4765 /* generate null pointer check stubs */
4769 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
4770 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4771 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4773 xcodeptr - cd->mcodebase - (5 + 5 + 2));
4777 gen_resolvebranch(cd->mcodebase + bref->branchpos,
4779 cd->mcodeptr - cd->mcodebase);
4783 i386_mov_imm_reg(cd, 0, REG_ITMP2_XPC); /* 5 bytes */
4784 dseg_adddata(cd, cd->mcodeptr);
4785 i386_mov_imm_reg(cd, bref->branchpos - 6, REG_ITMP1); /* 5 bytes */
4786 i386_alu_reg_reg(cd, I386_ADD, REG_ITMP1, REG_ITMP2_XPC); /* 2 bytes */
4788 if (xcodeptr != NULL) {
4789 i386_jmp_imm(cd, (xcodeptr - cd->mcodeptr) - 5);
4792 xcodeptr = cd->mcodeptr;
4794 i386_push_reg(cd, REG_ITMP2_XPC);
4796 /*PREPARE_NATIVE_STACKINFO;*/
4797 i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
4798 i386_push_imm(cd,0);
4799 i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
4800 i386_call_reg(cd,REG_ITMP3);
4805 /* create native call block*/
4806 i386_alu_imm_reg(cd, I386_SUB, 3*4, REG_SP); /* build stack frame (4 * 4 bytes) */
4809 i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1);
4810 i386_call_reg(cd, REG_ITMP1); /*call codegen_stubcalled*/
4812 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1);
4813 i386_call_reg(cd, REG_ITMP1); /*call builtin_asm_get_stackframeinfo*/
4814 i386_mov_imm_membase(cd, 0,REG_SP, 2*4); /* builtin */
4815 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer to native call stack*/
4816 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */
4817 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4); /* store value on stack */
4818 i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */
4821 i386_mov_imm_reg(cd, (u4) new_nullpointerexception, REG_ITMP1);
4822 i386_call_reg(cd, REG_ITMP1); /* return value is REG_ITMP1_XPTR */
4824 /*REMOVE_NATIVE_STACKINFO;*/
4825 i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
4826 i386_call_reg(cd,REG_ITMP3);
4830 /* restore native call stack */
4831 i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2);
4832 i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3);
4833 i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0);
4834 i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
4837 i386_pop_reg(cd, REG_ITMP2_XPC);
4839 i386_mov_imm_reg(cd, (s4) asm_handle_exception, REG_ITMP3);
4840 i386_jmp_reg(cd, REG_ITMP3);
4844 /* generate put/getstatic stub call code */
4852 tmpcd = DNEW(codegendata);
4854 for (cref = cd->clinitrefs; cref != NULL; cref = cref->next) {
4855 /* Get machine code which is patched back in later. A */
4856 /* `call rel32' is 5 bytes long. */
4857 xcodeptr = cd->mcodebase + cref->branchpos;
4859 mcode = *((u4 *) (xcodeptr + 1));
4863 /* patch in `call rel32' to call the following code */
4864 tmpcd->mcodeptr = xcodeptr; /* set dummy mcode pointer */
4865 i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
4867 /* Save current stack pointer into a temporary register. */
4868 i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
4870 /* Push machine code bytes to patch onto the stack. */
4871 i386_push_imm(cd, (u4) xmcode);
4872 i386_push_imm(cd, (u4) mcode);
4874 i386_push_imm(cd, (u4) cref->class);
4876 /* Push previously saved stack pointer onto stack. */
4877 i386_push_reg(cd, REG_ITMP1);
4879 i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
4880 i386_jmp_reg(cd, REG_ITMP1);
4885 codegen_finish(m, cd, (u4) (cd->mcodeptr - cd->mcodebase));
4889 /* function createcompilerstub *************************************************
4891 creates a stub routine which calls the compiler
4893 *******************************************************************************/
4895 #define COMPSTUBSIZE 12
4897 u1 *createcompilerstub(methodinfo *m)
4899 u1 *s = CNEW(u1, COMPSTUBSIZE); /* memory to hold the stub */
4903 /* mark start of dump memory area */
4905 dumpsize = dump_size();
4907 cd = DNEW(codegendata);
4910 /* code for the stub */
4911 i386_mov_imm_reg(cd, (u4) m, REG_ITMP1);/* pass method pointer to compiler*/
4913 /* we use REG_ITMP3 cause ECX (REG_ITMP2) is used for patching */
4914 i386_mov_imm_reg(cd, (u4) asm_call_jit_compiler, REG_ITMP3);
4915 i386_jmp_reg(cd, REG_ITMP3); /* jump to compiler */
4917 #if defined(STATISTICS)
4919 count_cstub_len += COMPSTUBSIZE;
4922 /* release dump area */
4924 dump_release(dumpsize);
4930 /* function removecompilerstub *************************************************
4932 deletes a compilerstub from memory (simply by freeing it)
4934 *******************************************************************************/
4936 void removecompilerstub(u1 *stub)
4938 CFREE(stub, COMPSTUBSIZE);
4942 /* function: createnativestub **************************************************
4944 creates a stub routine which calls a native method
4946 *******************************************************************************/
4948 #define NATIVESTUBSIZE 370 + 36
4951 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4952 static java_objectheader **(*callgetexceptionptrptr)() = builtin_get_exceptionptrptr;
4955 void i386_native_stub_debug(void **p) {
4956 printf("Pos on stack: %p\n",p);
4957 printf("Return adress should be: %p\n",*p);
4960 void i386_native_stub_debug2(void **p) {
4961 printf("Pos on stack: %p\n",p);
4962 printf("Return for lookup is: %p\n",*p);
4965 void traverseStackInfo() {
4966 void **p=builtin_asm_get_stackframeinfo();
4970 printf("base addr:%p, methodinfo:%p\n",*p,(methodinfo*)((*p)+8));
4971 m=*((methodinfo**)((*p)+8));
4972 utf_display(m->name);
4981 u1 *createnativestub(functionptr f, methodinfo *m)
4983 u1 *s = CNEW(u1, NATIVESTUBSIZE); /* memory to hold the stub */
4986 t_inlining_globals *id;
4992 int stackframesize = 4+16; /* initial 4 bytes is space for jni env,
4993 + 4 byte thread pointer + 4 byte previous pointer + method info + 4 offset native*/
4994 int stackframeoffset = 4;
4998 void** callAddrPatchPos=0;
5000 void** jmpInstrPatchPos=0;
5002 /* mark start of dump memory area */
5004 dumpsize = dump_size();
5006 /* allocate required dump memory */
5008 cd = DNEW(codegendata);
5009 rd = DNEW(registerdata);
5010 id = DNEW(t_inlining_globals);
5012 /* setup registers before using it */
5014 inlining_setup(m, id);
5015 reg_setup(m, rd, id);
5017 /* set some required varibles which are normally set by codegen_setup */
5020 cd->clinitrefs = NULL;
5022 if (m->flags & ACC_STATIC) {
5023 stackframesize += 4;
5024 stackframeoffset += 4;
5027 descriptor2types(m); /* set paramcount and paramtypes */
5030 /* i386_push_reg(cd, REG_SP);
5031 i386_mov_imm_reg(cd, (s4) i386_native_stub_debug, REG_ITMP1);
5032 i386_call_reg(cd, REG_ITMP1);
5033 i386_pop_reg(cd, REG_ITMP1);*/
5036 /* if function is static, check for initialized */
5038 if (m->flags & ACC_STATIC) {
5039 /* if class isn't yet initialized, do it */
5040 if (!m->class->initialized) {
5041 s4 *header = (s4 *) s;
5042 *header = 0;/*extablesize*/
5044 *header = 0;/*line number table start*/
5046 *header = 0;/*line number table size*/
5048 *header = 0;/*fltsave*/
5050 *header = 0;/*intsave*/
5052 *header = 0;/*isleaf*/
5054 *header = 0;/*issync*/
5056 *header = 0;/*framesize*/
5058 *header = (u4) m;/*methodpointer*/
5067 codegen_addclinitref(cd, cd->mcodeptr, m->class);
5072 i386_alu_imm_reg(cd, I386_SUB, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5074 for (p = 0; p < m->paramcount && p < TRACE_ARGS_NUM; p++) {
5075 t = m->paramtypes[p];
5076 if (IS_INT_LNG_TYPE(t)) {
5077 if (IS_2_WORD_TYPE(t)) {
5078 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5079 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4 + 4, REG_ITMP2);
5080 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5081 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5083 } else if (t == TYPE_ADR) {
5084 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, REG_ITMP1);
5085 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
5086 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5087 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5090 i386_mov_membase_reg(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4, EAX);
5092 i386_mov_reg_membase(cd, EAX, REG_SP, p * 8);
5093 i386_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4);
5097 if (!IS_2_WORD_TYPE(t)) {
5098 i386_flds_membase(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5099 i386_fstps_membase(cd, REG_SP, p * 8);
5100 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP2, REG_ITMP2);
5101 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, p * 8 + 4);
5104 i386_fldl_membase(cd, REG_SP, 4 + (TRACE_ARGS_NUM + p) * 8 + 4);
5105 i386_fstpl_membase(cd, REG_SP, p * 8);
5110 i386_alu_reg_reg(cd, I386_XOR, REG_ITMP1, REG_ITMP1);
5111 for (p = m->paramcount; p < TRACE_ARGS_NUM; p++) {
5112 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
5113 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
5116 i386_mov_imm_membase(cd, (s4) m, REG_SP, TRACE_ARGS_NUM * 8);
5118 i386_mov_imm_reg(cd, (s4) builtin_trace_args, REG_ITMP1);
5119 i386_call_reg(cd, REG_ITMP1);
5121 i386_alu_imm_reg(cd, I386_ADD, TRACE_ARGS_NUM * 8 + 4, REG_SP);
5125 * mark the whole fpu stack as free for native functions
5126 * (only for saved register count == 0)
5128 i386_ffree_reg(cd, 0);
5129 i386_ffree_reg(cd, 1);
5130 i386_ffree_reg(cd, 2);
5131 i386_ffree_reg(cd, 3);
5132 i386_ffree_reg(cd, 4);
5133 i386_ffree_reg(cd, 5);
5134 i386_ffree_reg(cd, 6);
5135 i386_ffree_reg(cd, 7);
5137 /* calculate stackframe size for native function */
5138 tptr = m->paramtypes;
5139 for (i = 0; i < m->paramcount; i++) {
5144 stackframesize += 4;
5149 stackframesize += 8;
5153 panic("unknown parameter type in native function");
5157 i386_alu_imm_reg(cd, I386_SUB, stackframesize, REG_SP);
5159 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
5160 i386_mov_imm_membase(cd,0,REG_SP,stackframesize-4);
5161 i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
5162 i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
5163 i386_call_reg(cd, REG_ITMP1);
5164 i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-12); /*save thread specific pointer*/
5165 i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2);
5166 i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-16); /*save previous value of memory adress pointed to by thread specific pointer*/
5167 i386_mov_reg_reg(cd, REG_SP,REG_ITMP2);
5168 i386_alu_imm_reg(cd, I386_ADD,stackframesize-16,REG_ITMP2);
5169 i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT,0);
5172 /* i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-4);
5173 i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
5174 i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-12);*/
5176 /* CREATE DYNAMIC STACK INFO -- END*/
5178 /* RESOLVE NATIVE METHOD -- BEGIN*/
5179 #ifndef STATIC_CLASSPATH
5181 /*log_text("Dynamic classpath: preparing for delayed native function resolving");*/
5183 jmpInstrPos=cd->mcodeptr-4;
5185 i386_mov_imm_reg(cd,jmpInstrPos,REG_ITMP1);
5186 i386_push_reg(cd,REG_ITMP1);
5188 i386_mov_imm_reg(cd,0,REG_ITMP1);
5189 jmpInstrPatchPos=cd->mcodeptr-4;
5190 i386_push_reg(cd,REG_ITMP1);
5191 /*position of call address to patch*/
5192 i386_mov_imm_reg(cd,0,REG_ITMP1);
5193 callAddrPatchPos=(cd->mcodeptr-4);
5194 i386_push_reg(cd,REG_ITMP1);
5195 /*method info structure*/
5196 i386_mov_imm_reg(cd,(s4) m, REG_ITMP1);
5197 i386_push_reg(cd,REG_ITMP1);
5198 /*call resolve functions*/
5199 i386_mov_imm_reg(cd, (s4)codegen_resolve_native,REG_ITMP1);
5200 i386_call_reg(cd,REG_ITMP1);
5202 i386_pop_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 /*fix jmp offset replacement*/
5207 (*jmpInstrPatchPos)=cd->mcodeptr-jmpInstrPos-4;
5208 } /*else log_text("Dynamic classpath: immediate native function resolution possible");*/
5210 /* RESOLVE NATIVE METHOD -- END*/
5214 tptr = m->paramtypes;
5215 for (i = 0; i < m->paramcount; i++) {
5220 i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5221 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, stackframeoffset);
5222 stackframeoffset += 4;
5227 i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8, REG_ITMP1);
5228 i386_mov_membase_reg(cd, REG_SP, stackframesize + (1 * 4) + i * 8 + 4, REG_ITMP2);
5229 i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, stackframeoffset);
5230 i386_mov_reg_membase(cd, REG_ITMP2, REG_SP, stackframeoffset + 4);
5231 stackframeoffset += 8;
5235 panic("unknown parameter type in native function");
5239 if (m->flags & ACC_STATIC) {
5240 /* put class into second argument */
5241 i386_mov_imm_membase(cd, (s4) m->class, REG_SP, 4);
5244 /* put env into first argument */
5245 i386_mov_imm_membase(cd, (s4) &env, REG_SP, 0);
5247 i386_mov_imm_reg(cd, (s4) f, REG_ITMP1);
5248 #ifndef STATIC_CLASSPATH
5250 (*callAddrPatchPos)=(cd->mcodeptr-4);
5252 i386_call_reg(cd, REG_ITMP1);
5254 /*REMOVE DYNAMIC STACK INFO -BEGIN */
5255 i386_push_reg(cd, REG_RESULT2);
5256 i386_mov_membase_reg(cd, REG_SP,stackframesize-12,REG_ITMP2); /*old value*/
5257 i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_RESULT2); /*pointer*/
5258 i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT2,0);
5259 i386_pop_reg(cd, REG_RESULT2);
5260 /*REMOVE DYNAMIC STACK INFO -END */
5262 i386_alu_imm_reg(cd, I386_ADD, stackframesize, REG_SP);
5266 i386_alu_imm_reg(cd, I386_SUB, 4 + 8 + 8 + 4, REG_SP);
5268 i386_mov_imm_membase(cd, (u4) m, REG_SP, 0);
5270 i386_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
5271 i386_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
5273 i386_fstl_membase(cd, REG_SP, 4 + 8);
5274 i386_fsts_membase(cd, REG_SP, 4 + 8 + 8);
5276 i386_mov_imm_reg(cd, (u4) builtin_displaymethodstop, REG_ITMP1);
5277 i386_call_reg(cd, REG_ITMP1);
5279 i386_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
5280 i386_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
5282 i386_alu_imm_reg(cd, I386_ADD, 4 + 8 + 8 + 4, REG_SP);
5285 /* we can't use REG_ITMP3 == REG_RESULT2 */
5286 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5287 i386_push_reg(cd, REG_RESULT);
5288 i386_push_reg(cd, REG_RESULT2);
5289 i386_call_mem(cd, (s4) &callgetexceptionptrptr);
5290 i386_mov_membase_reg(cd, REG_RESULT, 0, REG_ITMP2);
5291 i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
5292 i386_pop_reg(cd, REG_RESULT2);
5293 i386_pop_reg(cd, REG_RESULT);
5295 i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP2);
5296 i386_mov_membase_reg(cd, REG_ITMP2, 0, REG_ITMP2);
5297 i386_test_reg_reg(cd, REG_ITMP2, REG_ITMP2);
5299 i386_jcc(cd, I386_CC_NE, 1);
5303 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
5304 i386_push_reg(cd, REG_ITMP2);
5305 i386_call_mem(cd, (s4) &callgetexceptionptrptr);
5306 i386_mov_imm_membase(cd, 0, REG_RESULT, 0);
5307 i386_pop_reg(cd, REG_ITMP1_XPTR);
5309 i386_mov_reg_reg(cd, REG_ITMP2, REG_ITMP1_XPTR);
5310 i386_mov_imm_reg(cd, (s4) &_exceptionptr, REG_ITMP2);
5311 i386_mov_imm_membase(cd, 0, REG_ITMP2, 0);
5313 i386_mov_membase_reg(cd, REG_SP, 0, REG_ITMP2_XPC);
5314 i386_alu_imm_reg(cd, I386_SUB, 2, REG_ITMP2_XPC);
5316 i386_mov_imm_reg(cd, (s4) asm_handle_nat_exception, REG_ITMP3);
5317 i386_jmp_reg(cd, REG_ITMP3);
5320 codegen_insertmethod(s, cd->mcodeptr);
5330 tmpcd = DNEW(codegendata);
5332 /* there can only be one clinit ref entry */
5333 cref = cd->clinitrefs;
5336 /* Get machine code which is patched back in later. A */
5337 /* `call rel32' is 5 bytes long. */
5338 xcodeptr = cd->mcodebase + cref->branchpos;
5340 mcode = *((u4 *) (xcodeptr + 1));
5342 /* patch in `call rel32' to call the following code */
5343 tmpcd->mcodeptr = xcodeptr; /* set dummy mcode pointer */
5344 i386_call_imm(tmpcd, cd->mcodeptr - (xcodeptr + 5));
5346 /* Save current stack pointer into a temporary register. */
5347 i386_mov_reg_reg(cd, REG_SP, REG_ITMP1);
5349 /* Push machine code bytes to patch onto the stack. */
5350 i386_push_imm(cd, (u4) xmcode);
5351 i386_push_imm(cd, (u4) mcode);
5353 i386_push_imm(cd, (u4) cref->class);
5355 /* Push previously saved stack pointer onto stack. */
5356 i386_push_reg(cd, REG_ITMP1);
5358 i386_mov_imm_reg(cd, (u4) asm_check_clinit, REG_ITMP1);
5359 i386_jmp_reg(cd, REG_ITMP1);
5364 dolog_plain("native stubentry: %p, stubsize: %d (for %d params) --", (s4)s,(s4) (cd->mcodeptr - s), m->paramcount);
5365 utf_display(m->name);
5369 #if defined(STATISTICS)
5371 count_nstub_len += NATIVESTUBSIZE;
5374 /* release dump area */
5376 dump_release(dumpsize);
5382 /* function: removenativestub **************************************************
5384 removes a previously created native-stub from memory
5386 *******************************************************************************/
5388 void removenativestub(u1 *stub)
5390 CFREE(stub, NATIVESTUBSIZE);
5395 * These are local overrides for various environment variables in Emacs.
5396 * Please do not remove this and leave it at the end of the file, where
5397 * Emacs will automagically detect them.
5398 * ---------------------------------------------------------------------
5401 * indent-tabs-mode: t