1 /* src/vm/jit/i386/codegen.c - machine code generator for i386
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
34 $Id: codegen.c 5234 2006-08-14 17:50:12Z christian $
46 #include "vm/jit/i386/md-abi.h"
48 #include "vm/jit/i386/codegen.h"
49 #include "vm/jit/i386/md-emit.h"
51 #include "mm/memory.h"
52 #include "native/jni.h"
53 #include "native/native.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/lock.h"
59 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
78 # include "vm/jit/allocator/lsra.h"
80 #if defined(ENABLE_SSA)
81 # include "vm/jit/optimizing/lsra.h"
82 # include "vm/jit/optimizing/ssa.h"
86 /* codegen *********************************************************************
88 Generates machine code.
90 *******************************************************************************/
92 #if defined(ENABLE_SSA)
93 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
94 s4 dst_regoff, s4 dst_flags);
95 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls,
99 bool codegen(jitdata *jd)
105 s4 len, s1, s2, s3, d, off, disp;
113 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
114 builtintable_entry *bte;
116 rplpoint *replacementpoint;
117 #if defined(ENABLE_SSA)
119 bool last_cmd_was_goto;
121 last_cmd_was_goto = false;
125 /* get required compiler data */
132 /* prevent compiler warnings */
142 s4 savedregs_num = 0;
145 /* space to save used callee saved registers */
147 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
149 /* float register are saved on 2 4-byte stackslots */
150 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
152 stackframesize = rd->memuse + savedregs_num;
155 #if defined(ENABLE_THREADS)
156 /* space to save argument of monitor_enter */
158 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
159 /* reserve 2 slots for long/double return values for monitorexit */
161 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
168 /* create method header */
170 /* Keep stack of non-leaf functions 16-byte aligned. */
172 if (!jd->isleafmethod)
173 stackframesize |= 0x3;
175 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
176 (void) dseg_adds4(cd, stackframesize * 4); /* FrameSize */
178 #if defined(ENABLE_THREADS)
179 /* IsSync contains the offset relative to the stack pointer for the
180 argument of monitor_exit used in the exception handler. Since the
181 offset could be zero and give a wrong meaning of the flag it is
185 if (checksync && (m->flags & ACC_SYNCHRONIZED))
186 (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
189 (void) dseg_adds4(cd, 0); /* IsSync */
191 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
192 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
193 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
195 /* adds a reference for the length of the line number counter. We don't
196 know the size yet, since we evaluate the information during code
197 generation, to save one additional iteration over the whole
198 instructions. During code optimization the position could have changed
199 to the information gotten from the class file */
200 (void) dseg_addlinenumbertablesize(cd);
202 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
204 /* create exception table */
206 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
207 dseg_addtarget(cd, ex->start);
208 dseg_addtarget(cd, ex->end);
209 dseg_addtarget(cd, ex->handler);
210 (void) dseg_addaddress(cd, ex->catchtype.cls);
213 /* generate method profiling code */
215 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
216 /* count frequency */
218 M_MOV_IMM(code, REG_ITMP3);
219 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
222 /* create stack frame (if necessary) */
225 M_ASUB_IMM(stackframesize * 4, REG_SP);
227 /* save return address and used callee saved registers */
230 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
231 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
233 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
234 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
237 /* take arguments out of register or stack frame */
242 for (p = 0, l = 0; p < md->paramcount; p++) {
243 t = md->paramtypes[p].type;
244 #if defined(ENABLE_SSA)
249 var = &(rd->locals[l][t]);
251 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
255 s1 = md->params[p].regoff;
257 if (IS_INT_LNG_TYPE(t)) { /* integer args */
258 if (!md->params[p].inmemory) { /* register arguments */
259 log_text("integer register argument");
261 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
262 /* rd->argintregs[md->params[p].regoff -> var->regoff */
264 else { /* reg arg -> spilled */
265 /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
268 else { /* stack arguments */
269 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
270 emit_mov_membase_reg( /* + 4 for return address */
271 cd, REG_SP, (stackframesize + s1) * 4 + 4, var->regoff);
272 /* + 4 for return address */
274 else { /* stack arg -> spilled */
275 if (!IS_2_WORD_TYPE(t)) {
276 #if defined(ENABLE_SSA)
277 /* no copy avoiding by now possible with SSA */
279 emit_mov_membase_reg( /* + 4 for return address */
280 cd, REG_SP, (stackframesize + s1) * 4 + 4,
282 emit_mov_reg_membase(
283 cd, REG_ITMP1, REG_SP, var->regoff * 4);
286 #endif /*defined(ENABLE_SSA)*/
287 /* reuse Stackslotand avoid copying */
288 var->regoff = stackframesize + s1 + 1;
292 #if defined(ENABLE_SSA)
293 /* no copy avoiding by now possible with SSA */
295 emit_mov_membase_reg( /* + 4 for return address */
296 cd, REG_SP, (stackframesize + s1) * 4 + 4,
298 emit_mov_reg_membase(
299 cd, REG_ITMP1, REG_SP, var->regoff * 4);
300 emit_mov_membase_reg( /* + 4 for return address */
301 cd, REG_SP, (stackframesize + s1) * 4 + 4 + 4,
303 emit_mov_reg_membase(
304 cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
307 #endif /*defined(ENABLE_SSA)*/
308 /* reuse Stackslotand avoid copying */
309 var->regoff = stackframesize + s1 + 1;
314 else { /* floating args */
315 if (!md->params[p].inmemory) { /* register arguments */
316 log_text("There are no float argument registers!");
318 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
319 /* rd->argfltregs[md->params[p].regoff -> var->regoff */
320 } else { /* reg arg -> spilled */
321 /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
325 else { /* stack arguments */
326 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
329 cd, REG_SP, (stackframesize + s1) * 4 + 4);
331 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
336 cd, REG_SP, (stackframesize + s1) * 4 + 4);
338 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
341 } else { /* stack-arg -> spilled */
342 #if defined(ENABLE_SSA)
343 /* no copy avoiding by now possible with SSA */
345 emit_mov_membase_reg(
346 cd, REG_SP, (stackframesize + s1) * 4 + 4, REG_ITMP1);
347 emit_mov_reg_membase(
348 cd, REG_ITMP1, REG_SP, var->regoff * 4);
351 cd, REG_SP, (stackframesize + s1) * 4 + 4);
352 emit_fstps_membase(cd, REG_SP, var->regoff * 4);
356 cd, REG_SP, (stackframesize + s1) * 4 + 4);
357 emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
361 #endif /*defined(ENABLE_SSA)*/
362 /* reuse Stackslotand avoid copying */
363 var->regoff = stackframesize + s1 + 1;
369 /* call monitorenter function */
371 #if defined(ENABLE_THREADS)
372 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
375 if (m->flags & ACC_STATIC) {
376 M_MOV_IMM(&m->class->object.header, REG_ITMP1);
379 M_ALD(REG_ITMP1, REG_SP, stackframesize * 4 + 4);
382 codegen_add_nullpointerexception_ref(cd);
385 M_AST(REG_ITMP1, REG_SP, s1 * 4);
386 M_AST(REG_ITMP1, REG_SP, 0 * 4);
387 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
392 /* copy argument registers to stack and call trace function with pointer
393 to arguments on stack.
397 if (opt_verbosecall) {
399 s1 = INT_TMP_CNT * 4 + TRACE_ARGS_NUM * 8 + 4 + 4 + stackframesize * 4;
401 M_ISUB_IMM(INT_TMP_CNT * 4 + TRACE_ARGS_NUM * 8 + 4, REG_SP);
403 /* save temporary registers for leaf methods */
405 for (p = 0; p < INT_TMP_CNT; p++)
406 M_IST(rd->tmpintregs[p], REG_SP, TRACE_ARGS_NUM * 8 + 4 + p * 4);
408 for (p = 0, l = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
409 t = md->paramtypes[p].type;
411 if (IS_INT_LNG_TYPE(t)) {
412 if (IS_2_WORD_TYPE(t)) {
413 emit_mov_membase_reg(cd, REG_SP, s1 + stack_off, REG_ITMP1);
414 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
415 emit_mov_membase_reg(cd, REG_SP, s1 + stack_off + 4, REG_ITMP1);
416 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
418 } else if (t == TYPE_ADR) {
420 emit_mov_membase_reg(cd, REG_SP, s1 + stack_off, REG_ITMP1);
421 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
422 emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP1, REG_ITMP1);
423 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
426 emit_mov_membase_reg(cd, REG_SP, s1 + stack_off, EAX);
428 emit_mov_reg_membase(cd, EAX, REG_SP, p * 8);
429 emit_mov_reg_membase(cd, EDX, REG_SP, p * 8 + 4);
433 if (!IS_2_WORD_TYPE(t)) {
434 emit_flds_membase(cd, REG_SP, s1 + stack_off);
435 emit_fstps_membase(cd, REG_SP, p * 8);
436 emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP1, REG_ITMP1);
437 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
440 emit_fldl_membase(cd, REG_SP, s1 + stack_off);
441 emit_fstpl_membase(cd, REG_SP, p * 8);
444 stack_off += (IS_2_WORD_TYPE(t)) ? 8 : 4;
447 /* fill up the remaining arguments */
448 emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP1, REG_ITMP1);
449 for (p = md->paramcount; p < TRACE_ARGS_NUM; p++) {
450 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8);
451 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, p * 8 + 4);
454 emit_mov_imm_membase(cd, (ptrint) m, REG_SP, TRACE_ARGS_NUM * 8);
455 emit_mov_imm_reg(cd, (ptrint) builtin_trace_args, REG_ITMP1);
456 emit_call_reg(cd, REG_ITMP1);
458 /* restore temporary registers for leaf methods */
460 for (p = 0; p < INT_TMP_CNT; p++)
461 M_ILD(rd->tmpintregs[p], REG_SP, TRACE_ARGS_NUM * 8 + 4 + p * 4);
463 M_IADD_IMM(INT_TMP_CNT * 4 + TRACE_ARGS_NUM * 8 + 4, REG_SP);
465 #endif /* !defined(NDEBUG) */
469 #if defined(ENABLE_SSA)
470 /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
472 codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
475 /* end of header generation */
477 replacementpoint = jd->code->rplpoints;
479 /* walk through all basic blocks */
480 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
482 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
484 if (bptr->flags >= BBREACHED) {
486 /* branch resolving */
489 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
490 gen_resolvebranch(cd->mcodebase + brefs->branchpos,
495 /* handle replacement points */
497 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
498 replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
502 assert(cd->lastmcodeptr <= cd->mcodeptr);
503 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
506 /* copy interface registers to their destination */
513 /* generate basic block profiling code */
515 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
516 /* count frequency */
518 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
519 M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
523 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
524 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
527 # if defined(ENABLE_SSA)
529 last_cmd_was_goto = false;
533 if (bptr->type != BBTYPE_STD) {
534 if (!IS_2_WORD_TYPE(src->type)) {
535 if (bptr->type == BBTYPE_SBR) {
536 if (!(src->flags & INMEMORY))
541 emit_store(jd, NULL, src, d);
542 } else if (bptr->type == BBTYPE_EXH) {
543 if (!(src->flags & INMEMORY))
547 M_INTMOVE(REG_ITMP1, d);
548 emit_store(jd, NULL, src, d);
552 log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
560 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
562 while (src != NULL) {
564 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
565 if (!IS_2_WORD_TYPE(src->type)) {
566 if (bptr->type == BBTYPE_SBR) {
567 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
569 emit_store(jd, NULL, src, d);
571 } else if (bptr->type == BBTYPE_EXH) {
572 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
573 M_INTMOVE(REG_ITMP1, d);
574 emit_store(jd, NULL, src, d);
577 log_text("copy interface registers: longs have to be in memory (begin 1)");
582 if (IS_LNG_TYPE(src->type))
583 d = codegen_reg_of_var(rd, 0, src, PACK_REGS(REG_ITMP1, REG_ITMP2));
585 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
586 /* d = codegen_reg_of_var(rd, 0, src, REG_IFTMP); */
588 if ((src->varkind != STACKVAR)) {
590 s1 = rd->interfaces[len][s2].regoff;
592 if (IS_FLT_DBL_TYPE(s2)) {
593 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
597 if (IS_2_WORD_TYPE(s2))
598 M_DLD(d, REG_SP, s1 * 4);
600 M_FLD(d, REG_SP, s1 * 4);
604 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
605 if (IS_2_WORD_TYPE(s2))
611 if (IS_2_WORD_TYPE(s2))
612 M_LLD(d, REG_SP, s1 * 4);
614 M_ILD(d, REG_SP, s1 * 4);
618 emit_store(jd, NULL, src, d);
625 /* walk through all instructions */
630 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
631 if (iptr->line != currentline) {
632 dseg_addlinenumber(cd, iptr->line);
633 currentline = iptr->line;
636 MCODECHECK(1024); /* 1kB should be enough */
639 case ICMD_INLINE_START:
641 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
642 #if defined(ENABLE_THREADS)
643 if (insinfo->synchronize) {
644 /* add monitor enter code */
645 if (insinfo->method->flags & ACC_STATIC) {
646 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
647 M_AST(REG_ITMP1, REG_SP, 0 * 4);
650 /* nullpointer check must have been performed before */
651 /* (XXX not done, yet) */
652 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
653 if (var->flags & INMEMORY) {
654 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
655 M_AST(REG_ITMP1, REG_SP, 0 * 4);
658 M_AST(var->regoff, REG_SP, 0 * 4);
662 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
666 dseg_addlinenumber_inline_start(cd, iptr);
670 case ICMD_INLINE_END:
672 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
674 dseg_addlinenumber_inline_end(cd, iptr);
675 dseg_addlinenumber(cd, iptr->line);
677 #if defined(ENABLE_THREADS)
678 if (insinfo->synchronize) {
679 /* add monitor exit code */
680 if (insinfo->method->flags & ACC_STATIC) {
681 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
682 M_AST(REG_ITMP1, REG_SP, 0 * 4);
685 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
686 if (var->flags & INMEMORY) {
687 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
688 M_AST(REG_ITMP1, REG_SP, 0 * 4);
691 M_AST(var->regoff, REG_SP, 0 * 4);
695 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
702 case ICMD_NOP: /* ... ==> ... */
705 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
707 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
710 codegen_add_nullpointerexception_ref(cd);
713 /* constant operations ************************************************/
715 case ICMD_ICONST: /* ... ==> ..., constant */
716 /* op1 = 0, val.i = constant */
718 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
719 ICONST(d, iptr->val.i);
720 emit_store(jd, iptr, iptr->dst, d);
723 case ICMD_LCONST: /* ... ==> ..., constant */
724 /* op1 = 0, val.l = constant */
726 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
727 LCONST(d, iptr->val.l);
728 emit_store(jd, iptr, iptr->dst, d);
731 case ICMD_FCONST: /* ... ==> ..., constant */
732 /* op1 = 0, val.f = constant */
734 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
735 if (iptr->val.f == 0.0) {
739 if (iptr->val.i == 0x80000000) {
743 } else if (iptr->val.f == 1.0) {
746 } else if (iptr->val.f == 2.0) {
752 disp = dseg_addfloat(cd, iptr->val.f);
753 emit_mov_imm_reg(cd, 0, REG_ITMP1);
755 emit_flds_membase(cd, REG_ITMP1, disp);
757 emit_store(jd, iptr, iptr->dst, d);
760 case ICMD_DCONST: /* ... ==> ..., constant */
761 /* op1 = 0, val.d = constant */
763 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
764 if (iptr->val.d == 0.0) {
768 if (iptr->val.l == 0x8000000000000000LL) {
772 } else if (iptr->val.d == 1.0) {
775 } else if (iptr->val.d == 2.0) {
781 disp = dseg_adddouble(cd, iptr->val.d);
782 emit_mov_imm_reg(cd, 0, REG_ITMP1);
784 emit_fldl_membase(cd, REG_ITMP1, disp);
786 emit_store(jd, iptr, iptr->dst, d);
789 case ICMD_ACONST: /* ... ==> ..., constant */
790 /* op1 = 0, val.a = constant */
792 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
794 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
795 codegen_addpatchref(cd, PATCHER_aconst,
796 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr), 0);
798 if (opt_showdisassemble) {
799 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
805 if (iptr->val.a == NULL)
808 M_MOV_IMM(iptr->val.a, d);
810 emit_store(jd, iptr, iptr->dst, d);
814 /* load/store operations **********************************************/
816 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
817 case ICMD_ALOAD: /* op1 = local variable */
819 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
820 if ((iptr->dst->varkind == LOCALVAR) &&
821 (iptr->dst->varnum == iptr->op1))
823 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
824 if (var->flags & INMEMORY)
825 M_ILD(d, REG_SP, var->regoff * 4);
827 M_INTMOVE(var->regoff, d);
828 emit_store(jd, iptr, iptr->dst, d);
831 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
832 /* op1 = local variable */
834 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
835 if ((iptr->dst->varkind == LOCALVAR) &&
836 (iptr->dst->varnum == iptr->op1))
838 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
839 if (var->flags & INMEMORY)
840 M_LLD(d, REG_SP, var->regoff * 4);
842 M_LNGMOVE(var->regoff, d);
843 emit_store(jd, iptr, iptr->dst, d);
846 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
847 /* op1 = local variable */
849 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
850 if ((iptr->dst->varkind == LOCALVAR) &&
851 (iptr->dst->varnum == iptr->op1))
853 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
854 if (var->flags & INMEMORY)
855 M_FLD(d, REG_SP, var->regoff * 4);
857 M_FLTMOVE(var->regoff, d);
858 emit_store(jd, iptr, iptr->dst, d);
861 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
862 /* op1 = local variable */
864 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
865 if ((iptr->dst->varkind == LOCALVAR) &&
866 (iptr->dst->varnum == iptr->op1))
868 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
869 if (var->flags & INMEMORY)
870 M_DLD(d, REG_SP, var->regoff * 4);
872 M_FLTMOVE(var->regoff, d);
873 emit_store(jd, iptr, 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))
882 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
883 if (var->flags & INMEMORY) {
884 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
885 M_IST(s1, REG_SP, var->regoff * 4);
888 s1 = emit_load_s1(jd, iptr, src, var->regoff);
889 M_INTMOVE(s1, var->regoff);
893 case ICMD_LSTORE: /* ..., value ==> ... */
894 /* op1 = local variable */
896 if ((src->varkind == LOCALVAR) &&
897 (src->varnum == iptr->op1))
899 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
900 if (var->flags & INMEMORY) {
901 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
902 M_LST(s1, REG_SP, var->regoff * 4);
905 s1 = emit_load_s1(jd, iptr, src, var->regoff);
906 M_LNGMOVE(s1, var->regoff);
910 case ICMD_FSTORE: /* ..., value ==> ... */
911 /* op1 = local variable */
913 if ((src->varkind == LOCALVAR) &&
914 (src->varnum == iptr->op1))
916 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
917 if (var->flags & INMEMORY) {
918 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
919 M_FST(s1, REG_SP, var->regoff * 4);
922 s1 = emit_load_s1(jd, iptr, src, var->regoff);
923 M_FLTMOVE(s1, var->regoff);
927 case ICMD_DSTORE: /* ..., value ==> ... */
928 /* op1 = local variable */
930 if ((src->varkind == LOCALVAR) &&
931 (src->varnum == iptr->op1))
933 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
934 if (var->flags & INMEMORY) {
935 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
936 M_DST(s1, REG_SP, var->regoff * 4);
939 s1 = emit_load_s1(jd, iptr, src, var->regoff);
940 M_FLTMOVE(s1, var->regoff);
945 /* pop/dup/swap operations ********************************************/
947 /* attention: double and longs are only one entry in CACAO ICMDs */
949 case ICMD_POP: /* ..., value ==> ... */
950 case ICMD_POP2: /* ..., value, value ==> ... */
953 case ICMD_DUP: /* ..., a ==> ..., a, a */
955 M_COPY(src, iptr->dst);
958 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
960 M_COPY(src, iptr->dst);
961 M_COPY(src->prev, iptr->dst->prev);
964 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
966 M_COPY(src, iptr->dst);
967 M_COPY(src->prev, iptr->dst->prev);
968 #if defined(ENABLE_SSA)
969 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
970 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
972 M_COPY(iptr->dst, iptr->dst->prev->prev);
973 #if defined(ENABLE_SSA)
975 M_COPY(src, iptr->dst->prev->prev);
980 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
982 M_COPY(src, iptr->dst);
983 M_COPY(src->prev, iptr->dst->prev);
984 M_COPY(src->prev->prev, iptr->dst->prev->prev);
985 #if defined(ENABLE_SSA)
986 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
987 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
989 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
990 #if defined(ENABLE_SSA)
992 M_COPY(src, iptr->dst->prev->prev->prev);
997 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
999 M_COPY(src, iptr->dst);
1000 M_COPY(src->prev, iptr->dst->prev);
1001 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1002 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
1003 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
1006 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
1008 M_COPY(src, iptr->dst);
1009 M_COPY(src->prev, iptr->dst->prev);
1010 M_COPY(src->prev->prev, iptr->dst->prev->prev);
1011 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
1012 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
1013 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
1016 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
1018 M_COPY(src, iptr->dst->prev);
1019 M_COPY(src->prev, iptr->dst);
1023 /* integer operations *************************************************/
1025 case ICMD_INEG: /* ..., value ==> ..., - value */
1027 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1028 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1031 emit_store(jd, iptr, iptr->dst, d);
1034 case ICMD_LNEG: /* ..., value ==> ..., - value */
1036 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1037 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1039 M_NEG(GET_LOW_REG(d));
1040 M_IADDC_IMM(0, GET_HIGH_REG(d));
1041 M_NEG(GET_HIGH_REG(d));
1042 emit_store(jd, iptr, iptr->dst, d);
1045 case ICMD_I2L: /* ..., value ==> ..., value */
1047 s1 = emit_load_s1(jd, iptr, src, EAX);
1048 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1051 M_LNGMOVE(EAX_EDX_PACKED, d);
1052 emit_store(jd, iptr, iptr->dst, d);
1055 case ICMD_L2I: /* ..., value ==> ..., value */
1057 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
1058 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1060 emit_store(jd, iptr, iptr->dst, d);
1063 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1065 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1066 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1070 emit_store(jd, iptr, iptr->dst, d);
1073 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1075 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1076 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1078 emit_store(jd, iptr, iptr->dst, d);
1081 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1083 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1084 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1086 emit_store(jd, iptr, iptr->dst, d);
1090 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1092 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1093 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1094 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1101 emit_store(jd, iptr, iptr->dst, d);
1104 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1105 /* val.i = constant */
1107 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1108 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1110 M_IADD_IMM(iptr->val.i, d);
1111 emit_store(jd, iptr, iptr->dst, d);
1114 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1116 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1117 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1118 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1119 M_INTMOVE(s1, GET_LOW_REG(d));
1120 M_IADD(s2, GET_LOW_REG(d));
1121 /* don't use REG_ITMP1 */
1122 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1123 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1124 M_INTMOVE(s1, GET_HIGH_REG(d));
1125 M_IADDC(s2, GET_HIGH_REG(d));
1126 emit_store(jd, iptr, iptr->dst, d);
1129 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1130 /* val.l = constant */
1132 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1133 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1135 M_IADD_IMM(iptr->val.l, GET_LOW_REG(d));
1136 M_IADDC_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1137 emit_store(jd, iptr, iptr->dst, d);
1140 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1142 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1143 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1144 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1146 M_INTMOVE(s1, REG_ITMP1);
1147 M_ISUB(s2, REG_ITMP1);
1148 M_INTMOVE(REG_ITMP1, d);
1154 emit_store(jd, iptr, iptr->dst, d);
1157 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1158 /* val.i = constant */
1160 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1161 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1163 M_ISUB_IMM(iptr->val.i, d);
1164 emit_store(jd, iptr, iptr->dst, d);
1167 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1169 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1170 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1171 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1172 if (s2 == GET_LOW_REG(d)) {
1173 M_INTMOVE(s1, REG_ITMP1);
1174 M_ISUB(s2, REG_ITMP1);
1175 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
1178 M_INTMOVE(s1, GET_LOW_REG(d));
1179 M_ISUB(s2, GET_LOW_REG(d));
1181 /* don't use REG_ITMP1 */
1182 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1183 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1184 if (s2 == GET_HIGH_REG(d)) {
1185 M_INTMOVE(s1, REG_ITMP2);
1186 M_ISUBB(s2, REG_ITMP2);
1187 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
1190 M_INTMOVE(s1, GET_HIGH_REG(d));
1191 M_ISUBB(s2, GET_HIGH_REG(d));
1193 emit_store(jd, iptr, iptr->dst, d);
1196 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1197 /* val.l = constant */
1199 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1200 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1202 M_ISUB_IMM(iptr->val.l, GET_LOW_REG(d));
1203 M_ISUBB_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1204 emit_store(jd, iptr, iptr->dst, d);
1207 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1209 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1210 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1211 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1218 emit_store(jd, iptr, iptr->dst, d);
1221 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1222 /* val.i = constant */
1224 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1225 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1226 M_IMUL_IMM(s1, iptr->val.i, d);
1227 emit_store(jd, iptr, iptr->dst, d);
1230 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1232 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1233 s2 = emit_load_s2_low(jd, iptr, src, EDX);
1234 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1236 M_INTMOVE(s1, REG_ITMP2);
1237 M_IMUL(s2, REG_ITMP2);
1239 s1 = emit_load_s1_low(jd, iptr, src->prev, EAX);
1240 s2 = emit_load_s2_high(jd, iptr, src, EDX);
1243 M_IADD(EDX, REG_ITMP2);
1245 s1 = emit_load_s1_low(jd, iptr, src->prev, EAX);
1246 s2 = emit_load_s2_low(jd, iptr, src, EDX);
1249 M_INTMOVE(EAX, GET_LOW_REG(d));
1250 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
1252 emit_store(jd, iptr, iptr->dst, d);
1255 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1256 /* val.l = constant */
1258 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
1259 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1260 ICONST(EAX, iptr->val.l);
1262 M_IMUL_IMM(s1, iptr->val.l >> 32, REG_ITMP2);
1263 M_IADD(REG_ITMP2, EDX);
1264 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
1265 M_IMUL_IMM(s1, iptr->val.l, REG_ITMP2);
1266 M_IADD(REG_ITMP2, EDX);
1267 M_LNGMOVE(EAX_EDX_PACKED, d);
1268 emit_store(jd, iptr, iptr->dst, d);
1271 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1273 s1 = emit_load_s1(jd, iptr, src->prev, EAX);
1274 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1275 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX);
1280 codegen_add_arithmeticexception_ref(cd);
1283 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1285 /* check as described in jvm spec */
1287 M_CMP_IMM(0x80000000, EAX);
1294 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
1295 emit_store(jd, iptr, iptr->dst, d);
1298 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1300 s1 = emit_load_s1(jd, iptr, src->prev, EAX);
1301 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1302 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EDX);
1307 codegen_add_arithmeticexception_ref(cd);
1310 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1312 /* check as described in jvm spec */
1314 M_CMP_IMM(0x80000000, EAX);
1322 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
1323 emit_store(jd, iptr, iptr->dst, d);
1326 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1327 /* val.i = constant */
1329 /* TODO: optimize for `/ 2' */
1330 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1331 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1335 M_IADD_IMM32((1 << iptr->val.i) - 1, d); /* 32-bit for jump off. */
1336 M_SRA_IMM(iptr->val.i, d);
1337 emit_store(jd, iptr, iptr->dst, d);
1340 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1341 /* val.i = constant */
1343 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1344 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1346 M_MOV(s1, REG_ITMP1);
1350 M_AND_IMM(iptr->val.i, d);
1352 M_BGE(2 + 2 + 6 + 2);
1353 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
1355 M_AND_IMM32(iptr->val.i, d); /* use 32-bit for jump offset */
1357 emit_store(jd, iptr, iptr->dst, d);
1360 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1361 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1363 s2 = emit_load_s2(jd, iptr, src, REG_ITMP12_PACKED);
1364 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1366 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1367 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1369 codegen_add_arithmeticexception_ref(cd);
1374 M_LST(s2, REG_SP, 2 * 4);
1376 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP12_PACKED);
1377 M_LST(s1, REG_SP, 0 * 4);
1379 M_MOV_IMM(bte->fp, REG_ITMP3);
1381 emit_store(jd, iptr, iptr->dst, d);
1384 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1385 /* val.i = constant */
1387 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1388 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1390 M_TEST(GET_HIGH_REG(d));
1392 M_IADD_IMM32((1 << iptr->val.i) - 1, GET_LOW_REG(d));
1393 M_IADDC_IMM(0, GET_HIGH_REG(d));
1394 M_SRLD_IMM(iptr->val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1395 M_SRA_IMM(iptr->val.i, GET_HIGH_REG(d));
1396 emit_store(jd, iptr, iptr->dst, d);
1400 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1401 /* val.l = constant */
1403 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
1404 if (iptr->dst->flags & INMEMORY) {
1405 if (src->flags & INMEMORY) {
1406 /* Alpha algorithm */
1408 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1410 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4 + 4);
1416 /* TODO: hmm, don't know if this is always correct */
1418 CALCIMMEDIATEBYTES(disp, iptr->val.l & 0x00000000ffffffff);
1420 CALCIMMEDIATEBYTES(disp, iptr->val.l >> 32);
1426 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
1427 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
1429 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l, REG_ITMP1);
1430 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l >> 32, REG_ITMP2);
1431 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, src->regoff * 4 + 4);
1432 emit_jcc(cd, CC_GE, disp);
1434 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
1435 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
1437 emit_neg_reg(cd, REG_ITMP1);
1438 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1439 emit_neg_reg(cd, REG_ITMP2);
1441 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l, REG_ITMP1);
1442 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l >> 32, REG_ITMP2);
1444 emit_neg_reg(cd, REG_ITMP1);
1445 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1446 emit_neg_reg(cd, REG_ITMP2);
1448 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
1449 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 4 + 4);
1453 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1454 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1456 M_AND_IMM(iptr->val.l, GET_LOW_REG(d));
1457 M_AND_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1458 M_TEST(GET_LOW_REG(s1));
1464 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1466 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1467 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1468 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1469 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1472 emit_store(jd, iptr, iptr->dst, d);
1475 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1476 /* val.i = constant */
1478 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1479 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1481 M_SLL_IMM(iptr->val.i, d);
1482 emit_store(jd, iptr, iptr->dst, d);
1485 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1487 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1488 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1489 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1490 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1493 emit_store(jd, iptr, iptr->dst, d);
1496 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1497 /* val.i = constant */
1499 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1500 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1502 M_SRA_IMM(iptr->val.i, d);
1503 emit_store(jd, iptr, iptr->dst, d);
1506 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1508 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1509 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1510 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1511 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1514 emit_store(jd, iptr, iptr->dst, d);
1517 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1518 /* val.i = constant */
1520 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1521 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1523 M_SRL_IMM(iptr->val.i, d);
1524 emit_store(jd, iptr, iptr->dst, d);
1527 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1529 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1530 s2 = emit_load_s2(jd, iptr, src, ECX);
1531 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1534 M_TEST_IMM(32, ECX);
1536 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1537 M_CLR(GET_LOW_REG(d));
1538 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1539 M_SLL(GET_LOW_REG(d));
1540 emit_store(jd, iptr, iptr->dst, d);
1543 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1544 /* val.i = constant */
1546 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1547 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1549 if (iptr->val.i & 0x20) {
1550 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1551 M_CLR(GET_LOW_REG(d));
1552 M_SLLD_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1555 M_SLLD_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1556 M_SLL_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d));
1558 emit_store(jd, iptr, iptr->dst, d);
1561 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1563 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1564 s2 = emit_load_s2(jd, iptr, src, ECX);
1565 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1568 M_TEST_IMM(32, ECX);
1570 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1571 M_SRA_IMM(31, GET_HIGH_REG(d));
1572 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1573 M_SRA(GET_HIGH_REG(d));
1574 emit_store(jd, iptr, iptr->dst, d);
1577 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1578 /* val.i = constant */
1580 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1581 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1583 if (iptr->val.i & 0x20) {
1584 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1585 M_SRA_IMM(31, GET_HIGH_REG(d));
1586 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1589 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1590 M_SRA_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d));
1592 emit_store(jd, iptr, iptr->dst, d);
1595 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1597 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1598 s2 = emit_load_s2(jd, iptr, src, ECX);
1599 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1602 M_TEST_IMM(32, ECX);
1604 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1605 M_CLR(GET_HIGH_REG(d));
1606 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1607 M_SRL(GET_HIGH_REG(d));
1608 emit_store(jd, iptr, iptr->dst, d);
1611 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1612 /* val.l = constant */
1614 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1615 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1617 if (iptr->val.i & 0x20) {
1618 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1619 M_CLR(GET_HIGH_REG(d));
1620 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1623 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1624 M_SRL_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d));
1626 emit_store(jd, iptr, iptr->dst, d);
1629 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1631 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1632 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1633 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1640 emit_store(jd, iptr, iptr->dst, d);
1643 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1644 /* val.i = constant */
1646 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1647 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1649 M_AND_IMM(iptr->val.i, d);
1650 emit_store(jd, iptr, iptr->dst, d);
1653 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1655 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1656 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1657 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1658 if (s2 == GET_LOW_REG(d))
1659 M_AND(s1, GET_LOW_REG(d));
1661 M_INTMOVE(s1, GET_LOW_REG(d));
1662 M_AND(s2, GET_LOW_REG(d));
1664 /* REG_ITMP1 probably contains low 32-bit of destination */
1665 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1666 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1667 if (s2 == GET_HIGH_REG(d))
1668 M_AND(s1, GET_HIGH_REG(d));
1670 M_INTMOVE(s1, GET_HIGH_REG(d));
1671 M_AND(s2, GET_HIGH_REG(d));
1673 emit_store(jd, iptr, iptr->dst, d);
1676 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1677 /* val.l = constant */
1679 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1680 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1682 M_AND_IMM(iptr->val.l, GET_LOW_REG(d));
1683 M_AND_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1684 emit_store(jd, iptr, iptr->dst, d);
1687 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1689 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1691 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1698 emit_store(jd, iptr, iptr->dst, d);
1701 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1702 /* val.i = constant */
1704 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1705 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1707 M_OR_IMM(iptr->val.i, d);
1708 emit_store(jd, iptr, iptr->dst, d);
1711 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1713 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1714 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1715 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1716 if (s2 == GET_LOW_REG(d))
1717 M_OR(s1, GET_LOW_REG(d));
1719 M_INTMOVE(s1, GET_LOW_REG(d));
1720 M_OR(s2, GET_LOW_REG(d));
1722 /* REG_ITMP1 probably contains low 32-bit of destination */
1723 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1724 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1725 if (s2 == GET_HIGH_REG(d))
1726 M_OR(s1, GET_HIGH_REG(d));
1728 M_INTMOVE(s1, GET_HIGH_REG(d));
1729 M_OR(s2, GET_HIGH_REG(d));
1731 emit_store(jd, iptr, iptr->dst, d);
1734 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1735 /* val.l = constant */
1737 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1738 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1740 M_OR_IMM(iptr->val.l, GET_LOW_REG(d));
1741 M_OR_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1742 emit_store(jd, iptr, iptr->dst, d);
1745 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1747 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1748 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1749 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1756 emit_store(jd, iptr, iptr->dst, d);
1759 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1760 /* val.i = constant */
1762 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1763 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1765 M_XOR_IMM(iptr->val.i, d);
1766 emit_store(jd, iptr, iptr->dst, d);
1769 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1771 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1772 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1773 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1774 if (s2 == GET_LOW_REG(d))
1775 M_XOR(s1, GET_LOW_REG(d));
1777 M_INTMOVE(s1, GET_LOW_REG(d));
1778 M_XOR(s2, GET_LOW_REG(d));
1780 /* REG_ITMP1 probably contains low 32-bit of destination */
1781 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1782 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1783 if (s2 == GET_HIGH_REG(d))
1784 M_XOR(s1, GET_HIGH_REG(d));
1786 M_INTMOVE(s1, GET_HIGH_REG(d));
1787 M_XOR(s2, GET_HIGH_REG(d));
1789 emit_store(jd, iptr, iptr->dst, d);
1792 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1793 /* val.l = constant */
1795 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1796 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1798 M_XOR_IMM(iptr->val.l, GET_LOW_REG(d));
1799 M_XOR_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1800 emit_store(jd, iptr, iptr->dst, d);
1803 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1804 /* op1 = variable, val.i = constant */
1806 #if defined(ENABLE_SSA)
1809 /* with SSA in op1 is the source Local Var, in val._i.op1_t */
1810 /* the target Local Var, in val._i.i the constant */
1811 /* val._i.op1_t <- op1 + val._i.i */
1814 var = &(rd->locals[iptr->op1][TYPE_INT]);
1815 var_t = &(rd->locals[iptr->val._i.op1_t][TYPE_INT]);
1817 if (var->flags & INMEMORY) {
1818 if (!(var_t->flags & INMEMORY))
1822 M_ILD(s1, REG_SP, var->regoff * 4);
1827 /* `inc reg' is slower on p4's (regarding to ia32
1828 optimization reference manual and benchmarks) and as
1829 fast on athlon's. */
1831 M_IADD_IMM(iptr->val._i.i, s1);
1833 if (var_t->flags && INMEMORY)
1834 M_IST(s1, REG_SP, var_t->regoff * 4);
1835 else if (!(var_t->flags && INMEMORY))
1836 M_INTMOVE(s1, var_t->regoff);
1839 #endif /* defined(ENABLE_SSA) */
1841 var = &(rd->locals[iptr->op1][TYPE_INT]);
1842 if (var->flags & INMEMORY) {
1844 M_ILD(s1, REG_SP, var->regoff * 4);
1849 /* `inc reg' is slower on p4's (regarding to ia32
1850 optimization reference manual and benchmarks) and as
1851 fast on athlon's. */
1853 M_IADD_IMM(iptr->val.i, s1);
1855 if (var->flags & INMEMORY)
1856 M_IST(s1, REG_SP, var->regoff * 4);
1861 /* floating operations ************************************************/
1863 case ICMD_FNEG: /* ..., value ==> ..., - value */
1865 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1866 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1868 emit_store(jd, iptr, iptr->dst, d);
1871 case ICMD_DNEG: /* ..., value ==> ..., - value */
1873 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1874 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1876 emit_store(jd, iptr, iptr->dst, d);
1879 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1881 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1882 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1883 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1885 emit_store(jd, iptr, iptr->dst, d);
1888 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1890 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1891 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1892 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1894 emit_store(jd, iptr, iptr->dst, d);
1897 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1899 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1900 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1901 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1903 emit_store(jd, iptr, iptr->dst, d);
1906 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1908 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1909 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1910 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1912 emit_store(jd, iptr, iptr->dst, d);
1915 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1917 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1918 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1919 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1921 emit_store(jd, iptr, iptr->dst, d);
1924 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1926 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1927 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1928 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1930 emit_store(jd, iptr, iptr->dst, d);
1933 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1935 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1936 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1937 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1939 emit_store(jd, iptr, iptr->dst, d);
1942 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1944 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1945 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1946 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1948 emit_store(jd, iptr, iptr->dst, d);
1951 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1953 /* exchanged to skip fxch */
1954 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1955 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1956 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1957 /* emit_fxch(cd); */
1962 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1963 emit_store(jd, iptr, iptr->dst, d);
1964 emit_ffree_reg(cd, 0);
1968 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1970 /* exchanged to skip fxch */
1971 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1972 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1973 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1974 /* emit_fxch(cd); */
1979 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1980 emit_store(jd, iptr, iptr->dst, d);
1981 emit_ffree_reg(cd, 0);
1985 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1986 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1988 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1989 if (src->flags & INMEMORY) {
1990 emit_fildl_membase(cd, REG_SP, src->regoff * 4);
1993 disp = dseg_adds4(cd, 0);
1994 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1996 emit_mov_reg_membase(cd, src->regoff, REG_ITMP1, disp);
1997 emit_fildl_membase(cd, REG_ITMP1, disp);
1999 emit_store(jd, iptr, iptr->dst, d);
2002 case ICMD_L2F: /* ..., value ==> ..., (float) value */
2003 case ICMD_L2D: /* ..., value ==> ..., (double) value */
2005 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2006 if (src->flags & INMEMORY) {
2007 emit_fildll_membase(cd, REG_SP, src->regoff * 4);
2010 log_text("L2F: longs have to be in memory");
2013 emit_store(jd, iptr, iptr->dst, d);
2016 case ICMD_F2I: /* ..., value ==> ..., (int) value */
2018 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2019 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2021 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2024 /* Round to zero, 53-bit mode, exception masked */
2025 disp = dseg_adds4(cd, 0x0e7f);
2026 emit_fldcw_membase(cd, REG_ITMP1, disp);
2028 if (iptr->dst->flags & INMEMORY) {
2029 emit_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 4);
2031 /* Round to nearest, 53-bit mode, exceptions masked */
2032 disp = dseg_adds4(cd, 0x027f);
2033 emit_fldcw_membase(cd, REG_ITMP1, disp);
2035 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4);
2038 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2040 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2043 disp = dseg_adds4(cd, 0);
2044 emit_fistpl_membase(cd, REG_ITMP1, disp);
2045 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst->regoff);
2047 /* Round to nearest, 53-bit mode, exceptions masked */
2048 disp = dseg_adds4(cd, 0x027f);
2049 emit_fldcw_membase(cd, REG_ITMP1, disp);
2051 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst->regoff);
2054 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2055 disp += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2058 emit_jcc(cd, CC_NE, disp);
2060 /* XXX: change this when we use registers */
2061 emit_flds_membase(cd, REG_SP, src->regoff * 4);
2062 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
2063 emit_call_reg(cd, REG_ITMP1);
2065 if (iptr->dst->flags & INMEMORY) {
2066 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2069 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2073 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2075 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2076 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2078 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2081 /* Round to zero, 53-bit mode, exception masked */
2082 disp = dseg_adds4(cd, 0x0e7f);
2083 emit_fldcw_membase(cd, REG_ITMP1, disp);
2085 if (iptr->dst->flags & INMEMORY) {
2086 emit_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 4);
2088 /* Round to nearest, 53-bit mode, exceptions masked */
2089 disp = dseg_adds4(cd, 0x027f);
2090 emit_fldcw_membase(cd, REG_ITMP1, disp);
2092 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4);
2095 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2097 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2100 disp = dseg_adds4(cd, 0);
2101 emit_fistpl_membase(cd, REG_ITMP1, disp);
2102 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst->regoff);
2104 /* Round to nearest, 53-bit mode, exceptions masked */
2105 disp = dseg_adds4(cd, 0x027f);
2106 emit_fldcw_membase(cd, REG_ITMP1, disp);
2108 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst->regoff);
2111 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2112 disp += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2115 emit_jcc(cd, CC_NE, disp);
2117 /* XXX: change this when we use registers */
2118 emit_fldl_membase(cd, REG_SP, src->regoff * 4);
2119 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
2120 emit_call_reg(cd, REG_ITMP1);
2122 if (iptr->dst->flags & INMEMORY) {
2123 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2125 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2129 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2131 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2132 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2134 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2137 /* Round to zero, 53-bit mode, exception masked */
2138 disp = dseg_adds4(cd, 0x0e7f);
2139 emit_fldcw_membase(cd, REG_ITMP1, disp);
2141 if (iptr->dst->flags & INMEMORY) {
2142 emit_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 4);
2144 /* Round to nearest, 53-bit mode, exceptions masked */
2145 disp = dseg_adds4(cd, 0x027f);
2146 emit_fldcw_membase(cd, REG_ITMP1, disp);
2148 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4 + 4);
2151 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2153 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2156 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2158 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4 + 4);
2160 emit_jcc(cd, CC_NE, disp);
2162 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst->regoff * 4);
2165 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2167 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2169 emit_jcc(cd, CC_NE, disp);
2171 /* XXX: change this when we use registers */
2172 emit_flds_membase(cd, REG_SP, src->regoff * 4);
2173 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
2174 emit_call_reg(cd, REG_ITMP1);
2175 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2176 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
2179 log_text("F2L: longs have to be in memory");
2184 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2186 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2187 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2189 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2192 /* Round to zero, 53-bit mode, exception masked */
2193 disp = dseg_adds4(cd, 0x0e7f);
2194 emit_fldcw_membase(cd, REG_ITMP1, disp);
2196 if (iptr->dst->flags & INMEMORY) {
2197 emit_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 4);
2199 /* Round to nearest, 53-bit mode, exceptions masked */
2200 disp = dseg_adds4(cd, 0x027f);
2201 emit_fldcw_membase(cd, REG_ITMP1, disp);
2203 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4 + 4);
2206 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2208 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2211 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2213 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4 + 4);
2215 emit_jcc(cd, CC_NE, disp);
2217 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst->regoff * 4);
2220 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2222 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2224 emit_jcc(cd, CC_NE, disp);
2226 /* XXX: change this when we use registers */
2227 emit_fldl_membase(cd, REG_SP, src->regoff * 4);
2228 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
2229 emit_call_reg(cd, REG_ITMP1);
2230 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2231 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
2234 log_text("D2L: longs have to be in memory");
2239 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2241 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2242 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2244 emit_store(jd, iptr, iptr->dst, d);
2247 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2249 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2250 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2252 emit_store(jd, iptr, iptr->dst, d);
2255 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2258 /* exchanged to skip fxch */
2259 s2 = emit_load_s2(jd, iptr, src->prev, REG_FTMP1);
2260 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2261 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2262 /* emit_fxch(cd); */
2265 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
2266 emit_jcc(cd, CC_E, 6);
2267 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
2269 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2270 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2271 emit_jcc(cd, CC_B, 3 + 5);
2272 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2273 emit_jmp_imm(cd, 3);
2274 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2275 emit_store(jd, iptr, iptr->dst, d);
2278 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2281 /* exchanged to skip fxch */
2282 s2 = emit_load_s2(jd, iptr, src->prev, REG_FTMP1);
2283 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2284 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2285 /* emit_fxch(cd); */
2288 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
2289 emit_jcc(cd, CC_E, 3);
2290 emit_movb_imm_reg(cd, 1, REG_AH);
2292 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2293 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2294 emit_jcc(cd, CC_B, 3 + 5);
2295 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2296 emit_jmp_imm(cd, 3);
2297 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2298 emit_store(jd, iptr, iptr->dst, d);
2302 /* memory operations **************************************************/
2304 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2306 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2307 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2308 gen_nullptr_check(s1);
2309 M_ILD(d, s1, OFFSET(java_arrayheader, size));
2310 emit_store(jd, iptr, iptr->dst, d);
2313 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2315 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2316 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2317 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2318 if (iptr->op1 == 0) {
2319 gen_nullptr_check(s1);
2322 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2323 emit_store(jd, iptr, iptr->dst, d);
2326 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2328 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2329 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2330 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2331 if (iptr->op1 == 0) {
2332 gen_nullptr_check(s1);
2335 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2336 emit_store(jd, iptr, iptr->dst, d);
2339 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2341 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2342 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2343 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2344 if (iptr->op1 == 0) {
2345 gen_nullptr_check(s1);
2348 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2349 emit_store(jd, iptr, iptr->dst, d);
2352 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2354 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2355 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2356 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2357 if (iptr->op1 == 0) {
2358 gen_nullptr_check(s1);
2361 emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2362 emit_store(jd, iptr, iptr->dst, d);
2365 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2367 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2368 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2369 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
2370 if (iptr->op1 == 0) {
2371 gen_nullptr_check(s1);
2374 assert(iptr->dst->flags & INMEMORY);
2375 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2376 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 4);
2377 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2378 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 4 + 4);
2381 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2383 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2384 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2385 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2386 if (iptr->op1 == 0) {
2387 gen_nullptr_check(s1);
2390 emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2391 emit_store(jd, iptr, iptr->dst, d);
2394 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2396 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2397 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2398 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2399 if (iptr->op1 == 0) {
2400 gen_nullptr_check(s1);
2403 emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2404 emit_store(jd, iptr, iptr->dst, d);
2407 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2409 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2410 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2411 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2412 if (iptr->op1 == 0) {
2413 gen_nullptr_check(s1);
2416 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2417 emit_store(jd, iptr, iptr->dst, d);
2421 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2423 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2424 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2425 if (iptr->op1 == 0) {
2426 gen_nullptr_check(s1);
2429 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2430 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2431 M_INTMOVE(s3, REG_ITMP3);
2434 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2437 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2439 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2440 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2441 if (iptr->op1 == 0) {
2442 gen_nullptr_check(s1);
2445 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2446 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2449 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2451 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2452 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2453 if (iptr->op1 == 0) {
2454 gen_nullptr_check(s1);
2457 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2458 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2461 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2463 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2464 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2465 if (iptr->op1 == 0) {
2466 gen_nullptr_check(s1);
2469 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2470 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2473 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2475 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2476 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2477 if (iptr->op1 == 0) {
2478 gen_nullptr_check(s1);
2481 assert(src->flags & INMEMORY);
2482 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP3);
2483 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2484 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP3);
2485 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2488 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2490 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2491 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2492 if (iptr->op1 == 0) {
2493 gen_nullptr_check(s1);
2496 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
2497 emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2500 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2502 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2503 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2504 if (iptr->op1 == 0) {
2505 gen_nullptr_check(s1);
2508 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
2509 emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2512 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2514 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2515 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2516 if (iptr->op1 == 0) {
2517 gen_nullptr_check(s1);
2520 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2522 M_AST(s1, REG_SP, 0 * 4);
2523 M_AST(s3, REG_SP, 1 * 4);
2524 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2528 codegen_add_arraystoreexception_ref(cd);
2530 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2531 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2532 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2533 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2536 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2538 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2539 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2540 if (iptr->op1 == 0) {
2541 gen_nullptr_check(s1);
2544 emit_movb_imm_memindex(cd, iptr->val.i, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2547 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2549 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2550 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2551 if (iptr->op1 == 0) {
2552 gen_nullptr_check(s1);
2555 emit_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_chararray, data[0]), s1, s2, 1);
2558 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2560 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2561 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2562 if (iptr->op1 == 0) {
2563 gen_nullptr_check(s1);
2566 emit_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2569 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2571 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2572 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2573 if (iptr->op1 == 0) {
2574 gen_nullptr_check(s1);
2577 emit_mov_imm_memindex(cd, iptr->val.i, OFFSET(java_intarray, data[0]), s1, s2, 2);
2580 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2582 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2583 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2584 if (iptr->op1 == 0) {
2585 gen_nullptr_check(s1);
2588 emit_mov_imm_memindex(cd, (u4) (iptr->val.l & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2589 emit_mov_imm_memindex(cd, (u4) (iptr->val.l >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2592 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2594 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2595 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2596 if (iptr->op1 == 0) {
2597 gen_nullptr_check(s1);
2600 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2604 case ICMD_GETSTATIC: /* ... ==> ..., value */
2605 /* op1 = type, val.a = field address */
2607 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2608 codegen_addpatchref(cd, PATCHER_get_putstatic,
2609 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2611 if (opt_showdisassemble) {
2612 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2619 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2621 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2622 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2624 if (opt_showdisassemble) {
2625 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2629 disp = (ptrint) &(fi->value);
2632 M_MOV_IMM(disp, REG_ITMP1);
2633 switch (iptr->op1) {
2636 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2637 M_ILD(d, REG_ITMP1, 0);
2640 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP23_PACKED);
2641 M_LLD(d, REG_ITMP1, 0);
2644 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2645 M_FLD(d, REG_ITMP1, 0);
2648 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2649 M_DLD(d, REG_ITMP1, 0);
2652 emit_store(jd, iptr, iptr->dst, d);
2655 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2656 /* op1 = type, val.a = field address */
2658 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2659 codegen_addpatchref(cd, PATCHER_get_putstatic,
2660 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2662 if (opt_showdisassemble) {
2663 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2670 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2672 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2673 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2675 if (opt_showdisassemble) {
2676 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2680 disp = (ptrint) &(fi->value);
2683 M_MOV_IMM(disp, REG_ITMP1);
2684 switch (iptr->op1) {
2687 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2688 M_IST(s2, REG_ITMP1, 0);
2691 s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
2692 M_LST(s2, REG_ITMP1, 0);
2695 s2 = emit_load_s2(jd, iptr, src, REG_FTMP1);
2696 emit_fstps_membase(cd, REG_ITMP1, 0);
2699 s2 = emit_load_s2(jd, iptr, src, REG_FTMP1);
2700 emit_fstpl_membase(cd, REG_ITMP1, 0);
2705 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2706 /* val = value (in current instruction) */
2707 /* op1 = type, val.a = field address (in */
2708 /* following NOP) */
2710 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2711 codegen_addpatchref(cd, PATCHER_get_putstatic,
2712 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2714 if (opt_showdisassemble) {
2715 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2722 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2724 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2725 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2727 if (opt_showdisassemble) {
2728 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2732 disp = (ptrint) &(fi->value);
2735 M_MOV_IMM(disp, REG_ITMP1);
2736 switch (iptr[1].op1) {
2740 M_IST_IMM(iptr->val.i, REG_ITMP1, 0);
2744 M_LST_IMM(iptr->val.l, REG_ITMP1, 0);
2749 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2750 /* op1 = type, val.i = field offset */
2752 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2753 gen_nullptr_check(s1);
2755 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2756 codegen_addpatchref(cd, PATCHER_getfield,
2757 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2759 if (opt_showdisassemble) {
2760 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2767 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2769 switch (iptr->op1) {
2772 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2773 M_ILD32(d, s1, disp);
2776 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP23_PACKED);
2777 M_LLD32(d, s1, disp);
2780 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2781 M_FLD32(d, s1, disp);
2784 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2785 M_DLD32(d, s1, disp);
2788 emit_store(jd, iptr, iptr->dst, d);
2791 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2792 /* op1 = type, val.a = field address */
2794 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2795 gen_nullptr_check(s1);
2797 /* must be done here because of code patching */
2799 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2800 if (IS_2_WORD_TYPE(iptr->op1))
2801 s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
2803 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2806 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2808 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2809 codegen_addpatchref(cd, PATCHER_putfield,
2810 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2812 if (opt_showdisassemble) {
2813 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2820 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2822 switch (iptr->op1) {
2825 M_IST32(s2, s1, disp);
2828 M_LST32(s2, s1, disp);
2831 emit_fstps_membase32(cd, s1, disp);
2834 emit_fstpl_membase32(cd, s1, disp);
2839 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2840 /* val = value (in current instruction) */
2841 /* op1 = type, val.a = field address (in */
2842 /* following NOP) */
2844 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2845 gen_nullptr_check(s1);
2847 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2848 codegen_addpatchref(cd, PATCHER_putfieldconst,
2849 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2851 if (opt_showdisassemble) {
2852 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2859 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2861 switch (iptr[1].op1) {
2865 M_IST32_IMM(iptr->val.i, s1, disp);
2869 M_LST32_IMM(iptr->val.l, s1, disp);
2875 /* branch operations **************************************************/
2877 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2879 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2880 M_INTMOVE(s1, REG_ITMP1_XPTR);
2882 #ifdef ENABLE_VERIFIER
2884 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2885 (unresolved_class *) iptr->val.a, 0);
2887 if (opt_showdisassemble) {
2888 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2891 #endif /* ENABLE_VERIFIER */
2893 M_CALL_IMM(0); /* passing exception pc */
2894 M_POP(REG_ITMP2_XPC);
2896 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2900 case ICMD_INLINE_GOTO:
2902 M_COPY(src, iptr->dst);
2905 case ICMD_GOTO: /* ... ==> ... */
2906 /* op1 = target JavaVM pc */
2908 #if defined(ENABLE_SSA)
2910 last_cmd_was_goto = true;
2911 /* In case of a Goto phimoves have to be inserted before the */
2913 codegen_insert_phi_moves(cd, rd, ls, bptr);
2917 codegen_addreference(cd, (basicblock *) iptr->target);
2921 case ICMD_JSR: /* ... ==> ... */
2922 /* op1 = target JavaVM pc */
2925 codegen_addreference(cd, (basicblock *) iptr->target);
2928 case ICMD_RET: /* ... ==> ... */
2929 /* op1 = local variable */
2931 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2932 if (var->flags & INMEMORY) {
2933 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2940 case ICMD_IFNULL: /* ..., value ==> ... */
2941 /* op1 = target JavaVM pc */
2943 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2946 codegen_addreference(cd, (basicblock *) iptr->target);
2949 case ICMD_IFNONNULL: /* ..., value ==> ... */
2950 /* op1 = target JavaVM pc */
2952 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2955 codegen_addreference(cd, (basicblock *) iptr->target);
2958 case ICMD_IFEQ: /* ..., value ==> ... */
2959 /* op1 = target JavaVM pc, val.i = constant */
2961 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2962 M_CMP_IMM(iptr->val.i, s1);
2964 codegen_addreference(cd, (basicblock *) iptr->target);
2967 case ICMD_IFLT: /* ..., value ==> ... */
2968 /* op1 = target JavaVM pc, val.i = constant */
2970 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2971 M_CMP_IMM(iptr->val.i, s1);
2973 codegen_addreference(cd, (basicblock *) iptr->target);
2976 case ICMD_IFLE: /* ..., value ==> ... */
2977 /* op1 = target JavaVM pc, val.i = constant */
2979 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2980 M_CMP_IMM(iptr->val.i, s1);
2982 codegen_addreference(cd, (basicblock *) iptr->target);
2985 case ICMD_IFNE: /* ..., value ==> ... */
2986 /* op1 = target JavaVM pc, val.i = constant */
2988 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2989 M_CMP_IMM(iptr->val.i, s1);
2991 codegen_addreference(cd, (basicblock *) iptr->target);
2994 case ICMD_IFGT: /* ..., value ==> ... */
2995 /* op1 = target JavaVM pc, val.i = constant */
2997 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2998 M_CMP_IMM(iptr->val.i, s1);
3000 codegen_addreference(cd, (basicblock *) iptr->target);
3003 case ICMD_IFGE: /* ..., value ==> ... */
3004 /* op1 = target JavaVM pc, val.i = constant */
3006 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3007 M_CMP_IMM(iptr->val.i, s1);
3009 codegen_addreference(cd, (basicblock *) iptr->target);
3012 case ICMD_IF_LEQ: /* ..., value ==> ... */
3013 /* op1 = target JavaVM pc, val.l = constant */
3015 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3016 if (iptr->val.l == 0) {
3017 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3018 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3021 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3022 M_XOR_IMM(iptr->val.l, REG_ITMP1);
3023 M_XOR_IMM(iptr->val.l >> 32, REG_ITMP2);
3024 M_OR(REG_ITMP2, REG_ITMP1);
3027 codegen_addreference(cd, (basicblock *) iptr->target);
3030 case ICMD_IF_LLT: /* ..., value ==> ... */
3031 /* op1 = target JavaVM pc, val.l = constant */
3033 if (iptr->val.l == 0) {
3034 /* If high 32-bit are less than zero, then the 64-bits
3036 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
3041 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3042 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3044 codegen_addreference(cd, (basicblock *) iptr->target);
3046 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3049 codegen_addreference(cd, (basicblock *) iptr->target);
3052 case ICMD_IF_LLE: /* ..., value ==> ... */
3053 /* op1 = target JavaVM pc, val.l = constant */
3055 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3056 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3058 codegen_addreference(cd, (basicblock *) iptr->target);
3060 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3062 codegen_addreference(cd, (basicblock *) iptr->target);
3065 case ICMD_IF_LNE: /* ..., value ==> ... */
3066 /* op1 = target JavaVM pc, val.l = constant */
3068 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3069 if (iptr->val.l == 0) {
3070 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3071 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3074 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3075 M_XOR_IMM(iptr->val.l, REG_ITMP1);
3076 M_XOR_IMM(iptr->val.l >> 32, REG_ITMP2);
3077 M_OR(REG_ITMP2, REG_ITMP1);
3080 codegen_addreference(cd, (basicblock *) iptr->target);
3083 case ICMD_IF_LGT: /* ..., value ==> ... */
3084 /* op1 = target JavaVM pc, val.l = constant */
3086 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3087 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3089 codegen_addreference(cd, (basicblock *) iptr->target);
3091 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3093 codegen_addreference(cd, (basicblock *) iptr->target);
3096 case ICMD_IF_LGE: /* ..., value ==> ... */
3097 /* op1 = target JavaVM pc, val.l = constant */
3099 if (iptr->val.l == 0) {
3100 /* If high 32-bit are greater equal zero, then the
3102 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
3107 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3108 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3110 codegen_addreference(cd, (basicblock *) iptr->target);
3112 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3115 codegen_addreference(cd, (basicblock *) iptr->target);
3118 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3119 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3121 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3122 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3125 codegen_addreference(cd, (basicblock *) iptr->target);
3128 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3129 /* op1 = target JavaVM pc */
3131 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3132 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3133 M_INTMOVE(s1, REG_ITMP1);
3134 M_XOR(s2, REG_ITMP1);
3135 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
3136 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
3137 M_INTMOVE(s1, REG_ITMP2);
3138 M_XOR(s2, REG_ITMP2);
3139 M_OR(REG_ITMP1, REG_ITMP2);
3141 codegen_addreference(cd, (basicblock *) iptr->target);
3144 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3145 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3147 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3148 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3151 codegen_addreference(cd, (basicblock *) iptr->target);
3154 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3155 /* op1 = target JavaVM pc */
3157 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3158 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3159 M_INTMOVE(s1, REG_ITMP1);
3160 M_XOR(s2, REG_ITMP1);
3161 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
3162 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
3163 M_INTMOVE(s1, REG_ITMP2);
3164 M_XOR(s2, REG_ITMP2);
3165 M_OR(REG_ITMP1, REG_ITMP2);
3167 codegen_addreference(cd, (basicblock *) iptr->target);
3170 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3171 /* op1 = target JavaVM pc */
3173 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3174 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3177 codegen_addreference(cd, (basicblock *) iptr->target);
3180 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3181 /* op1 = target JavaVM pc */
3183 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3184 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3187 codegen_addreference(cd, (basicblock *) iptr->target);
3188 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3189 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3193 codegen_addreference(cd, (basicblock *) iptr->target);
3196 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3197 /* op1 = target JavaVM pc */
3199 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3200 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3203 codegen_addreference(cd, (basicblock *) iptr->target);
3206 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3207 /* op1 = target JavaVM pc */
3209 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3210 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3213 codegen_addreference(cd, (basicblock *) iptr->target);
3214 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3215 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3219 codegen_addreference(cd, (basicblock *) iptr->target);
3222 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3223 /* op1 = target JavaVM pc */
3225 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3226 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3229 codegen_addreference(cd, (basicblock *) iptr->target);
3232 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3233 /* op1 = target JavaVM pc */
3235 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3236 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3239 codegen_addreference(cd, (basicblock *) iptr->target);
3240 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3241 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3245 codegen_addreference(cd, (basicblock *) iptr->target);
3248 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3249 /* op1 = target JavaVM pc */
3251 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3252 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3255 codegen_addreference(cd, (basicblock *) iptr->target);
3258 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3259 /* op1 = target JavaVM pc */
3261 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3262 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3265 codegen_addreference(cd, (basicblock *) iptr->target);
3266 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3267 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3271 codegen_addreference(cd, (basicblock *) iptr->target);
3275 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3277 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3278 M_INTMOVE(s1, REG_RESULT);
3279 goto nowperformreturn;
3281 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3283 s1 = emit_load_s1(jd, iptr, src, REG_RESULT_PACKED);
3284 M_LNGMOVE(s1, REG_RESULT_PACKED);
3285 goto nowperformreturn;
3287 case ICMD_ARETURN: /* ..., retvalue ==> ... */
3289 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3290 M_INTMOVE(s1, REG_RESULT);
3292 #ifdef ENABLE_VERIFIER
3294 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3295 (unresolved_class *) iptr->val.a, 0);
3297 if (opt_showdisassemble) {
3298 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3301 #endif /* ENABLE_VERIFIER */
3302 goto nowperformreturn;
3304 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3307 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
3308 goto nowperformreturn;
3310 case ICMD_RETURN: /* ... ==> ... */
3318 #if !defined(NDEBUG)
3319 /* call trace function */
3321 if (opt_verbosecall) {
3322 M_ISUB_IMM(4 + 8 + 8 + 4, REG_SP);
3324 emit_mov_imm_membase(cd, (s4) m, REG_SP, 0);
3326 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, 4);
3327 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, 4 + 4);
3329 emit_fstl_membase(cd, REG_SP, 4 + 8);
3330 emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
3332 emit_mov_imm_reg(cd, (s4) builtin_displaymethodstop, REG_ITMP1);
3333 emit_call_reg(cd, REG_ITMP1);
3335 emit_mov_membase_reg(cd, REG_SP, 4, REG_RESULT);
3336 emit_mov_membase_reg(cd, REG_SP, 4 + 4, REG_RESULT2);
3338 emit_alu_imm_reg(cd, ALU_ADD, 4 + 8 + 8 + 4, REG_SP);
3340 #endif /* !defined(NDEBUG) */
3342 #if defined(ENABLE_THREADS)
3343 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3344 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3346 /* we need to save the proper return value */
3347 switch (iptr->opc) {
3350 M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3354 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3358 emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3362 emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3366 M_AST(REG_ITMP2, REG_SP, 0);
3367 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3370 /* and now restore the proper return value */
3371 switch (iptr->opc) {
3374 M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3378 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3382 emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3386 emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3392 /* restore saved registers */
3394 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3395 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3398 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3400 emit_fldl_membase(cd, REG_SP, p * 4);
3401 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3403 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3406 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3410 /* deallocate stack */
3413 M_AADD_IMM(stackframesize * 4, REG_SP);
3420 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3425 tptr = (void **) iptr->target;
3427 s4ptr = iptr->val.a;
3428 l = s4ptr[1]; /* low */
3429 i = s4ptr[2]; /* high */
3431 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3432 M_INTMOVE(s1, REG_ITMP1);
3435 M_ISUB_IMM(l, REG_ITMP1);
3441 M_CMP_IMM(i - 1, REG_ITMP1);
3443 codegen_addreference(cd, (basicblock *) tptr[0]);
3445 /* build jump table top down and use address of lowest entry */
3450 dseg_addtarget(cd, (basicblock *) tptr[0]);
3454 /* length of dataseg after last dseg_addtarget is used
3457 M_MOV_IMM(0, REG_ITMP2);
3459 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3465 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3467 s4 i, l, val, *s4ptr;
3470 tptr = (void **) iptr->target;
3472 s4ptr = iptr->val.a;
3473 l = s4ptr[0]; /* default */
3474 i = s4ptr[1]; /* count */
3476 MCODECHECK((i<<2)+8);
3477 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3486 codegen_addreference(cd, (basicblock *) tptr[0]);
3491 tptr = (void **) iptr->target;
3492 codegen_addreference(cd, (basicblock *) tptr[0]);
3496 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
3497 /* op1 = arg count val.a = builtintable entry */
3503 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3504 /* op1 = arg count, val.a = method pointer */
3506 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3507 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3508 case ICMD_INVOKEINTERFACE:
3510 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3511 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3515 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3516 md = lm->parseddesc;
3520 s3 = md->paramcount;
3522 MCODECHECK((s3 << 1) + 64);
3524 /* copy arguments to registers or stack location */
3526 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3527 if (src->varkind == ARGVAR)
3529 if (IS_INT_LNG_TYPE(src->type)) {
3530 if (!md->params[s3].inmemory) {
3531 log_text("No integer argument registers available!");
3535 if (IS_2_WORD_TYPE(src->type)) {
3536 d = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3537 M_LST(d, REG_SP, md->params[s3].regoff * 4);
3539 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3540 M_IST(d, REG_SP, md->params[s3].regoff * 4);
3545 if (!md->params[s3].inmemory) {
3546 s1 = rd->argfltregs[md->params[s3].regoff];
3547 d = emit_load_s1(jd, iptr, src, s1);
3551 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3552 if (IS_2_WORD_TYPE(src->type))
3553 M_DST(d, REG_SP, md->params[s3].regoff * 4);
3555 M_FST(d, REG_SP, md->params[s3].regoff * 4);
3560 switch (iptr->opc) {
3562 disp = (ptrint) bte->fp;
3563 d = md->returntype.type;
3565 M_MOV_IMM(disp, REG_ITMP1);
3568 /* if op1 == true, we need to check for an exception */
3570 if (iptr->op1 == true) {
3573 codegen_add_fillinstacktrace_ref(cd);
3577 case ICMD_INVOKESPECIAL:
3578 M_ALD(REG_ITMP1, REG_SP, 0);
3581 codegen_add_nullpointerexception_ref(cd);
3585 case ICMD_INVOKESTATIC:
3587 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3589 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3592 if (opt_showdisassemble) {
3593 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3597 d = md->returntype.type;
3600 disp = (ptrint) lm->stubroutine;
3601 d = lm->parseddesc->returntype.type;
3604 M_MOV_IMM(disp, REG_ITMP2);
3608 case ICMD_INVOKEVIRTUAL:
3609 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3610 gen_nullptr_check(REG_ITMP1);
3613 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3615 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3617 if (opt_showdisassemble) {
3618 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3622 d = md->returntype.type;
3625 s1 = OFFSET(vftbl_t, table[0]) +
3626 sizeof(methodptr) * lm->vftblindex;
3627 d = md->returntype.type;
3630 M_ALD(REG_METHODPTR, REG_ITMP1,
3631 OFFSET(java_objectheader, vftbl));
3632 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3636 case ICMD_INVOKEINTERFACE:
3637 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3638 gen_nullptr_check(REG_ITMP1);
3641 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3643 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3645 if (opt_showdisassemble) {
3646 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3651 d = md->returntype.type;
3654 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3655 sizeof(methodptr) * lm->class->index;
3657 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3659 d = md->returntype.type;
3662 M_ALD(REG_METHODPTR, REG_ITMP1,
3663 OFFSET(java_objectheader, vftbl));
3664 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3665 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3670 /* d contains return type */
3672 if (d != TYPE_VOID) {
3673 #if defined(ENABLE_SSA)
3674 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
3675 (ls->lifetime[-iptr->dst->varnum-1].type != -1))
3676 /* a "living" stackslot */
3679 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3680 if (IS_2_WORD_TYPE(iptr->dst->type)) {
3681 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
3682 M_LNGMOVE(REG_RESULT_PACKED, s1);
3685 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3686 M_INTMOVE(REG_RESULT, s1);
3690 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3692 emit_store(jd, iptr, iptr->dst, s1);
3698 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3699 /* op1: 0 == array, 1 == class */
3700 /* val.a: (classinfo*) superclass */
3702 /* superclass is an interface:
3704 * OK if ((sub == NULL) ||
3705 * (sub->vftbl->interfacetablelength > super->index) &&
3706 * (sub->vftbl->interfacetable[-super->index] != NULL));
3708 * superclass is a class:
3710 * OK if ((sub == NULL) || (0
3711 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3712 * super->vftbl->diffval));
3715 if (iptr->op1 == 1) {
3716 /* object type cast-check */
3719 vftbl_t *supervftbl;
3722 super = (classinfo *) iptr->val.a;
3729 superindex = super->index;
3730 supervftbl = super->vftbl;
3733 #if defined(ENABLE_THREADS)
3734 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3736 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3738 /* calculate interface checkcast code size */
3740 s2 = 2; /* mov_membase_reg */
3741 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3743 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3744 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3745 2 /* test */ + 6 /* jcc */);
3748 s2 += (opt_showdisassemble ? 5 : 0);
3750 /* calculate class checkcast code size */
3752 s3 = 2; /* mov_membase_reg */
3753 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3755 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3758 if (s1 != REG_ITMP1) {
3760 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3763 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3770 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3771 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3772 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3775 s3 += 2 /* cmp */ + 6 /* jcc */;
3778 s3 += (opt_showdisassemble ? 5 : 0);
3780 /* if class is not resolved, check which code to call */
3782 if (super == NULL) {
3784 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3786 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3787 (constant_classref *) iptr->target, 0);
3789 if (opt_showdisassemble) {
3790 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3793 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3794 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3798 /* interface checkcast code */
3800 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3801 if (super != NULL) {
3806 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3808 if (super == NULL) {
3809 codegen_addpatchref(cd,
3810 PATCHER_checkcast_instanceof_interface,
3811 (constant_classref *) iptr->target,
3814 if (opt_showdisassemble) {
3815 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3820 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3821 M_ISUB_IMM32(superindex, REG_ITMP3);
3824 codegen_add_classcastexception_ref(cd, s1);
3825 M_ALD32(REG_ITMP3, REG_ITMP2,
3826 OFFSET(vftbl_t, interfacetable[0]) -
3827 superindex * sizeof(methodptr*));
3830 codegen_add_classcastexception_ref(cd, s1);
3836 /* class checkcast code */
3838 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3839 if (super != NULL) {
3844 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3846 if (super == NULL) {
3847 codegen_addpatchref(cd, PATCHER_checkcast_class,
3848 (constant_classref *) iptr->target,
3851 if (opt_showdisassemble) {
3852 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3856 M_MOV_IMM(supervftbl, REG_ITMP3);
3857 #if defined(ENABLE_THREADS)
3858 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3860 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3862 /* if (s1 != REG_ITMP1) { */
3863 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3864 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3865 /* #if defined(ENABLE_THREADS) */
3866 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3868 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3871 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3872 M_ISUB(REG_ITMP3, REG_ITMP2);
3873 M_MOV_IMM(supervftbl, REG_ITMP3);
3874 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3875 #if defined(ENABLE_THREADS)
3876 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3880 M_CMP(REG_ITMP3, REG_ITMP2);
3881 M_BA(0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3882 codegen_add_classcastexception_ref(cd, s1);
3885 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
3888 /* array type cast-check */
3890 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3891 M_AST(s1, REG_SP, 0 * 4);
3893 if (iptr->val.a == NULL) {
3894 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3897 if (opt_showdisassemble) {
3898 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3902 M_AST_IMM(iptr->val.a, REG_SP, 1 * 4);
3903 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3906 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3909 codegen_add_classcastexception_ref(cd, s1);
3911 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3915 emit_store(jd, iptr, iptr->dst, d);
3918 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3919 /* op1: 0 == array, 1 == class */
3920 /* val.a: (classinfo*) superclass */
3922 /* superclass is an interface:
3924 * return (sub != NULL) &&
3925 * (sub->vftbl->interfacetablelength > super->index) &&
3926 * (sub->vftbl->interfacetable[-super->index] != NULL);
3928 * superclass is a class:
3930 * return ((sub != NULL) && (0
3931 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3932 * super->vftbl->diffvall));
3937 vftbl_t *supervftbl;
3940 super = (classinfo *) iptr->val.a;
3947 superindex = super->index;
3948 supervftbl = super->vftbl;
3951 #if defined(ENABLE_THREADS)
3952 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3955 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3956 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3958 M_INTMOVE(s1, REG_ITMP1);
3962 /* calculate interface instanceof code size */
3964 s2 = 2; /* mov_membase_reg */
3965 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3967 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3968 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3969 2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3972 s2 += (opt_showdisassemble ? 5 : 0);
3974 /* calculate class instanceof code size */
3976 s3 = 2; /* mov_membase_reg */
3977 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3978 s3 += 5; /* mov_imm_reg */
3980 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3982 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3984 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3986 s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3987 2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3990 s3 += (opt_showdisassemble ? 5 : 0);
3994 /* if class is not resolved, check which code to call */
3998 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
4000 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
4001 (constant_classref *) iptr->target, 0);
4003 if (opt_showdisassemble) {
4004 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4007 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
4008 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
4012 /* interface instanceof code */
4014 if (!super || (super->flags & ACC_INTERFACE)) {
4020 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
4023 codegen_addpatchref(cd,
4024 PATCHER_checkcast_instanceof_interface,
4025 (constant_classref *) iptr->target, 0);
4027 if (opt_showdisassemble) {
4028 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4033 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
4034 M_ISUB_IMM32(superindex, REG_ITMP3);
4037 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
4038 6 /* jcc */ + 5 /* mov_imm_reg */);
4041 M_ALD32(REG_ITMP1, REG_ITMP1,
4042 OFFSET(vftbl_t, interfacetable[0]) -
4043 superindex * sizeof(methodptr*));
4045 /* emit_setcc_reg(cd, CC_A, d); */
4046 /* emit_jcc(cd, CC_BE, 5); */
4054 /* class instanceof code */
4056 if (!super || !(super->flags & ACC_INTERFACE)) {
4062 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
4065 codegen_addpatchref(cd, PATCHER_instanceof_class,
4066 (constant_classref *) iptr->target, 0);
4068 if (opt_showdisassemble) {
4069 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4073 M_MOV_IMM(supervftbl, REG_ITMP2);
4074 #if defined(ENABLE_THREADS)
4075 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4077 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
4078 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
4079 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
4080 #if defined(ENABLE_THREADS)
4081 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4083 M_ISUB(REG_ITMP2, REG_ITMP1);
4084 M_CLR(d); /* may be REG_ITMP2 */
4085 M_CMP(REG_ITMP3, REG_ITMP1);
4089 emit_store(jd, iptr, iptr->dst, d);
4095 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4096 /* op1 = dimension, val.a = class */
4098 /* check for negative sizes and copy sizes to stack if necessary */
4100 MCODECHECK((iptr->op1 << 1) + 64);
4102 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4103 /* copy SAVEDVAR sizes to stack */
4105 if (src->varkind != ARGVAR) {
4106 if (src->flags & INMEMORY) {
4107 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
4108 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
4111 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
4115 /* is a patcher function set? */
4117 if (iptr->val.a == NULL) {
4118 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4119 (constant_classref *) iptr->target, 0);
4121 if (opt_showdisassemble) {
4122 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4129 disp = (ptrint) iptr->val.a;
4131 /* a0 = dimension count */
4133 M_IST_IMM(iptr->op1, REG_SP, 0 * 4);
4135 /* a1 = arraydescriptor */
4137 M_IST_IMM(disp, REG_SP, 1 * 4);
4139 /* a2 = pointer to dimensions = stack pointer */
4141 M_MOV(REG_SP, REG_ITMP1);
4142 M_AADD_IMM(3 * 4, REG_ITMP1);
4143 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4145 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4148 /* check for exception before result assignment */
4152 codegen_add_fillinstacktrace_ref(cd);
4154 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
4155 M_INTMOVE(REG_RESULT, s1);
4156 emit_store(jd, iptr, iptr->dst, s1);
4161 new_internalerror("Unknown ICMD %d", iptr->opc);
4165 } /* for instruction */
4167 /* copy values to interface registers */
4169 src = bptr->outstack;
4170 len = bptr->outdepth;
4172 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4175 #if defined(ENABLE_SSA)
4177 /* by edge splitting, in Blocks with phi moves there can only */
4178 /* be a goto as last command, no other Jump/Branch Command */
4179 if (!last_cmd_was_goto)
4180 codegen_insert_phi_moves(cd, rd, ls, bptr);
4185 if ((src->varkind != STACKVAR)) {
4187 if (IS_FLT_DBL_TYPE(s2)) {
4188 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
4189 if (!(rd->interfaces[len][s2].flags & INMEMORY))
4190 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4192 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4195 if (IS_2_WORD_TYPE(s2))
4197 /* s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP1, REG_ITMP2)); */
4199 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
4201 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4202 if (IS_2_WORD_TYPE(s2))
4203 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
4205 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4208 if (IS_2_WORD_TYPE(s2))
4209 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4211 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4218 /* At the end of a basic block we may have to append some nops,
4219 because the patcher stub calling code might be longer than the
4220 actual instruction. So codepatching does not change the
4221 following block unintentionally. */
4223 if (cd->mcodeptr < cd->lastmcodeptr) {
4224 while (cd->mcodeptr < cd->lastmcodeptr) {
4229 } /* if (bptr -> flags >= BBREACHED) */
4230 } /* for basic block */
4232 dseg_createlinenumbertable(cd);
4235 /* generate exception and patcher stubs */
4244 savedmcodeptr = NULL;
4246 /* generate exception stubs */
4248 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
4249 gen_resolvebranch(cd->mcodebase + eref->branchpos,
4251 cd->mcodeptr - cd->mcodebase);
4255 /* Check if the exception is an
4256 ArrayIndexOutOfBoundsException. If so, move index register
4259 if (eref->reg != -1)
4260 M_INTMOVE(eref->reg, REG_ITMP1);
4262 /* calcuate exception address */
4264 M_MOV_IMM(0, REG_ITMP2_XPC);
4266 M_AADD_IMM32(eref->branchpos - 6, REG_ITMP2_XPC);
4268 /* move function to call into REG_ITMP3 */
4270 M_MOV_IMM(eref->function, REG_ITMP3);
4272 if (savedmcodeptr != NULL) {
4273 M_JMP_IMM((savedmcodeptr - cd->mcodeptr) - 5);
4276 savedmcodeptr = cd->mcodeptr;
4278 M_ASUB_IMM(5 * 4, REG_SP);
4280 /* first save REG_ITMP1 so we can use it */
4282 M_AST(REG_ITMP1, REG_SP, 4 * 4); /* for AIOOBE */
4284 M_AST_IMM(0, REG_SP, 0 * 4);
4286 M_MOV(REG_SP, REG_ITMP1);
4287 M_AADD_IMM(5 * 4, REG_ITMP1);
4288 M_AST(REG_ITMP1, REG_SP, 1 * 4);
4289 M_ALD(REG_ITMP1, REG_SP, (5 + stackframesize) * 4);
4290 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4291 M_AST(REG_ITMP2_XPC, REG_SP, 3 * 4);
4295 M_ALD(REG_ITMP2_XPC, REG_SP, 3 * 4);
4296 M_AADD_IMM(5 * 4, REG_SP);
4298 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
4304 /* generate code patching stub call code */
4306 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4307 /* check code segment size */
4311 /* Get machine code which is patched back in later. A
4312 `call rel32' is 5 bytes long. */
4314 savedmcodeptr = cd->mcodebase + pref->branchpos;
4315 mcode = *((u8 *) savedmcodeptr);
4317 /* patch in `call rel32' to call the following code */
4319 tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4320 cd->mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
4322 M_CALL_IMM(tmpmcodeptr - (savedmcodeptr + PATCHER_CALL_SIZE));
4324 cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4326 /* save REG_ITMP3 */
4330 /* move pointer to java_objectheader onto stack */
4332 #if defined(ENABLE_THREADS)
4333 (void) dseg_addaddress(cd, NULL); /* flcword */
4334 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4335 off = dseg_addaddress(cd, NULL); /* vftbl */
4337 M_MOV_IMM(0, REG_ITMP3);
4339 M_AADD_IMM(off, REG_ITMP3);
4345 /* move machine code bytes and classinfo pointer into registers */
4347 M_PUSH_IMM(mcode >> 32);
4349 M_PUSH_IMM(pref->ref);
4350 M_PUSH_IMM(pref->patcher);
4352 M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
4357 /* generate replacement-out stubs */
4362 replacementpoint = jd->code->rplpoints;
4364 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
4365 /* check code segment size */
4369 /* note start of stub code */
4371 replacementpoint->outcode = (u1*) (ptrint)(cd->mcodeptr - cd->mcodebase);
4373 /* make machine code for patching */
4375 disp = (ptrint)(replacementpoint->outcode - replacementpoint->pc) - 5;
4376 replacementpoint->mcode = 0xe9 | ((u8)disp << 8);
4378 /* push address of `rplpoint` struct */
4380 M_PUSH_IMM(replacementpoint);
4382 /* jump to replacement function */
4384 M_PUSH_IMM(asm_replacement_out);
4391 /* everything's ok */
4396 #if defined(ENABLE_SSA)
4397 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls, basicblock *bptr) {
4398 /* look for phi moves */
4399 int t_a,s_a,i, type;
4400 int t_lt, s_lt; /* lifetime indices of phi_moves */
4401 bool t_inmemory, s_inmemory;
4402 s4 t_regoff, s_regoff, s_flags, t_flags;
4405 /* Moves from phi functions with highest indices have to be */
4406 /* inserted first, since this is the order as is used for */
4407 /* conflict resolution */
4408 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
4409 t_a = ls->phi_moves[bptr->nr][i][0];
4410 s_a = ls->phi_moves[bptr->nr][i][1];
4411 #if defined(SSA_DEBUG_VERBOSE)
4413 printf("BB %3i Move %3i <- %3i ",bptr->nr,t_a,s_a);
4416 /* local var lifetimes */
4417 t_lt = ls->maxlifetimes + t_a;
4418 type = ls->lifetime[t_lt].type;
4421 type = ls->lifetime[t_lt].local_ss->s->type;
4422 /* stackslot lifetime */
4425 #if defined(SSA_DEBUG_VERBOSE)
4427 printf("...returning - phi lifetimes where joined\n");
4432 /* local var lifetimes */
4433 s_lt = ls->maxlifetimes + s_a;
4434 type = ls->lifetime[s_lt].type;
4437 type = ls->lifetime[s_lt].type;
4438 /* stackslot lifetime */
4441 #if defined(SSA_DEBUG_VERBOSE)
4443 printf("...returning - phi lifetimes where joined\n");
4449 t_inmemory = rd->locals[t_a][type].flags & INMEMORY;
4450 t_flags = rd->locals[t_a][type].flags;
4451 t_regoff = rd->locals[t_a][type].regoff;
4454 t_inmemory = ls->lifetime[t_lt].local_ss->s->flags & INMEMORY;
4455 t_flags = ls->lifetime[t_lt].local_ss->s->flags;
4456 t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
4460 /* local var move */
4462 s_inmemory = rd->locals[s_a][type].flags & INMEMORY;
4463 s_flags = rd->locals[s_a][type].flags;
4464 s_regoff = rd->locals[s_a][type].regoff;
4466 /* stackslot lifetime */
4467 s_inmemory = ls->lifetime[s_lt].local_ss->s->flags & INMEMORY;
4468 s_flags = ls->lifetime[s_lt].local_ss->s->flags;
4469 s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
4472 #if defined(SSA_DEBUG_VERBOSE)
4474 printf("...returning - phi lifetimes where joined\n");
4479 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
4481 #if defined(SSA_DEBUG_VERBOSE)
4482 if (compileverbose) {
4483 if ((t_inmemory) && (s_inmemory)) {
4485 printf("M%3i <- M%3i",t_regoff,s_regoff);
4486 } else if (s_inmemory) {
4488 printf("R%3i <- M%3i",t_regoff,s_regoff);
4489 } else if (t_inmemory) {
4491 printf("M%3i <- R%3i",t_regoff,s_regoff);
4494 printf("R%3i <- R%3i",t_regoff,s_regoff);
4498 #endif /* defined(SSA_DEBUG_VERBOSE) */
4502 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
4503 s4 dst_regoff, s4 dst_flags) {
4504 if ((dst_flags & INMEMORY) && (src_flags & INMEMORY)) {
4506 if (dst_regoff != src_regoff) {
4507 if (!IS_2_WORD_TYPE(type)) {
4508 if (IS_FLT_DBL_TYPE(type)) {
4509 emit_flds_membase(cd, REG_SP, src_regoff * 4);
4510 emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
4512 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
4514 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
4516 } else { /* LONG OR DOUBLE */
4517 if (IS_FLT_DBL_TYPE(type)) {
4518 emit_fldl_membase( cd, REG_SP, src_regoff * 4);
4519 emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
4521 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
4523 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
4524 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
4526 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP,
4527 dst_regoff * 4 + 4);
4532 if (IS_FLT_DBL_TYPE(type)) {
4533 log_text("cg_move: flt/dbl type have to be in memory\n");
4536 if (IS_2_WORD_TYPE(type)) {
4537 log_text("cg_move: longs have to be in memory\n");
4540 if (src_flags & INMEMORY) {
4542 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
4543 } else if (dst_flags & INMEMORY) {
4545 emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
4548 /* only ints can be in regs on i386 */
4549 M_INTMOVE(src_regoff,dst_regoff);
4553 #endif /* defined(ENABLE_SSA) */
4555 /* createcompilerstub **********************************************************
4557 Creates a stub routine which calls the compiler.
4559 *******************************************************************************/
4561 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
4562 #define COMPILERSTUB_CODESIZE 12
4564 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4567 u1 *createcompilerstub(methodinfo *m)
4569 u1 *s; /* memory to hold the stub */
4575 s = CNEW(u1, COMPILERSTUB_SIZE);
4577 /* set data pointer and code pointer */
4580 s = s + COMPILERSTUB_DATASIZE;
4582 /* mark start of dump memory area */
4584 dumpsize = dump_size();
4586 cd = DNEW(codegendata);
4589 /* Store the codeinfo pointer in the same place as in the
4590 methodheader for compiled methods. */
4592 code = code_codeinfo_new(m);
4594 d[0] = (ptrint) asm_call_jit_compiler;
4596 d[2] = (ptrint) code;
4598 /* code for the stub */
4600 M_MOV_IMM(m, REG_ITMP1); /* method info */
4601 M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
4604 #if defined(ENABLE_STATISTICS)
4606 count_cstub_len += COMPILERSTUB_SIZE;
4609 /* release dump area */
4611 dump_release(dumpsize);
4617 /* createnativestub ************************************************************
4619 Creates a stub routine which calls a native method.
4621 *******************************************************************************/
4623 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4632 s4 i, j; /* count variables */
4636 /* get required compiler data */
4643 /* set some variables */
4646 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4648 /* calculate stackframe size */
4651 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4652 sizeof(localref_table) / SIZEOF_VOID_P +
4653 1 + /* function pointer */
4654 4 * 4 + /* 4 arguments (start_native_call) */
4657 /* create method header */
4659 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
4660 (void) dseg_adds4(cd, stackframesize * 4); /* FrameSize */
4661 (void) dseg_adds4(cd, 0); /* IsSync */
4662 (void) dseg_adds4(cd, 0); /* IsLeaf */
4663 (void) dseg_adds4(cd, 0); /* IntSave */
4664 (void) dseg_adds4(cd, 0); /* FltSave */
4665 (void) dseg_addlinenumbertablesize(cd);
4666 (void) dseg_adds4(cd, 0); /* ExTableSize */
4668 /* generate native method profiling code */
4670 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4671 /* count frequency */
4673 M_MOV_IMM(code, REG_ITMP1);
4674 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
4677 /* calculate stackframe size for native function */
4679 M_ASUB_IMM(stackframesize * 4, REG_SP);
4681 #if !defined(NDEBUG)
4682 if (opt_verbosecall) {
4685 disp = stackframesize * 4;
4687 M_ASUB_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
4689 for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
4690 t = md->paramtypes[p].type;
4691 if (IS_INT_LNG_TYPE(t)) {
4692 if (IS_2_WORD_TYPE(t)) {
4693 M_ILD(REG_ITMP1, REG_SP,
4694 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4695 M_ILD(REG_ITMP2, REG_SP,
4696 4 + TRACE_ARGS_NUM * 8 + 4 + disp + 4);
4697 M_IST(REG_ITMP1, REG_SP, p * 8);
4698 M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
4700 } else if (t == TYPE_ADR) {
4701 M_ALD(REG_ITMP1, REG_SP,
4702 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4704 M_AST(REG_ITMP1, REG_SP, p * 8);
4705 M_AST(REG_ITMP2, REG_SP, p * 8 + 4);
4708 M_ILD(EAX, REG_SP, 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4710 M_IST(EAX, REG_SP, p * 8);
4711 M_IST(EDX, REG_SP, p * 8 + 4);
4715 if (!IS_2_WORD_TYPE(t)) {
4716 emit_flds_membase(cd, REG_SP,
4717 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4718 emit_fstps_membase(cd, REG_SP, p * 8);
4719 emit_alu_reg_reg(cd, ALU_XOR, REG_ITMP2, REG_ITMP2);
4720 M_IST(REG_ITMP2, REG_SP, p * 8 + 4);
4723 emit_fldl_membase(cd, REG_SP,
4724 4 + TRACE_ARGS_NUM * 8 + 4 + disp);
4725 emit_fstpl_membase(cd, REG_SP, p * 8);
4728 disp += (IS_2_WORD_TYPE(t)) ? 8 : 4;
4732 for (p = md->paramcount; p < TRACE_ARGS_NUM; p++) {
4733 M_IST(REG_ITMP1, REG_SP, p * 8);
4734 M_IST(REG_ITMP1, REG_SP, p * 8 + 4);
4737 M_AST_IMM(m, REG_SP, TRACE_ARGS_NUM * 8);
4739 M_MOV_IMM(builtin_trace_args, REG_ITMP1);
4742 M_AADD_IMM(TRACE_ARGS_NUM * 8 + 4, REG_SP);
4744 #endif /* !defined(NDEBUG) */
4746 /* get function address (this must happen before the stackframeinfo) */
4748 #if !defined(WITH_STATIC_CLASSPATH)
4750 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
4752 if (opt_showdisassemble) {
4753 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4758 M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
4760 /* Mark the whole fpu stack as free for native functions (only for saved */
4761 /* register count == 0). */
4763 emit_ffree_reg(cd, 0);
4764 emit_ffree_reg(cd, 1);
4765 emit_ffree_reg(cd, 2);
4766 emit_ffree_reg(cd, 3);
4767 emit_ffree_reg(cd, 4);
4768 emit_ffree_reg(cd, 5);
4769 emit_ffree_reg(cd, 6);
4770 emit_ffree_reg(cd, 7);
4772 /* prepare data structures for native function call */
4774 M_MOV(REG_SP, REG_ITMP1);
4775 M_AADD_IMM(stackframesize * 4, REG_ITMP1);
4777 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4778 M_IST_IMM(0, REG_SP, 1 * 4);
4781 M_MOV(REG_SP, REG_ITMP2);
4782 M_AADD_IMM(stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
4784 M_AST(REG_ITMP2, REG_SP, 2 * 4);
4785 M_ALD(REG_ITMP3, REG_SP, stackframesize * 4);
4786 M_AST(REG_ITMP3, REG_SP, 3 * 4);
4787 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
4790 M_ALD(REG_ITMP3, REG_SP, 4 * 4);
4792 /* copy arguments into new stackframe */
4794 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4795 t = md->paramtypes[i].type;
4797 if (!md->params[i].inmemory) {
4798 /* no integer argument registers */
4799 } else { /* float/double in memory can be copied like int/longs */
4800 s1 = (md->params[i].regoff + stackframesize + 1) * 4;
4801 s2 = nmd->params[j].regoff * 4;
4803 M_ILD(REG_ITMP1, REG_SP, s1);
4804 M_IST(REG_ITMP1, REG_SP, s2);
4805 if (IS_2_WORD_TYPE(t)) {
4806 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
4807 M_IST(REG_ITMP1, REG_SP, s2 + 4);
4812 /* if function is static, put class into second argument */
4814 if (m->flags & ACC_STATIC)
4815 M_AST_IMM((ptrint) m->class, REG_SP, 1 * 4);
4817 /* put env into first argument */
4819 M_AST_IMM((ptrint) _Jv_env, REG_SP, 0 * 4);
4821 /* call the native function */
4825 /* save return value */
4827 if (md->returntype.type != TYPE_VOID) {
4828 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4829 if (IS_2_WORD_TYPE(md->returntype.type))
4830 M_IST(REG_RESULT2, REG_SP, 2 * 4);
4831 M_IST(REG_RESULT, REG_SP, 1 * 4);
4834 if (IS_2_WORD_TYPE(md->returntype.type))
4835 emit_fstl_membase(cd, REG_SP, 1 * 4);
4837 emit_fsts_membase(cd, REG_SP, 1 * 4);
4841 #if !defined(NDEBUG)
4842 if (opt_verbosecall) {
4843 /* restore return value */
4845 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4846 if (IS_2_WORD_TYPE(md->returntype.type))
4847 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4848 M_ILD(REG_RESULT, REG_SP, 1 * 4);
4851 if (IS_2_WORD_TYPE(md->returntype.type))
4852 emit_fldl_membase(cd, REG_SP, 1 * 4);
4854 emit_flds_membase(cd, REG_SP, 1 * 4);
4857 M_ASUB_IMM(4 + 8 + 8 + 4, REG_SP);
4859 M_AST_IMM((ptrint) m, REG_SP, 0);
4861 M_IST(REG_RESULT, REG_SP, 4);
4862 M_IST(REG_RESULT2, REG_SP, 4 + 4);
4864 emit_fstl_membase(cd, REG_SP, 4 + 8);
4865 emit_fsts_membase(cd, REG_SP, 4 + 8 + 8);
4867 M_MOV_IMM(builtin_displaymethodstop, REG_ITMP1);
4870 M_AADD_IMM(4 + 8 + 8 + 4, REG_SP);
4872 #endif /* !defined(NDEBUG) */
4874 /* remove native stackframe info */
4876 M_MOV(REG_SP, REG_ITMP1);
4877 M_AADD_IMM(stackframesize * 4, REG_ITMP1);
4879 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4880 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
4882 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
4884 /* restore return value */
4886 if (md->returntype.type != TYPE_VOID) {
4887 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4888 if (IS_2_WORD_TYPE(md->returntype.type))
4889 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4890 M_ILD(REG_RESULT, REG_SP, 1 * 4);
4893 if (IS_2_WORD_TYPE(md->returntype.type))
4894 emit_fldl_membase(cd, REG_SP, 1 * 4);
4896 emit_flds_membase(cd, REG_SP, 1 * 4);
4900 M_AADD_IMM(stackframesize * 4, REG_SP);
4902 /* check for exception */
4909 /* handle exception */
4911 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
4912 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
4913 M_ASUB_IMM(2, REG_ITMP2_XPC);
4915 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4919 /* process patcher calls **************************************************/
4927 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4928 /* Get machine code which is patched back in later. A
4929 `call rel32' is 5 bytes long. */
4931 xcodeptr = cd->mcodebase + pref->branchpos;
4932 mcode = *((u8 *) xcodeptr);
4934 /* patch in `call rel32' to call the following code */
4936 tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4937 cd->mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4939 M_CALL_IMM(tmpmcodeptr - (xcodeptr + PATCHER_CALL_SIZE));
4941 cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4943 /* save REG_ITMP3 */
4947 /* move pointer to java_objectheader onto stack */
4949 #if defined(ENABLE_THREADS)
4950 /* create a virtual java_objectheader */
4952 (void) dseg_addaddress(cd, NULL); /* flcword */
4953 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4954 disp = dseg_addaddress(cd, NULL); /* vftbl */
4956 M_MOV_IMM(0, REG_ITMP3);
4958 M_AADD_IMM(disp, REG_ITMP3);
4964 /* move machine code bytes and classinfo pointer onto stack */
4966 M_PUSH_IMM((mcode >> 32));
4968 M_PUSH_IMM(pref->ref);
4969 M_PUSH_IMM(pref->patcher);
4971 M_MOV_IMM(asm_patcher_wrapper, REG_ITMP3);
4978 return code->entrypoint;
4983 * These are local overrides for various environment variables in Emacs.
4984 * Please do not remove this and leave it at the end of the file, where
4985 * Emacs will automagically detect them.
4986 * ---------------------------------------------------------------------
4989 * indent-tabs-mode: t
4993 * vim:noexpandtab:sw=4:ts=4: