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 5323 2006-09-05 16:45:24Z edwin $
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, disp;
112 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
113 builtintable_entry *bte;
115 rplpoint *replacementpoint;
116 #if defined(ENABLE_SSA)
118 bool last_cmd_was_goto;
120 last_cmd_was_goto = false;
124 /* get required compiler data */
131 /* prevent compiler warnings */
141 s4 savedregs_num = 0;
144 /* space to save used callee saved registers */
146 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
148 /* float register are saved on 2 4-byte stackslots */
149 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
151 cd->stackframesize = rd->memuse + savedregs_num;
154 #if defined(ENABLE_THREADS)
155 /* space to save argument of monitor_enter */
157 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
158 /* reserve 2 slots for long/double return values for monitorexit */
160 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
161 cd->stackframesize += 2;
163 cd->stackframesize++;
167 /* create method header */
169 /* Keep stack of non-leaf functions 16-byte aligned. */
171 if (!jd->isleafmethod)
172 cd->stackframesize |= 0x3;
174 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
175 (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
177 #if defined(ENABLE_THREADS)
178 /* IsSync contains the offset relative to the stack pointer for the
179 argument of monitor_exit used in the exception handler. Since the
180 offset could be zero and give a wrong meaning of the flag it is
184 if (checksync && (m->flags & ACC_SYNCHRONIZED))
185 (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
188 (void) dseg_adds4(cd, 0); /* IsSync */
190 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
191 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
192 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
194 /* adds a reference for the length of the line number counter. We don't
195 know the size yet, since we evaluate the information during code
196 generation, to save one additional iteration over the whole
197 instructions. During code optimization the position could have changed
198 to the information gotten from the class file */
199 (void) dseg_addlinenumbertablesize(cd);
201 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
203 /* create exception table */
205 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
206 dseg_addtarget(cd, ex->start);
207 dseg_addtarget(cd, ex->end);
208 dseg_addtarget(cd, ex->handler);
209 (void) dseg_addaddress(cd, ex->catchtype.cls);
212 /* generate method profiling code */
214 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
215 /* count frequency */
217 M_MOV_IMM(code, REG_ITMP3);
218 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
221 /* create stack frame (if necessary) */
223 if (cd->stackframesize)
224 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
226 /* save return address and used callee saved registers */
228 p = cd->stackframesize;
229 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
230 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
232 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
233 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
236 /* take arguments out of register or stack frame */
241 for (p = 0, l = 0; p < md->paramcount; p++) {
242 t = md->paramtypes[p].type;
243 #if defined(ENABLE_SSA)
248 var = &(rd->locals[l][t]);
250 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
254 s1 = md->params[p].regoff;
256 if (IS_INT_LNG_TYPE(t)) { /* integer args */
257 if (!md->params[p].inmemory) { /* register arguments */
258 log_text("integer register argument");
260 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
261 /* rd->argintregs[md->params[p].regoff -> var->regoff */
263 else { /* reg arg -> spilled */
264 /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
267 else { /* stack arguments */
268 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
269 emit_mov_membase_reg( /* + 4 for return address */
270 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->regoff);
271 /* + 4 for return address */
273 else { /* stack arg -> spilled */
274 if (!IS_2_WORD_TYPE(t)) {
275 #if defined(ENABLE_SSA)
276 /* no copy avoiding by now possible with SSA */
278 emit_mov_membase_reg( /* + 4 for return address */
279 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
281 emit_mov_reg_membase(
282 cd, REG_ITMP1, REG_SP, var->regoff * 4);
285 #endif /*defined(ENABLE_SSA)*/
286 /* reuse Stackslotand avoid copying */
287 var->regoff = cd->stackframesize + s1 + 1;
291 #if defined(ENABLE_SSA)
292 /* no copy avoiding by now possible with SSA */
294 emit_mov_membase_reg( /* + 4 for return address */
295 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
297 emit_mov_reg_membase(
298 cd, REG_ITMP1, REG_SP, var->regoff * 4);
299 emit_mov_membase_reg( /* + 4 for return address */
300 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
302 emit_mov_reg_membase(
303 cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
306 #endif /*defined(ENABLE_SSA)*/
307 /* reuse Stackslotand avoid copying */
308 var->regoff = cd->stackframesize + s1 + 1;
313 else { /* floating args */
314 if (!md->params[p].inmemory) { /* register arguments */
315 log_text("There are no float argument registers!");
317 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
318 /* rd->argfltregs[md->params[p].regoff -> var->regoff */
319 } else { /* reg arg -> spilled */
320 /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
324 else { /* stack arguments */
325 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
328 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
330 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
335 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
337 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
340 } else { /* stack-arg -> spilled */
341 #if defined(ENABLE_SSA)
342 /* no copy avoiding by now possible with SSA */
344 emit_mov_membase_reg(
345 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
346 emit_mov_reg_membase(
347 cd, REG_ITMP1, REG_SP, var->regoff * 4);
350 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
351 emit_fstps_membase(cd, REG_SP, var->regoff * 4);
355 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
356 emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
360 #endif /*defined(ENABLE_SSA)*/
361 /* reuse Stackslotand avoid copying */
362 var->regoff = cd->stackframesize + s1 + 1;
368 /* call monitorenter function */
370 #if defined(ENABLE_THREADS)
371 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
374 if (m->flags & ACC_STATIC) {
375 M_MOV_IMM(&m->class->object.header, REG_ITMP1);
378 M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
381 codegen_add_nullpointerexception_ref(cd);
384 M_AST(REG_ITMP1, REG_SP, s1 * 4);
385 M_AST(REG_ITMP1, REG_SP, 0 * 4);
386 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
392 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
393 emit_verbosecall_enter(jd);
398 #if defined(ENABLE_SSA)
399 /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
401 codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
404 /* end of header generation */
406 replacementpoint = jd->code->rplpoints;
408 /* walk through all basic blocks */
409 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
411 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
413 if (bptr->flags >= BBREACHED) {
415 /* branch resolving */
418 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
419 gen_resolvebranch(cd->mcodebase + brefs->branchpos,
424 /* handle replacement points */
426 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
427 replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
431 assert(cd->lastmcodeptr <= cd->mcodeptr);
432 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
435 /* copy interface registers to their destination */
442 /* generate basic block profiling code */
444 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
445 /* count frequency */
447 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
448 M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
452 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
453 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
456 # if defined(ENABLE_SSA)
458 last_cmd_was_goto = false;
462 if (bptr->type != BBTYPE_STD) {
463 if (!IS_2_WORD_TYPE(src->type)) {
464 if (bptr->type == BBTYPE_SBR) {
465 if (!(src->flags & INMEMORY))
470 emit_store(jd, NULL, src, d);
471 } else if (bptr->type == BBTYPE_EXH) {
472 if (!(src->flags & INMEMORY))
476 M_INTMOVE(REG_ITMP1, d);
477 emit_store(jd, NULL, src, d);
481 log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
489 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
491 while (src != NULL) {
493 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
494 if (!IS_2_WORD_TYPE(src->type)) {
495 if (bptr->type == BBTYPE_SBR) {
496 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
498 emit_store(jd, NULL, src, d);
500 } else if (bptr->type == BBTYPE_EXH) {
501 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
502 M_INTMOVE(REG_ITMP1, d);
503 emit_store(jd, NULL, src, d);
506 log_text("copy interface registers: longs have to be in memory (begin 1)");
511 if (IS_LNG_TYPE(src->type))
512 d = codegen_reg_of_var(rd, 0, src, PACK_REGS(REG_ITMP1, REG_ITMP2));
514 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
515 /* d = codegen_reg_of_var(rd, 0, src, REG_IFTMP); */
517 if ((src->varkind != STACKVAR)) {
519 s1 = rd->interfaces[len][s2].regoff;
521 if (IS_FLT_DBL_TYPE(s2)) {
522 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
526 if (IS_2_WORD_TYPE(s2))
527 M_DLD(d, REG_SP, s1 * 4);
529 M_FLD(d, REG_SP, s1 * 4);
533 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
534 if (IS_2_WORD_TYPE(s2))
540 if (IS_2_WORD_TYPE(s2))
541 M_LLD(d, REG_SP, s1 * 4);
543 M_ILD(d, REG_SP, s1 * 4);
547 emit_store(jd, NULL, src, d);
554 /* walk through all instructions */
559 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
560 if (iptr->line != currentline) {
561 dseg_addlinenumber(cd, iptr->line);
562 currentline = iptr->line;
565 MCODECHECK(1024); /* 1kB should be enough */
568 case ICMD_INLINE_START:
570 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
571 #if defined(ENABLE_THREADS)
572 if (insinfo->synchronize) {
573 /* add monitor enter code */
574 if (insinfo->method->flags & ACC_STATIC) {
575 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
576 M_AST(REG_ITMP1, REG_SP, 0 * 4);
579 /* nullpointer check must have been performed before */
580 /* (XXX not done, yet) */
581 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
582 if (var->flags & INMEMORY) {
583 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
584 M_AST(REG_ITMP1, REG_SP, 0 * 4);
587 M_AST(var->regoff, REG_SP, 0 * 4);
591 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
595 dseg_addlinenumber_inline_start(cd, iptr);
599 case ICMD_INLINE_END:
601 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
603 dseg_addlinenumber_inline_end(cd, iptr);
604 dseg_addlinenumber(cd, iptr->line);
606 #if defined(ENABLE_THREADS)
607 if (insinfo->synchronize) {
608 /* add monitor exit code */
609 if (insinfo->method->flags & ACC_STATIC) {
610 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
611 M_AST(REG_ITMP1, REG_SP, 0 * 4);
614 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
615 if (var->flags & INMEMORY) {
616 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
617 M_AST(REG_ITMP1, REG_SP, 0 * 4);
620 M_AST(var->regoff, REG_SP, 0 * 4);
624 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
631 case ICMD_NOP: /* ... ==> ... */
634 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
636 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
639 codegen_add_nullpointerexception_ref(cd);
642 /* constant operations ************************************************/
644 case ICMD_ICONST: /* ... ==> ..., constant */
645 /* op1 = 0, val.i = constant */
647 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
648 ICONST(d, iptr->val.i);
649 emit_store(jd, iptr, iptr->dst, d);
652 case ICMD_LCONST: /* ... ==> ..., constant */
653 /* op1 = 0, val.l = constant */
655 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
656 LCONST(d, iptr->val.l);
657 emit_store(jd, iptr, iptr->dst, d);
660 case ICMD_FCONST: /* ... ==> ..., constant */
661 /* op1 = 0, val.f = constant */
663 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
664 if (iptr->val.f == 0.0) {
668 if (iptr->val.i == 0x80000000) {
672 } else if (iptr->val.f == 1.0) {
675 } else if (iptr->val.f == 2.0) {
681 disp = dseg_addfloat(cd, iptr->val.f);
682 emit_mov_imm_reg(cd, 0, REG_ITMP1);
684 emit_flds_membase(cd, REG_ITMP1, disp);
686 emit_store(jd, iptr, iptr->dst, d);
689 case ICMD_DCONST: /* ... ==> ..., constant */
690 /* op1 = 0, val.d = constant */
692 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
693 if (iptr->val.d == 0.0) {
697 if (iptr->val.l == 0x8000000000000000LL) {
701 } else if (iptr->val.d == 1.0) {
704 } else if (iptr->val.d == 2.0) {
710 disp = dseg_adddouble(cd, iptr->val.d);
711 emit_mov_imm_reg(cd, 0, REG_ITMP1);
713 emit_fldl_membase(cd, REG_ITMP1, disp);
715 emit_store(jd, iptr, iptr->dst, d);
718 case ICMD_ACONST: /* ... ==> ..., constant */
719 /* op1 = 0, val.a = constant */
721 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
723 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
724 codegen_addpatchref(cd, PATCHER_aconst,
725 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr), 0);
727 if (opt_showdisassemble) {
728 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
734 if (iptr->val.a == NULL)
737 M_MOV_IMM(iptr->val.a, d);
739 emit_store(jd, iptr, iptr->dst, d);
743 /* load/store operations **********************************************/
745 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
746 case ICMD_ALOAD: /* op1 = local variable */
748 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
749 if ((iptr->dst->varkind == LOCALVAR) &&
750 (iptr->dst->varnum == iptr->op1))
752 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
753 if (var->flags & INMEMORY)
754 M_ILD(d, REG_SP, var->regoff * 4);
756 M_INTMOVE(var->regoff, d);
757 emit_store(jd, iptr, iptr->dst, d);
760 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
761 /* op1 = local variable */
763 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
764 if ((iptr->dst->varkind == LOCALVAR) &&
765 (iptr->dst->varnum == iptr->op1))
767 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
768 if (var->flags & INMEMORY)
769 M_LLD(d, REG_SP, var->regoff * 4);
771 M_LNGMOVE(var->regoff, d);
772 emit_store(jd, iptr, iptr->dst, d);
775 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
776 /* op1 = local variable */
778 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
779 if ((iptr->dst->varkind == LOCALVAR) &&
780 (iptr->dst->varnum == iptr->op1))
782 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
783 if (var->flags & INMEMORY)
784 M_FLD(d, REG_SP, var->regoff * 4);
786 M_FLTMOVE(var->regoff, d);
787 emit_store(jd, iptr, iptr->dst, d);
790 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
791 /* op1 = local variable */
793 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
794 if ((iptr->dst->varkind == LOCALVAR) &&
795 (iptr->dst->varnum == iptr->op1))
797 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
798 if (var->flags & INMEMORY)
799 M_DLD(d, REG_SP, var->regoff * 4);
801 M_FLTMOVE(var->regoff, d);
802 emit_store(jd, iptr, iptr->dst, d);
805 case ICMD_ISTORE: /* ..., value ==> ... */
806 case ICMD_ASTORE: /* op1 = local variable */
808 if ((src->varkind == LOCALVAR) &&
809 (src->varnum == iptr->op1))
811 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
812 if (var->flags & INMEMORY) {
813 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
814 M_IST(s1, REG_SP, var->regoff * 4);
817 s1 = emit_load_s1(jd, iptr, src, var->regoff);
818 M_INTMOVE(s1, var->regoff);
822 case ICMD_LSTORE: /* ..., value ==> ... */
823 /* op1 = local variable */
825 if ((src->varkind == LOCALVAR) &&
826 (src->varnum == iptr->op1))
828 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
829 if (var->flags & INMEMORY) {
830 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
831 M_LST(s1, REG_SP, var->regoff * 4);
834 s1 = emit_load_s1(jd, iptr, src, var->regoff);
835 M_LNGMOVE(s1, var->regoff);
839 case ICMD_FSTORE: /* ..., value ==> ... */
840 /* op1 = local variable */
842 if ((src->varkind == LOCALVAR) &&
843 (src->varnum == iptr->op1))
845 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
846 if (var->flags & INMEMORY) {
847 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
848 M_FST(s1, REG_SP, var->regoff * 4);
851 s1 = emit_load_s1(jd, iptr, src, var->regoff);
852 M_FLTMOVE(s1, var->regoff);
856 case ICMD_DSTORE: /* ..., value ==> ... */
857 /* op1 = local variable */
859 if ((src->varkind == LOCALVAR) &&
860 (src->varnum == iptr->op1))
862 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
863 if (var->flags & INMEMORY) {
864 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
865 M_DST(s1, REG_SP, var->regoff * 4);
868 s1 = emit_load_s1(jd, iptr, src, var->regoff);
869 M_FLTMOVE(s1, var->regoff);
874 /* pop/dup/swap operations ********************************************/
876 /* attention: double and longs are only one entry in CACAO ICMDs */
878 case ICMD_POP: /* ..., value ==> ... */
879 case ICMD_POP2: /* ..., value, value ==> ... */
882 case ICMD_DUP: /* ..., a ==> ..., a, a */
884 M_COPY(src, iptr->dst);
887 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
889 M_COPY(src, iptr->dst);
890 M_COPY(src->prev, iptr->dst->prev);
893 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
895 M_COPY(src, iptr->dst);
896 M_COPY(src->prev, iptr->dst->prev);
897 #if defined(ENABLE_SSA)
898 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
899 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
901 M_COPY(iptr->dst, iptr->dst->prev->prev);
902 #if defined(ENABLE_SSA)
904 M_COPY(src, iptr->dst->prev->prev);
909 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
911 M_COPY(src, iptr->dst);
912 M_COPY(src->prev, iptr->dst->prev);
913 M_COPY(src->prev->prev, iptr->dst->prev->prev);
914 #if defined(ENABLE_SSA)
915 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
916 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
918 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
919 #if defined(ENABLE_SSA)
921 M_COPY(src, iptr->dst->prev->prev->prev);
926 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
928 M_COPY(src, iptr->dst);
929 M_COPY(src->prev, iptr->dst->prev);
930 M_COPY(src->prev->prev, iptr->dst->prev->prev);
931 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
932 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
935 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
937 M_COPY(src, iptr->dst);
938 M_COPY(src->prev, iptr->dst->prev);
939 M_COPY(src->prev->prev, iptr->dst->prev->prev);
940 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
941 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
942 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
945 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
947 M_COPY(src, iptr->dst->prev);
948 M_COPY(src->prev, iptr->dst);
952 /* integer operations *************************************************/
954 case ICMD_INEG: /* ..., value ==> ..., - value */
956 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
957 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
960 emit_store(jd, iptr, iptr->dst, d);
963 case ICMD_LNEG: /* ..., value ==> ..., - value */
965 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
966 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
968 M_NEG(GET_LOW_REG(d));
969 M_IADDC_IMM(0, GET_HIGH_REG(d));
970 M_NEG(GET_HIGH_REG(d));
971 emit_store(jd, iptr, iptr->dst, d);
974 case ICMD_I2L: /* ..., value ==> ..., value */
976 s1 = emit_load_s1(jd, iptr, src, EAX);
977 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
980 M_LNGMOVE(EAX_EDX_PACKED, d);
981 emit_store(jd, iptr, iptr->dst, d);
984 case ICMD_L2I: /* ..., value ==> ..., value */
986 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
987 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
989 emit_store(jd, iptr, iptr->dst, d);
992 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
994 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
995 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
999 emit_store(jd, iptr, iptr->dst, d);
1002 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1004 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1005 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1007 emit_store(jd, iptr, iptr->dst, d);
1010 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1012 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1013 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1015 emit_store(jd, iptr, iptr->dst, d);
1019 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1021 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1022 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1023 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1030 emit_store(jd, iptr, iptr->dst, d);
1033 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1034 /* val.i = constant */
1036 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1037 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1039 M_IADD_IMM(iptr->val.i, d);
1040 emit_store(jd, iptr, iptr->dst, d);
1043 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1045 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1046 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1047 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1048 M_INTMOVE(s1, GET_LOW_REG(d));
1049 M_IADD(s2, GET_LOW_REG(d));
1050 /* don't use REG_ITMP1 */
1051 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1052 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1053 M_INTMOVE(s1, GET_HIGH_REG(d));
1054 M_IADDC(s2, GET_HIGH_REG(d));
1055 emit_store(jd, iptr, iptr->dst, d);
1058 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1059 /* val.l = constant */
1061 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1062 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1064 M_IADD_IMM(iptr->val.l, GET_LOW_REG(d));
1065 M_IADDC_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1066 emit_store(jd, iptr, iptr->dst, d);
1069 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1071 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1072 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1073 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1075 M_INTMOVE(s1, REG_ITMP1);
1076 M_ISUB(s2, REG_ITMP1);
1077 M_INTMOVE(REG_ITMP1, d);
1083 emit_store(jd, iptr, iptr->dst, d);
1086 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1087 /* val.i = constant */
1089 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1090 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1092 M_ISUB_IMM(iptr->val.i, d);
1093 emit_store(jd, iptr, iptr->dst, d);
1096 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1098 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1099 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1100 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1101 if (s2 == GET_LOW_REG(d)) {
1102 M_INTMOVE(s1, REG_ITMP1);
1103 M_ISUB(s2, REG_ITMP1);
1104 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
1107 M_INTMOVE(s1, GET_LOW_REG(d));
1108 M_ISUB(s2, GET_LOW_REG(d));
1110 /* don't use REG_ITMP1 */
1111 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1112 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1113 if (s2 == GET_HIGH_REG(d)) {
1114 M_INTMOVE(s1, REG_ITMP2);
1115 M_ISUBB(s2, REG_ITMP2);
1116 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
1119 M_INTMOVE(s1, GET_HIGH_REG(d));
1120 M_ISUBB(s2, GET_HIGH_REG(d));
1122 emit_store(jd, iptr, iptr->dst, d);
1125 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1126 /* val.l = constant */
1128 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1129 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1131 M_ISUB_IMM(iptr->val.l, GET_LOW_REG(d));
1132 M_ISUBB_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1133 emit_store(jd, iptr, iptr->dst, d);
1136 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1138 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1139 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1140 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1147 emit_store(jd, iptr, iptr->dst, d);
1150 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1151 /* val.i = constant */
1153 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1154 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1155 M_IMUL_IMM(s1, iptr->val.i, d);
1156 emit_store(jd, iptr, iptr->dst, d);
1159 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1161 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1162 s2 = emit_load_s2_low(jd, iptr, src, EDX);
1163 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1165 M_INTMOVE(s1, REG_ITMP2);
1166 M_IMUL(s2, REG_ITMP2);
1168 s1 = emit_load_s1_low(jd, iptr, src->prev, EAX);
1169 s2 = emit_load_s2_high(jd, iptr, src, EDX);
1172 M_IADD(EDX, REG_ITMP2);
1174 s1 = emit_load_s1_low(jd, iptr, src->prev, EAX);
1175 s2 = emit_load_s2_low(jd, iptr, src, EDX);
1178 M_INTMOVE(EAX, GET_LOW_REG(d));
1179 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
1181 emit_store(jd, iptr, iptr->dst, d);
1184 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1185 /* val.l = constant */
1187 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
1188 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX_EDX_PACKED);
1189 ICONST(EAX, iptr->val.l);
1191 M_IMUL_IMM(s1, iptr->val.l >> 32, REG_ITMP2);
1192 M_IADD(REG_ITMP2, EDX);
1193 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
1194 M_IMUL_IMM(s1, iptr->val.l, REG_ITMP2);
1195 M_IADD(REG_ITMP2, EDX);
1196 M_LNGMOVE(EAX_EDX_PACKED, d);
1197 emit_store(jd, iptr, iptr->dst, d);
1200 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1202 s1 = emit_load_s1(jd, iptr, src->prev, EAX);
1203 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1204 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EAX);
1209 codegen_add_arithmeticexception_ref(cd);
1212 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1214 /* check as described in jvm spec */
1216 M_CMP_IMM(0x80000000, EAX);
1223 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
1224 emit_store(jd, iptr, iptr->dst, d);
1227 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1229 s1 = emit_load_s1(jd, iptr, src->prev, EAX);
1230 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1231 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, EDX);
1236 codegen_add_arithmeticexception_ref(cd);
1239 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1241 /* check as described in jvm spec */
1243 M_CMP_IMM(0x80000000, EAX);
1251 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
1252 emit_store(jd, iptr, iptr->dst, d);
1255 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1256 /* val.i = constant */
1258 /* TODO: optimize for `/ 2' */
1259 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1260 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1264 M_IADD_IMM32((1 << iptr->val.i) - 1, d); /* 32-bit for jump off. */
1265 M_SRA_IMM(iptr->val.i, d);
1266 emit_store(jd, iptr, iptr->dst, d);
1269 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1270 /* val.i = constant */
1272 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1273 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1275 M_MOV(s1, REG_ITMP1);
1279 M_AND_IMM(iptr->val.i, d);
1281 M_BGE(2 + 2 + 6 + 2);
1282 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
1284 M_AND_IMM32(iptr->val.i, d); /* use 32-bit for jump offset */
1286 emit_store(jd, iptr, iptr->dst, d);
1289 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1290 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1292 s2 = emit_load_s2(jd, iptr, src, REG_ITMP12_PACKED);
1293 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1295 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1296 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1298 codegen_add_arithmeticexception_ref(cd);
1303 M_LST(s2, REG_SP, 2 * 4);
1305 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP12_PACKED);
1306 M_LST(s1, REG_SP, 0 * 4);
1308 M_MOV_IMM(bte->fp, REG_ITMP3);
1310 emit_store(jd, iptr, iptr->dst, d);
1313 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1314 /* val.i = constant */
1316 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1317 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1319 M_TEST(GET_HIGH_REG(d));
1321 M_IADD_IMM32((1 << iptr->val.i) - 1, GET_LOW_REG(d));
1322 M_IADDC_IMM(0, GET_HIGH_REG(d));
1323 M_SRLD_IMM(iptr->val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1324 M_SRA_IMM(iptr->val.i, GET_HIGH_REG(d));
1325 emit_store(jd, iptr, iptr->dst, d);
1329 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1330 /* val.l = constant */
1332 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
1333 if (iptr->dst->flags & INMEMORY) {
1334 if (src->flags & INMEMORY) {
1335 /* Alpha algorithm */
1337 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1339 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4 + 4);
1345 /* TODO: hmm, don't know if this is always correct */
1347 CALCIMMEDIATEBYTES(disp, iptr->val.l & 0x00000000ffffffff);
1349 CALCIMMEDIATEBYTES(disp, iptr->val.l >> 32);
1355 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
1356 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
1358 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l, REG_ITMP1);
1359 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l >> 32, REG_ITMP2);
1360 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, src->regoff * 4 + 4);
1361 emit_jcc(cd, CC_GE, disp);
1363 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP1);
1364 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP2);
1366 emit_neg_reg(cd, REG_ITMP1);
1367 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1368 emit_neg_reg(cd, REG_ITMP2);
1370 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l, REG_ITMP1);
1371 emit_alu_imm_reg(cd, ALU_AND, iptr->val.l >> 32, REG_ITMP2);
1373 emit_neg_reg(cd, REG_ITMP1);
1374 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1375 emit_neg_reg(cd, REG_ITMP2);
1377 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst->regoff * 4);
1378 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst->regoff * 4 + 4);
1382 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1383 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1385 M_AND_IMM(iptr->val.l, GET_LOW_REG(d));
1386 M_AND_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1387 M_TEST(GET_LOW_REG(s1));
1393 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1395 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1396 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1397 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1398 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1401 emit_store(jd, iptr, iptr->dst, d);
1404 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1405 /* val.i = constant */
1407 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1408 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1410 M_SLL_IMM(iptr->val.i, d);
1411 emit_store(jd, iptr, iptr->dst, d);
1414 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1416 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1417 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1418 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1419 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1422 emit_store(jd, iptr, iptr->dst, d);
1425 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1426 /* val.i = constant */
1428 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1429 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1431 M_SRA_IMM(iptr->val.i, d);
1432 emit_store(jd, iptr, iptr->dst, d);
1435 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1437 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1438 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1439 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1440 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1443 emit_store(jd, iptr, iptr->dst, d);
1446 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1447 /* val.i = constant */
1449 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1450 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1452 M_SRL_IMM(iptr->val.i, d);
1453 emit_store(jd, iptr, iptr->dst, d);
1456 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1458 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1459 s2 = emit_load_s2(jd, iptr, src, ECX);
1460 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1463 M_TEST_IMM(32, ECX);
1465 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1466 M_CLR(GET_LOW_REG(d));
1467 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1468 M_SLL(GET_LOW_REG(d));
1469 emit_store(jd, iptr, iptr->dst, d);
1472 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1473 /* val.i = constant */
1475 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1476 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1478 if (iptr->val.i & 0x20) {
1479 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1480 M_CLR(GET_LOW_REG(d));
1481 M_SLLD_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1484 M_SLLD_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1485 M_SLL_IMM(iptr->val.i & 0x3f, GET_LOW_REG(d));
1487 emit_store(jd, iptr, iptr->dst, d);
1490 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1492 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1493 s2 = emit_load_s2(jd, iptr, src, ECX);
1494 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1497 M_TEST_IMM(32, ECX);
1499 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1500 M_SRA_IMM(31, GET_HIGH_REG(d));
1501 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1502 M_SRA(GET_HIGH_REG(d));
1503 emit_store(jd, iptr, iptr->dst, d);
1506 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1507 /* val.i = constant */
1509 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1510 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1512 if (iptr->val.i & 0x20) {
1513 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1514 M_SRA_IMM(31, GET_HIGH_REG(d));
1515 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1518 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1519 M_SRA_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d));
1521 emit_store(jd, iptr, iptr->dst, d);
1524 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1526 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP13_PACKED);
1527 s2 = emit_load_s2(jd, iptr, src, ECX);
1528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP13_PACKED);
1531 M_TEST_IMM(32, ECX);
1533 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1534 M_CLR(GET_HIGH_REG(d));
1535 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1536 M_SRL(GET_HIGH_REG(d));
1537 emit_store(jd, iptr, iptr->dst, d);
1540 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1541 /* val.l = constant */
1543 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1544 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1546 if (iptr->val.i & 0x20) {
1547 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1548 M_CLR(GET_HIGH_REG(d));
1549 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1552 M_SRLD_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d), GET_LOW_REG(d));
1553 M_SRL_IMM(iptr->val.i & 0x3f, GET_HIGH_REG(d));
1555 emit_store(jd, iptr, iptr->dst, d);
1558 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1560 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1561 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1562 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1569 emit_store(jd, iptr, iptr->dst, d);
1572 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1573 /* val.i = constant */
1575 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1576 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1578 M_AND_IMM(iptr->val.i, d);
1579 emit_store(jd, iptr, iptr->dst, d);
1582 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1584 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1585 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1586 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1587 if (s2 == GET_LOW_REG(d))
1588 M_AND(s1, GET_LOW_REG(d));
1590 M_INTMOVE(s1, GET_LOW_REG(d));
1591 M_AND(s2, GET_LOW_REG(d));
1593 /* REG_ITMP1 probably contains low 32-bit of destination */
1594 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1595 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1596 if (s2 == GET_HIGH_REG(d))
1597 M_AND(s1, GET_HIGH_REG(d));
1599 M_INTMOVE(s1, GET_HIGH_REG(d));
1600 M_AND(s2, GET_HIGH_REG(d));
1602 emit_store(jd, iptr, iptr->dst, d);
1605 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1606 /* val.l = constant */
1608 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1609 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1611 M_AND_IMM(iptr->val.l, GET_LOW_REG(d));
1612 M_AND_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1613 emit_store(jd, iptr, iptr->dst, d);
1616 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1618 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1619 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1620 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1627 emit_store(jd, iptr, iptr->dst, d);
1630 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1631 /* val.i = constant */
1633 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1634 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1636 M_OR_IMM(iptr->val.i, d);
1637 emit_store(jd, iptr, iptr->dst, d);
1640 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1642 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1643 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1644 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1645 if (s2 == GET_LOW_REG(d))
1646 M_OR(s1, GET_LOW_REG(d));
1648 M_INTMOVE(s1, GET_LOW_REG(d));
1649 M_OR(s2, GET_LOW_REG(d));
1651 /* REG_ITMP1 probably contains low 32-bit of destination */
1652 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1653 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1654 if (s2 == GET_HIGH_REG(d))
1655 M_OR(s1, GET_HIGH_REG(d));
1657 M_INTMOVE(s1, GET_HIGH_REG(d));
1658 M_OR(s2, GET_HIGH_REG(d));
1660 emit_store(jd, iptr, iptr->dst, d);
1663 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1664 /* val.l = constant */
1666 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1667 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1669 M_OR_IMM(iptr->val.l, GET_LOW_REG(d));
1670 M_OR_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1671 emit_store(jd, iptr, iptr->dst, d);
1674 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1676 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1677 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1678 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1685 emit_store(jd, iptr, iptr->dst, d);
1688 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1689 /* val.i = constant */
1691 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1692 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1694 M_XOR_IMM(iptr->val.i, d);
1695 emit_store(jd, iptr, iptr->dst, d);
1698 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1700 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1701 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1702 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1703 if (s2 == GET_LOW_REG(d))
1704 M_XOR(s1, GET_LOW_REG(d));
1706 M_INTMOVE(s1, GET_LOW_REG(d));
1707 M_XOR(s2, GET_LOW_REG(d));
1709 /* REG_ITMP1 probably contains low 32-bit of destination */
1710 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
1711 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
1712 if (s2 == GET_HIGH_REG(d))
1713 M_XOR(s1, GET_HIGH_REG(d));
1715 M_INTMOVE(s1, GET_HIGH_REG(d));
1716 M_XOR(s2, GET_HIGH_REG(d));
1718 emit_store(jd, iptr, iptr->dst, d);
1721 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1722 /* val.l = constant */
1724 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
1725 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1727 M_XOR_IMM(iptr->val.l, GET_LOW_REG(d));
1728 M_XOR_IMM(iptr->val.l >> 32, GET_HIGH_REG(d));
1729 emit_store(jd, iptr, iptr->dst, d);
1732 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1733 /* op1 = variable, val.i = constant */
1735 #if defined(ENABLE_SSA)
1738 /* with SSA in op1 is the source Local Var, in val._i.op1_t */
1739 /* the target Local Var, in val._i.i the constant */
1740 /* val._i.op1_t <- op1 + val._i.i */
1743 var = &(rd->locals[iptr->op1][TYPE_INT]);
1744 var_t = &(rd->locals[iptr->val._i.op1_t][TYPE_INT]);
1746 /* set s1 to reg of destination or REG_ITMP1 */
1747 if (var_t->flags & INMEMORY)
1752 /* move source value to s1 */
1753 if (var->flags & INMEMORY)
1754 M_ILD( s1, REG_SP, var->regoff * 4);
1756 M_INTMOVE(var->regoff, s1);
1758 /* `inc reg' is slower on p4's (regarding to ia32
1759 optimization reference manual and benchmarks) and as
1760 fast on athlon's. */
1762 M_IADD_IMM(iptr->val._i.i, s1);
1764 if (var_t->flags & INMEMORY)
1765 M_IST(s1, REG_SP, var_t->regoff * 4);
1768 #endif /* defined(ENABLE_SSA) */
1770 var = &(rd->locals[iptr->op1][TYPE_INT]);
1771 if (var->flags & INMEMORY) {
1773 M_ILD(s1, REG_SP, var->regoff * 4);
1778 /* `inc reg' is slower on p4's (regarding to ia32
1779 optimization reference manual and benchmarks) and as
1780 fast on athlon's. */
1782 M_IADD_IMM(iptr->val.i, s1);
1784 if (var->flags & INMEMORY)
1785 M_IST(s1, REG_SP, var->regoff * 4);
1790 /* floating operations ************************************************/
1792 case ICMD_FNEG: /* ..., value ==> ..., - value */
1794 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1795 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1797 emit_store(jd, iptr, iptr->dst, d);
1800 case ICMD_DNEG: /* ..., value ==> ..., - value */
1802 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1803 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1805 emit_store(jd, iptr, iptr->dst, d);
1808 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1810 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1811 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1812 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1814 emit_store(jd, iptr, iptr->dst, d);
1817 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1819 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1820 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1821 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1823 emit_store(jd, iptr, iptr->dst, d);
1826 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1828 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1829 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1830 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1832 emit_store(jd, iptr, iptr->dst, d);
1835 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1837 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1838 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1839 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1841 emit_store(jd, iptr, iptr->dst, d);
1844 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1846 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1847 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1848 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1850 emit_store(jd, iptr, iptr->dst, d);
1853 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1855 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1856 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1857 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1859 emit_store(jd, iptr, iptr->dst, d);
1862 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1864 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1865 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1866 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1868 emit_store(jd, iptr, iptr->dst, d);
1871 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1873 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1874 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1875 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1877 emit_store(jd, iptr, iptr->dst, d);
1880 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1882 /* exchanged to skip fxch */
1883 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1884 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1885 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1886 /* emit_fxch(cd); */
1891 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1892 emit_store(jd, iptr, iptr->dst, d);
1893 emit_ffree_reg(cd, 0);
1897 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1899 /* exchanged to skip fxch */
1900 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1901 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1902 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1903 /* emit_fxch(cd); */
1908 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1909 emit_store(jd, iptr, iptr->dst, d);
1910 emit_ffree_reg(cd, 0);
1914 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1915 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1917 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1918 if (src->flags & INMEMORY) {
1919 emit_fildl_membase(cd, REG_SP, src->regoff * 4);
1922 disp = dseg_adds4(cd, 0);
1923 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1925 emit_mov_reg_membase(cd, src->regoff, REG_ITMP1, disp);
1926 emit_fildl_membase(cd, REG_ITMP1, disp);
1928 emit_store(jd, iptr, iptr->dst, d);
1931 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1932 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1934 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1935 if (src->flags & INMEMORY) {
1936 emit_fildll_membase(cd, REG_SP, src->regoff * 4);
1939 log_text("L2F: longs have to be in memory");
1942 emit_store(jd, iptr, iptr->dst, d);
1945 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1947 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1948 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
1950 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1953 /* Round to zero, 53-bit mode, exception masked */
1954 disp = dseg_adds4(cd, 0x0e7f);
1955 emit_fldcw_membase(cd, REG_ITMP1, disp);
1957 if (iptr->dst->flags & INMEMORY) {
1958 emit_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 4);
1960 /* Round to nearest, 53-bit mode, exceptions masked */
1961 disp = dseg_adds4(cd, 0x027f);
1962 emit_fldcw_membase(cd, REG_ITMP1, disp);
1964 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4);
1967 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1969 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
1972 disp = dseg_adds4(cd, 0);
1973 emit_fistpl_membase(cd, REG_ITMP1, disp);
1974 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst->regoff);
1976 /* Round to nearest, 53-bit mode, exceptions masked */
1977 disp = dseg_adds4(cd, 0x027f);
1978 emit_fldcw_membase(cd, REG_ITMP1, disp);
1980 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst->regoff);
1983 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
1984 disp += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
1987 emit_jcc(cd, CC_NE, disp);
1989 /* XXX: change this when we use registers */
1990 emit_flds_membase(cd, REG_SP, src->regoff * 4);
1991 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1992 emit_call_reg(cd, REG_ITMP1);
1994 if (iptr->dst->flags & INMEMORY) {
1995 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
1998 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2002 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2004 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2005 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2007 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2010 /* Round to zero, 53-bit mode, exception masked */
2011 disp = dseg_adds4(cd, 0x0e7f);
2012 emit_fldcw_membase(cd, REG_ITMP1, disp);
2014 if (iptr->dst->flags & INMEMORY) {
2015 emit_fistpl_membase(cd, REG_SP, iptr->dst->regoff * 4);
2017 /* Round to nearest, 53-bit mode, exceptions masked */
2018 disp = dseg_adds4(cd, 0x027f);
2019 emit_fldcw_membase(cd, REG_ITMP1, disp);
2021 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4);
2024 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2026 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2029 disp = dseg_adds4(cd, 0);
2030 emit_fistpl_membase(cd, REG_ITMP1, disp);
2031 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst->regoff);
2033 /* Round to nearest, 53-bit mode, exceptions masked */
2034 disp = dseg_adds4(cd, 0x027f);
2035 emit_fldcw_membase(cd, REG_ITMP1, disp);
2037 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst->regoff);
2040 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2041 disp += 5 + 2 + ((REG_RESULT == iptr->dst->regoff) ? 0 : 2);
2044 emit_jcc(cd, CC_NE, disp);
2046 /* XXX: change this when we use registers */
2047 emit_fldl_membase(cd, REG_SP, src->regoff * 4);
2048 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
2049 emit_call_reg(cd, REG_ITMP1);
2051 if (iptr->dst->flags & INMEMORY) {
2052 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2054 M_INTMOVE(REG_RESULT, iptr->dst->regoff);
2058 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2060 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2061 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2063 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2066 /* Round to zero, 53-bit mode, exception masked */
2067 disp = dseg_adds4(cd, 0x0e7f);
2068 emit_fldcw_membase(cd, REG_ITMP1, disp);
2070 if (iptr->dst->flags & INMEMORY) {
2071 emit_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 4);
2073 /* Round to nearest, 53-bit mode, exceptions masked */
2074 disp = dseg_adds4(cd, 0x027f);
2075 emit_fldcw_membase(cd, REG_ITMP1, disp);
2077 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4 + 4);
2080 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2082 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2085 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2087 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4 + 4);
2089 emit_jcc(cd, CC_NE, disp);
2091 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst->regoff * 4);
2094 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2096 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2098 emit_jcc(cd, CC_NE, disp);
2100 /* XXX: change this when we use registers */
2101 emit_flds_membase(cd, REG_SP, src->regoff * 4);
2102 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
2103 emit_call_reg(cd, REG_ITMP1);
2104 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2105 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
2108 log_text("F2L: longs have to be in memory");
2113 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2115 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2116 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
2118 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2121 /* Round to zero, 53-bit mode, exception masked */
2122 disp = dseg_adds4(cd, 0x0e7f);
2123 emit_fldcw_membase(cd, REG_ITMP1, disp);
2125 if (iptr->dst->flags & INMEMORY) {
2126 emit_fistpll_membase(cd, REG_SP, iptr->dst->regoff * 4);
2128 /* Round to nearest, 53-bit mode, exceptions masked */
2129 disp = dseg_adds4(cd, 0x027f);
2130 emit_fldcw_membase(cd, REG_ITMP1, disp);
2132 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst->regoff * 4 + 4);
2135 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2137 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2140 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2142 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4 + 4);
2144 emit_jcc(cd, CC_NE, disp);
2146 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst->regoff * 4);
2149 CALCOFFSETBYTES(disp, REG_SP, src->regoff * 4);
2151 CALCOFFSETBYTES(disp, REG_SP, iptr->dst->regoff * 4);
2153 emit_jcc(cd, CC_NE, disp);
2155 /* XXX: change this when we use registers */
2156 emit_fldl_membase(cd, REG_SP, src->regoff * 4);
2157 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
2158 emit_call_reg(cd, REG_ITMP1);
2159 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst->regoff * 4);
2160 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst->regoff * 4 + 4);
2163 log_text("D2L: longs have to be in memory");
2168 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2170 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2171 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2173 emit_store(jd, iptr, iptr->dst, d);
2176 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2178 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2179 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2181 emit_store(jd, iptr, iptr->dst, d);
2184 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2187 /* exchanged to skip fxch */
2188 s2 = emit_load_s2(jd, iptr, src->prev, REG_FTMP1);
2189 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2190 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2191 /* emit_fxch(cd); */
2194 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
2195 emit_jcc(cd, CC_E, 6);
2196 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
2198 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2199 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2200 emit_jcc(cd, CC_B, 3 + 5);
2201 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2202 emit_jmp_imm(cd, 3);
2203 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2204 emit_store(jd, iptr, iptr->dst, d);
2207 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2210 /* exchanged to skip fxch */
2211 s2 = emit_load_s2(jd, iptr, src->prev, REG_FTMP1);
2212 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2213 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2214 /* emit_fxch(cd); */
2217 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
2218 emit_jcc(cd, CC_E, 3);
2219 emit_movb_imm_reg(cd, 1, REG_AH);
2221 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2222 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2223 emit_jcc(cd, CC_B, 3 + 5);
2224 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2225 emit_jmp_imm(cd, 3);
2226 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2227 emit_store(jd, iptr, iptr->dst, d);
2231 /* memory operations **************************************************/
2233 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2235 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2236 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2237 gen_nullptr_check(s1);
2238 M_ILD(d, s1, OFFSET(java_arrayheader, size));
2239 emit_store(jd, iptr, iptr->dst, d);
2242 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2244 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2245 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2246 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2247 if (iptr->op1 == 0) {
2248 gen_nullptr_check(s1);
2251 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2252 emit_store(jd, iptr, iptr->dst, d);
2255 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2257 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2258 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2259 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2260 if (iptr->op1 == 0) {
2261 gen_nullptr_check(s1);
2264 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2265 emit_store(jd, iptr, iptr->dst, d);
2268 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2270 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2271 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2272 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2273 if (iptr->op1 == 0) {
2274 gen_nullptr_check(s1);
2277 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2278 emit_store(jd, iptr, iptr->dst, d);
2281 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2283 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2284 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2285 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2286 if (iptr->op1 == 0) {
2287 gen_nullptr_check(s1);
2290 emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2291 emit_store(jd, iptr, iptr->dst, d);
2294 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2296 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2297 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2298 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
2299 if (iptr->op1 == 0) {
2300 gen_nullptr_check(s1);
2303 assert(iptr->dst->flags & INMEMORY);
2304 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2305 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 4);
2306 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2307 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst->regoff * 4 + 4);
2310 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2312 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2313 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2314 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2315 if (iptr->op1 == 0) {
2316 gen_nullptr_check(s1);
2319 emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2320 emit_store(jd, iptr, iptr->dst, d);
2323 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2325 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2326 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2327 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
2328 if (iptr->op1 == 0) {
2329 gen_nullptr_check(s1);
2332 emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2333 emit_store(jd, iptr, iptr->dst, d);
2336 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2338 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2339 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2340 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
2341 if (iptr->op1 == 0) {
2342 gen_nullptr_check(s1);
2345 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2346 emit_store(jd, iptr, iptr->dst, d);
2350 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2352 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2353 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2354 if (iptr->op1 == 0) {
2355 gen_nullptr_check(s1);
2358 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2359 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2360 M_INTMOVE(s3, REG_ITMP3);
2363 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2366 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2368 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2369 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2370 if (iptr->op1 == 0) {
2371 gen_nullptr_check(s1);
2374 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2375 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2378 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2380 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2381 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2382 if (iptr->op1 == 0) {
2383 gen_nullptr_check(s1);
2386 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2387 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2390 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2392 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2393 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2394 if (iptr->op1 == 0) {
2395 gen_nullptr_check(s1);
2398 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2399 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2402 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2404 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2405 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2406 if (iptr->op1 == 0) {
2407 gen_nullptr_check(s1);
2410 assert(src->flags & INMEMORY);
2411 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4, REG_ITMP3);
2412 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2413 emit_mov_membase_reg(cd, REG_SP, src->regoff * 4 + 4, REG_ITMP3);
2414 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2417 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2419 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2420 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2421 if (iptr->op1 == 0) {
2422 gen_nullptr_check(s1);
2425 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
2426 emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2429 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2431 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2432 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2433 if (iptr->op1 == 0) {
2434 gen_nullptr_check(s1);
2437 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
2438 emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2441 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2443 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2444 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2445 if (iptr->op1 == 0) {
2446 gen_nullptr_check(s1);
2449 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2451 M_AST(s1, REG_SP, 0 * 4);
2452 M_AST(s3, REG_SP, 1 * 4);
2453 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2457 codegen_add_arraystoreexception_ref(cd);
2459 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
2460 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
2461 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
2462 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2465 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2467 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2468 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2469 if (iptr->op1 == 0) {
2470 gen_nullptr_check(s1);
2473 emit_movb_imm_memindex(cd, iptr->val.i, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2476 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2478 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2479 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2480 if (iptr->op1 == 0) {
2481 gen_nullptr_check(s1);
2484 emit_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_chararray, data[0]), s1, s2, 1);
2487 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2489 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2490 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2491 if (iptr->op1 == 0) {
2492 gen_nullptr_check(s1);
2495 emit_movw_imm_memindex(cd, iptr->val.i, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2498 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2500 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2501 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2502 if (iptr->op1 == 0) {
2503 gen_nullptr_check(s1);
2506 emit_mov_imm_memindex(cd, iptr->val.i, OFFSET(java_intarray, data[0]), s1, s2, 2);
2509 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2511 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2512 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2513 if (iptr->op1 == 0) {
2514 gen_nullptr_check(s1);
2517 emit_mov_imm_memindex(cd, (u4) (iptr->val.l & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2518 emit_mov_imm_memindex(cd, (u4) (iptr->val.l >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2521 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2523 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2524 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2525 if (iptr->op1 == 0) {
2526 gen_nullptr_check(s1);
2529 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2533 case ICMD_GETSTATIC: /* ... ==> ..., value */
2534 /* op1 = type, val.a = field address */
2536 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2537 codegen_addpatchref(cd, PATCHER_get_putstatic,
2538 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2540 if (opt_showdisassemble) {
2541 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2548 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2550 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2551 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2553 if (opt_showdisassemble) {
2554 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2558 disp = (ptrint) &(fi->value);
2561 M_MOV_IMM(disp, REG_ITMP1);
2562 switch (iptr->op1) {
2565 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2566 M_ILD(d, REG_ITMP1, 0);
2569 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP23_PACKED);
2570 M_LLD(d, REG_ITMP1, 0);
2573 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2574 M_FLD(d, REG_ITMP1, 0);
2577 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2578 M_DLD(d, REG_ITMP1, 0);
2581 emit_store(jd, iptr, iptr->dst, d);
2584 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2585 /* op1 = type, val.a = field address */
2587 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2588 codegen_addpatchref(cd, PATCHER_get_putstatic,
2589 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2591 if (opt_showdisassemble) {
2592 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2599 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2601 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2602 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2604 if (opt_showdisassemble) {
2605 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2609 disp = (ptrint) &(fi->value);
2612 M_MOV_IMM(disp, REG_ITMP1);
2613 switch (iptr->op1) {
2616 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
2617 M_IST(s1, REG_ITMP1, 0);
2620 s1 = emit_load_s1(jd, iptr, src, REG_ITMP23_PACKED);
2621 M_LST(s1, REG_ITMP1, 0);
2624 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2625 emit_fstps_membase(cd, REG_ITMP1, 0);
2628 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2629 emit_fstpl_membase(cd, REG_ITMP1, 0);
2634 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2635 /* val = value (in current instruction) */
2636 /* op1 = type, val.a = field address (in */
2637 /* following NOP) */
2639 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2640 codegen_addpatchref(cd, PATCHER_get_putstatic,
2641 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2643 if (opt_showdisassemble) {
2644 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2651 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2653 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2654 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2656 if (opt_showdisassemble) {
2657 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2661 disp = (ptrint) &(fi->value);
2664 M_MOV_IMM(disp, REG_ITMP1);
2665 switch (iptr[1].op1) {
2669 M_IST_IMM(iptr->val.i, REG_ITMP1, 0);
2673 M_LST_IMM(iptr->val.l, REG_ITMP1, 0);
2678 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2679 /* op1 = type, val.i = field offset */
2681 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2682 gen_nullptr_check(s1);
2684 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2685 codegen_addpatchref(cd, PATCHER_getfield,
2686 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2688 if (opt_showdisassemble) {
2689 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2696 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2698 switch (iptr->op1) {
2701 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2702 M_ILD32(d, s1, disp);
2705 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP23_PACKED);
2706 M_LLD32(d, s1, disp);
2709 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2710 M_FLD32(d, s1, disp);
2713 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2714 M_DLD32(d, s1, disp);
2717 emit_store(jd, iptr, iptr->dst, d);
2720 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2721 /* op1 = type, val.a = field address */
2723 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2724 gen_nullptr_check(s1);
2726 /* must be done here because of code patching */
2728 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2729 if (IS_2_WORD_TYPE(iptr->op1))
2730 s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
2732 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2735 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2737 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2738 codegen_addpatchref(cd, PATCHER_putfield,
2739 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2741 if (opt_showdisassemble) {
2742 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2749 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2751 switch (iptr->op1) {
2754 M_IST32(s2, s1, disp);
2757 M_LST32(s2, s1, disp);
2760 emit_fstps_membase32(cd, s1, disp);
2763 emit_fstpl_membase32(cd, s1, disp);
2768 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2769 /* val = value (in current instruction) */
2770 /* op1 = type, val.a = field address (in */
2771 /* following NOP) */
2773 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2774 gen_nullptr_check(s1);
2776 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2777 codegen_addpatchref(cd, PATCHER_putfieldconst,
2778 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2780 if (opt_showdisassemble) {
2781 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2788 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2790 switch (iptr[1].op1) {
2794 M_IST32_IMM(iptr->val.i, s1, disp);
2798 M_LST32_IMM(iptr->val.l, s1, disp);
2804 /* branch operations **************************************************/
2806 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2808 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2809 M_INTMOVE(s1, REG_ITMP1_XPTR);
2811 #ifdef ENABLE_VERIFIER
2813 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2814 (unresolved_class *) iptr->val.a, 0);
2816 if (opt_showdisassemble) {
2817 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2820 #endif /* ENABLE_VERIFIER */
2822 M_CALL_IMM(0); /* passing exception pc */
2823 M_POP(REG_ITMP2_XPC);
2825 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2829 case ICMD_INLINE_GOTO:
2831 M_COPY(src, iptr->dst);
2834 case ICMD_GOTO: /* ... ==> ... */
2835 /* op1 = target JavaVM pc */
2837 #if defined(ENABLE_SSA)
2839 last_cmd_was_goto = true;
2840 /* In case of a Goto phimoves have to be inserted before the */
2842 codegen_insert_phi_moves(cd, rd, ls, bptr);
2846 codegen_addreference(cd, (basicblock *) iptr->target);
2850 case ICMD_JSR: /* ... ==> ... */
2851 /* op1 = target JavaVM pc */
2854 codegen_addreference(cd, (basicblock *) iptr->target);
2857 case ICMD_RET: /* ... ==> ... */
2858 /* op1 = local variable */
2860 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2861 if (var->flags & INMEMORY) {
2862 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2869 case ICMD_IFNULL: /* ..., value ==> ... */
2870 /* op1 = target JavaVM pc */
2872 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2875 codegen_addreference(cd, (basicblock *) iptr->target);
2878 case ICMD_IFNONNULL: /* ..., value ==> ... */
2879 /* op1 = target JavaVM pc */
2881 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2884 codegen_addreference(cd, (basicblock *) iptr->target);
2887 case ICMD_IFEQ: /* ..., value ==> ... */
2888 /* op1 = target JavaVM pc, val.i = constant */
2890 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2891 M_CMP_IMM(iptr->val.i, s1);
2893 codegen_addreference(cd, (basicblock *) iptr->target);
2896 case ICMD_IFLT: /* ..., value ==> ... */
2897 /* op1 = target JavaVM pc, val.i = constant */
2899 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2900 M_CMP_IMM(iptr->val.i, s1);
2902 codegen_addreference(cd, (basicblock *) iptr->target);
2905 case ICMD_IFLE: /* ..., value ==> ... */
2906 /* op1 = target JavaVM pc, val.i = constant */
2908 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2909 M_CMP_IMM(iptr->val.i, s1);
2911 codegen_addreference(cd, (basicblock *) iptr->target);
2914 case ICMD_IFNE: /* ..., value ==> ... */
2915 /* op1 = target JavaVM pc, val.i = constant */
2917 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2918 M_CMP_IMM(iptr->val.i, s1);
2920 codegen_addreference(cd, (basicblock *) iptr->target);
2923 case ICMD_IFGT: /* ..., value ==> ... */
2924 /* op1 = target JavaVM pc, val.i = constant */
2926 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2927 M_CMP_IMM(iptr->val.i, s1);
2929 codegen_addreference(cd, (basicblock *) iptr->target);
2932 case ICMD_IFGE: /* ..., value ==> ... */
2933 /* op1 = target JavaVM pc, val.i = constant */
2935 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2936 M_CMP_IMM(iptr->val.i, s1);
2938 codegen_addreference(cd, (basicblock *) iptr->target);
2941 case ICMD_IF_LEQ: /* ..., value ==> ... */
2942 /* op1 = target JavaVM pc, val.l = constant */
2944 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2945 if (iptr->val.l == 0) {
2946 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2947 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2950 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2951 M_XOR_IMM(iptr->val.l, REG_ITMP1);
2952 M_XOR_IMM(iptr->val.l >> 32, REG_ITMP2);
2953 M_OR(REG_ITMP2, REG_ITMP1);
2956 codegen_addreference(cd, (basicblock *) iptr->target);
2959 case ICMD_IF_LLT: /* ..., value ==> ... */
2960 /* op1 = target JavaVM pc, val.l = constant */
2962 if (iptr->val.l == 0) {
2963 /* If high 32-bit are less than zero, then the 64-bits
2965 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
2970 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2971 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
2973 codegen_addreference(cd, (basicblock *) iptr->target);
2975 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
2978 codegen_addreference(cd, (basicblock *) iptr->target);
2981 case ICMD_IF_LLE: /* ..., value ==> ... */
2982 /* op1 = target JavaVM pc, val.l = constant */
2984 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2985 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
2987 codegen_addreference(cd, (basicblock *) iptr->target);
2989 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
2991 codegen_addreference(cd, (basicblock *) iptr->target);
2994 case ICMD_IF_LNE: /* ..., value ==> ... */
2995 /* op1 = target JavaVM pc, val.l = constant */
2997 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2998 if (iptr->val.l == 0) {
2999 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3000 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3003 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3004 M_XOR_IMM(iptr->val.l, REG_ITMP1);
3005 M_XOR_IMM(iptr->val.l >> 32, REG_ITMP2);
3006 M_OR(REG_ITMP2, REG_ITMP1);
3009 codegen_addreference(cd, (basicblock *) iptr->target);
3012 case ICMD_IF_LGT: /* ..., value ==> ... */
3013 /* op1 = target JavaVM pc, val.l = constant */
3015 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3016 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3018 codegen_addreference(cd, (basicblock *) iptr->target);
3020 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3022 codegen_addreference(cd, (basicblock *) iptr->target);
3025 case ICMD_IF_LGE: /* ..., value ==> ... */
3026 /* op1 = target JavaVM pc, val.l = constant */
3028 if (iptr->val.l == 0) {
3029 /* If high 32-bit are greater equal zero, then the
3031 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP2);
3036 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3037 M_CMP_IMM(iptr->val.l >> 32, GET_HIGH_REG(s1));
3039 codegen_addreference(cd, (basicblock *) iptr->target);
3041 M_CMP_IMM32(iptr->val.l, GET_LOW_REG(s1));
3044 codegen_addreference(cd, (basicblock *) iptr->target);
3047 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3048 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3050 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3051 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3054 codegen_addreference(cd, (basicblock *) iptr->target);
3057 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3058 /* op1 = target JavaVM pc */
3060 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3061 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3062 M_INTMOVE(s1, REG_ITMP1);
3063 M_XOR(s2, REG_ITMP1);
3064 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
3065 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
3066 M_INTMOVE(s1, REG_ITMP2);
3067 M_XOR(s2, REG_ITMP2);
3068 M_OR(REG_ITMP1, REG_ITMP2);
3070 codegen_addreference(cd, (basicblock *) iptr->target);
3073 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3074 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3076 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3077 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3080 codegen_addreference(cd, (basicblock *) iptr->target);
3083 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3084 /* op1 = target JavaVM pc */
3086 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3087 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3088 M_INTMOVE(s1, REG_ITMP1);
3089 M_XOR(s2, REG_ITMP1);
3090 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP2);
3091 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3);
3092 M_INTMOVE(s1, REG_ITMP2);
3093 M_XOR(s2, REG_ITMP2);
3094 M_OR(REG_ITMP1, REG_ITMP2);
3096 codegen_addreference(cd, (basicblock *) iptr->target);
3099 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3100 /* op1 = target JavaVM pc */
3102 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3103 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3106 codegen_addreference(cd, (basicblock *) iptr->target);
3109 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3110 /* op1 = target JavaVM pc */
3112 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3113 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3116 codegen_addreference(cd, (basicblock *) iptr->target);
3117 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3118 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3122 codegen_addreference(cd, (basicblock *) iptr->target);
3125 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3126 /* op1 = target JavaVM pc */
3128 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3129 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3132 codegen_addreference(cd, (basicblock *) iptr->target);
3135 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3136 /* op1 = target JavaVM pc */
3138 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3139 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3142 codegen_addreference(cd, (basicblock *) iptr->target);
3143 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3144 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3148 codegen_addreference(cd, (basicblock *) iptr->target);
3151 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3152 /* op1 = target JavaVM pc */
3154 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3155 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3158 codegen_addreference(cd, (basicblock *) iptr->target);
3161 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3162 /* op1 = target JavaVM pc */
3164 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3165 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3168 codegen_addreference(cd, (basicblock *) iptr->target);
3169 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3170 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3174 codegen_addreference(cd, (basicblock *) iptr->target);
3177 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3178 /* op1 = target JavaVM pc */
3180 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
3181 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
3184 codegen_addreference(cd, (basicblock *) iptr->target);
3187 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3188 /* op1 = target JavaVM pc */
3190 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
3191 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
3194 codegen_addreference(cd, (basicblock *) iptr->target);
3195 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
3196 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
3200 codegen_addreference(cd, (basicblock *) iptr->target);
3204 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3206 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3207 M_INTMOVE(s1, REG_RESULT);
3208 goto nowperformreturn;
3210 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3212 s1 = emit_load_s1(jd, iptr, src, REG_RESULT_PACKED);
3213 M_LNGMOVE(s1, REG_RESULT_PACKED);
3214 goto nowperformreturn;
3216 case ICMD_ARETURN: /* ..., retvalue ==> ... */
3218 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
3219 M_INTMOVE(s1, REG_RESULT);
3221 #ifdef ENABLE_VERIFIER
3223 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3224 (unresolved_class *) iptr->val.a, 0);
3226 if (opt_showdisassemble) {
3227 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3230 #endif /* ENABLE_VERIFIER */
3231 goto nowperformreturn;
3233 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3236 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
3237 goto nowperformreturn;
3239 case ICMD_RETURN: /* ... ==> ... */
3245 p = cd->stackframesize;
3247 #if !defined(NDEBUG)
3248 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3249 emit_verbosecall_exit(jd);
3252 #if defined(ENABLE_THREADS)
3253 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3254 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3256 /* we need to save the proper return value */
3257 switch (iptr->opc) {
3260 M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3264 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3268 emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3272 emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3276 M_AST(REG_ITMP2, REG_SP, 0);
3277 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3280 /* and now restore the proper return value */
3281 switch (iptr->opc) {
3284 M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3288 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3292 emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3296 emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3302 /* restore saved registers */
3304 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3305 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3308 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3310 emit_fldl_membase(cd, REG_SP, p * 4);
3311 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3313 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3316 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3320 /* deallocate stack */
3322 if (cd->stackframesize)
3323 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3330 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3335 tptr = (void **) iptr->target;
3337 s4ptr = iptr->val.a;
3338 l = s4ptr[1]; /* low */
3339 i = s4ptr[2]; /* high */
3341 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3342 M_INTMOVE(s1, REG_ITMP1);
3345 M_ISUB_IMM(l, REG_ITMP1);
3351 M_CMP_IMM(i - 1, REG_ITMP1);
3353 codegen_addreference(cd, (basicblock *) tptr[0]);
3355 /* build jump table top down and use address of lowest entry */
3360 dseg_addtarget(cd, (basicblock *) tptr[0]);
3364 /* length of dataseg after last dseg_addtarget is used
3367 M_MOV_IMM(0, REG_ITMP2);
3369 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3375 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3377 s4 i, l, val, *s4ptr;
3380 tptr = (void **) iptr->target;
3382 s4ptr = iptr->val.a;
3383 l = s4ptr[0]; /* default */
3384 i = s4ptr[1]; /* count */
3386 MCODECHECK((i<<2)+8);
3387 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3396 codegen_addreference(cd, (basicblock *) tptr[0]);
3401 tptr = (void **) iptr->target;
3402 codegen_addreference(cd, (basicblock *) tptr[0]);
3406 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
3407 /* op1 = arg count val.a = builtintable entry */
3413 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3414 /* op1 = arg count, val.a = method pointer */
3416 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3417 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3418 case ICMD_INVOKEINTERFACE:
3420 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3421 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3425 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3426 md = lm->parseddesc;
3430 s3 = md->paramcount;
3432 MCODECHECK((s3 << 1) + 64);
3434 /* copy arguments to registers or stack location */
3436 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3437 if (src->varkind == ARGVAR)
3439 if (IS_INT_LNG_TYPE(src->type)) {
3440 if (!md->params[s3].inmemory) {
3441 log_text("No integer argument registers available!");
3445 if (IS_2_WORD_TYPE(src->type)) {
3446 d = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
3447 M_LST(d, REG_SP, md->params[s3].regoff * 4);
3449 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3450 M_IST(d, REG_SP, md->params[s3].regoff * 4);
3455 if (!md->params[s3].inmemory) {
3456 s1 = rd->argfltregs[md->params[s3].regoff];
3457 d = emit_load_s1(jd, iptr, src, s1);
3461 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3462 if (IS_2_WORD_TYPE(src->type))
3463 M_DST(d, REG_SP, md->params[s3].regoff * 4);
3465 M_FST(d, REG_SP, md->params[s3].regoff * 4);
3470 switch (iptr->opc) {
3472 disp = (ptrint) bte->fp;
3473 d = md->returntype.type;
3475 M_MOV_IMM(disp, REG_ITMP1);
3478 /* if op1 == true, we need to check for an exception */
3480 if (iptr->op1 == true) {
3483 codegen_add_fillinstacktrace_ref(cd);
3487 case ICMD_INVOKESPECIAL:
3488 M_ALD(REG_ITMP1, REG_SP, 0);
3491 codegen_add_nullpointerexception_ref(cd);
3495 case ICMD_INVOKESTATIC:
3497 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3499 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3502 if (opt_showdisassemble) {
3503 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3507 d = md->returntype.type;
3510 disp = (ptrint) lm->stubroutine;
3511 d = lm->parseddesc->returntype.type;
3514 M_MOV_IMM(disp, REG_ITMP2);
3518 case ICMD_INVOKEVIRTUAL:
3519 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3520 gen_nullptr_check(REG_ITMP1);
3523 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3525 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3527 if (opt_showdisassemble) {
3528 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3532 d = md->returntype.type;
3535 s1 = OFFSET(vftbl_t, table[0]) +
3536 sizeof(methodptr) * lm->vftblindex;
3537 d = md->returntype.type;
3540 M_ALD(REG_METHODPTR, REG_ITMP1,
3541 OFFSET(java_objectheader, vftbl));
3542 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3546 case ICMD_INVOKEINTERFACE:
3547 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3548 gen_nullptr_check(REG_ITMP1);
3551 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3553 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3555 if (opt_showdisassemble) {
3556 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3561 d = md->returntype.type;
3564 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3565 sizeof(methodptr) * lm->class->index;
3567 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3569 d = md->returntype.type;
3572 M_ALD(REG_METHODPTR, REG_ITMP1,
3573 OFFSET(java_objectheader, vftbl));
3574 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3575 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3580 /* d contains return type */
3582 if (d != TYPE_VOID) {
3583 #if defined(ENABLE_SSA)
3584 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
3585 (ls->lifetime[-iptr->dst->varnum-1].type != -1))
3586 /* a "living" stackslot */
3589 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3590 if (IS_2_WORD_TYPE(iptr->dst->type)) {
3591 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
3592 M_LNGMOVE(REG_RESULT_PACKED, s1);
3595 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3596 M_INTMOVE(REG_RESULT, s1);
3600 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_NULL);
3602 emit_store(jd, iptr, iptr->dst, s1);
3608 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3609 /* op1: 0 == array, 1 == class */
3610 /* val.a: (classinfo*) superclass */
3612 /* superclass is an interface:
3614 * OK if ((sub == NULL) ||
3615 * (sub->vftbl->interfacetablelength > super->index) &&
3616 * (sub->vftbl->interfacetable[-super->index] != NULL));
3618 * superclass is a class:
3620 * OK if ((sub == NULL) || (0
3621 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3622 * super->vftbl->diffval));
3625 if (iptr->op1 == 1) {
3626 /* object type cast-check */
3629 vftbl_t *supervftbl;
3632 super = (classinfo *) iptr->val.a;
3639 superindex = super->index;
3640 supervftbl = super->vftbl;
3643 #if defined(ENABLE_THREADS)
3644 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3646 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3648 /* calculate interface checkcast code size */
3650 s2 = 2; /* mov_membase_reg */
3651 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3653 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3654 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3655 2 /* test */ + 6 /* jcc */);
3658 s2 += (opt_showdisassemble ? 5 : 0);
3660 /* calculate class checkcast code size */
3662 s3 = 2; /* mov_membase_reg */
3663 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3665 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3668 if (s1 != REG_ITMP1) {
3670 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3673 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3680 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3681 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3682 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3685 s3 += 2 /* cmp */ + 6 /* jcc */;
3688 s3 += (opt_showdisassemble ? 5 : 0);
3690 /* if class is not resolved, check which code to call */
3692 if (super == NULL) {
3694 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3696 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3697 (constant_classref *) iptr->target, 0);
3699 if (opt_showdisassemble) {
3700 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3703 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3704 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3708 /* interface checkcast code */
3710 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3711 if (super != NULL) {
3716 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3718 if (super == NULL) {
3719 codegen_addpatchref(cd,
3720 PATCHER_checkcast_instanceof_interface,
3721 (constant_classref *) iptr->target,
3724 if (opt_showdisassemble) {
3725 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3730 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3731 M_ISUB_IMM32(superindex, REG_ITMP3);
3734 codegen_add_classcastexception_ref(cd, s1);
3735 M_ALD32(REG_ITMP3, REG_ITMP2,
3736 OFFSET(vftbl_t, interfacetable[0]) -
3737 superindex * sizeof(methodptr*));
3740 codegen_add_classcastexception_ref(cd, s1);
3746 /* class checkcast code */
3748 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3749 if (super != NULL) {
3754 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3756 if (super == NULL) {
3757 codegen_addpatchref(cd, PATCHER_checkcast_class,
3758 (constant_classref *) iptr->target,
3761 if (opt_showdisassemble) {
3762 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3766 M_MOV_IMM(supervftbl, REG_ITMP3);
3767 #if defined(ENABLE_THREADS)
3768 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3770 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3772 /* if (s1 != REG_ITMP1) { */
3773 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3774 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3775 /* #if defined(ENABLE_THREADS) */
3776 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3778 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3781 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3782 M_ISUB(REG_ITMP3, REG_ITMP2);
3783 M_MOV_IMM(supervftbl, REG_ITMP3);
3784 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3785 #if defined(ENABLE_THREADS)
3786 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3790 M_CMP(REG_ITMP3, REG_ITMP2);
3791 M_BA(0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3792 codegen_add_classcastexception_ref(cd, s1);
3795 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
3798 /* array type cast-check */
3800 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3801 M_AST(s1, REG_SP, 0 * 4);
3803 if (iptr->val.a == NULL) {
3804 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3807 if (opt_showdisassemble) {
3808 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3812 M_AST_IMM(iptr->val.a, REG_SP, 1 * 4);
3813 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3816 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
3819 codegen_add_classcastexception_ref(cd, s1);
3821 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3825 emit_store(jd, iptr, iptr->dst, d);
3828 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3829 /* op1: 0 == array, 1 == class */
3830 /* val.a: (classinfo*) superclass */
3832 /* superclass is an interface:
3834 * return (sub != NULL) &&
3835 * (sub->vftbl->interfacetablelength > super->index) &&
3836 * (sub->vftbl->interfacetable[-super->index] != NULL);
3838 * superclass is a class:
3840 * return ((sub != NULL) && (0
3841 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3842 * super->vftbl->diffvall));
3847 vftbl_t *supervftbl;
3850 super = (classinfo *) iptr->val.a;
3857 superindex = super->index;
3858 supervftbl = super->vftbl;
3861 #if defined(ENABLE_THREADS)
3862 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3865 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3866 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3868 M_INTMOVE(s1, REG_ITMP1);
3872 /* calculate interface instanceof code size */
3874 s2 = 2; /* mov_membase_reg */
3875 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3877 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3878 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3879 2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3882 s2 += (opt_showdisassemble ? 5 : 0);
3884 /* calculate class instanceof code size */
3886 s3 = 2; /* mov_membase_reg */
3887 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3888 s3 += 5; /* mov_imm_reg */
3890 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3892 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3894 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3896 s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3897 2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3900 s3 += (opt_showdisassemble ? 5 : 0);
3904 /* if class is not resolved, check which code to call */
3908 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3910 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3911 (constant_classref *) iptr->target, 0);
3913 if (opt_showdisassemble) {
3914 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3917 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
3918 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3922 /* interface instanceof code */
3924 if (!super || (super->flags & ACC_INTERFACE)) {
3930 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3933 codegen_addpatchref(cd,
3934 PATCHER_checkcast_instanceof_interface,
3935 (constant_classref *) iptr->target, 0);
3937 if (opt_showdisassemble) {
3938 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3943 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3944 M_ISUB_IMM32(superindex, REG_ITMP3);
3947 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3948 6 /* jcc */ + 5 /* mov_imm_reg */);
3951 M_ALD32(REG_ITMP1, REG_ITMP1,
3952 OFFSET(vftbl_t, interfacetable[0]) -
3953 superindex * sizeof(methodptr*));
3955 /* emit_setcc_reg(cd, CC_A, d); */
3956 /* emit_jcc(cd, CC_BE, 5); */
3964 /* class instanceof code */
3966 if (!super || !(super->flags & ACC_INTERFACE)) {
3972 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3975 codegen_addpatchref(cd, PATCHER_instanceof_class,
3976 (constant_classref *) iptr->target, 0);
3978 if (opt_showdisassemble) {
3979 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3983 M_MOV_IMM(supervftbl, REG_ITMP2);
3984 #if defined(ENABLE_THREADS)
3985 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3987 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3988 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3989 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3990 #if defined(ENABLE_THREADS)
3991 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3993 M_ISUB(REG_ITMP2, REG_ITMP1);
3994 M_CLR(d); /* may be REG_ITMP2 */
3995 M_CMP(REG_ITMP3, REG_ITMP1);
3999 emit_store(jd, iptr, iptr->dst, d);
4005 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4006 /* op1 = dimension, val.a = class */
4008 /* check for negative sizes and copy sizes to stack if necessary */
4010 MCODECHECK((iptr->op1 << 1) + 64);
4012 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
4013 /* copy SAVEDVAR sizes to stack */
4015 if (src->varkind != ARGVAR) {
4016 if (src->flags & INMEMORY) {
4017 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
4018 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
4021 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
4025 /* is a patcher function set? */
4027 if (iptr->val.a == NULL) {
4028 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4029 (constant_classref *) iptr->target, 0);
4031 if (opt_showdisassemble) {
4032 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4039 disp = (ptrint) iptr->val.a;
4041 /* a0 = dimension count */
4043 M_IST_IMM(iptr->op1, REG_SP, 0 * 4);
4045 /* a1 = arraydescriptor */
4047 M_IST_IMM(disp, REG_SP, 1 * 4);
4049 /* a2 = pointer to dimensions = stack pointer */
4051 M_MOV(REG_SP, REG_ITMP1);
4052 M_AADD_IMM(3 * 4, REG_ITMP1);
4053 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4055 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4058 /* check for exception before result assignment */
4062 codegen_add_fillinstacktrace_ref(cd);
4064 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
4065 M_INTMOVE(REG_RESULT, s1);
4066 emit_store(jd, iptr, iptr->dst, s1);
4071 new_internalerror("Unknown ICMD %d", iptr->opc);
4075 } /* for instruction */
4077 /* copy values to interface registers */
4079 src = bptr->outstack;
4080 len = bptr->outdepth;
4082 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4085 #if defined(ENABLE_SSA)
4087 /* by edge splitting, in Blocks with phi moves there can only */
4088 /* be a goto as last command, no other Jump/Branch Command */
4089 if (!last_cmd_was_goto)
4090 codegen_insert_phi_moves(cd, rd, ls, bptr);
4095 if ((src->varkind != STACKVAR)) {
4097 if (IS_FLT_DBL_TYPE(s2)) {
4098 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
4099 if (!(rd->interfaces[len][s2].flags & INMEMORY))
4100 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4102 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4105 if (IS_2_WORD_TYPE(s2))
4107 /* s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP1, REG_ITMP2)); */
4109 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
4111 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
4112 if (IS_2_WORD_TYPE(s2))
4113 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
4115 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4118 if (IS_2_WORD_TYPE(s2))
4119 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4121 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4128 /* At the end of a basic block we may have to append some nops,
4129 because the patcher stub calling code might be longer than the
4130 actual instruction. So codepatching does not change the
4131 following block unintentionally. */
4133 if (cd->mcodeptr < cd->lastmcodeptr) {
4134 while (cd->mcodeptr < cd->lastmcodeptr) {
4139 } /* if (bptr -> flags >= BBREACHED) */
4140 } /* for basic block */
4142 dseg_createlinenumbertable(cd);
4145 /* generate exception and patcher stubs */
4147 emit_exception_stubs(jd);
4148 emit_patcher_stubs(jd);
4149 emit_replacement_stubs(jd);
4153 /* everything's ok */
4158 #if defined(ENABLE_SSA)
4159 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls, basicblock *bptr) {
4160 /* look for phi moves */
4161 int t_a,s_a,i, type;
4162 int t_lt, s_lt; /* lifetime indices of phi_moves */
4163 bool t_inmemory, s_inmemory;
4164 s4 t_regoff, s_regoff, s_flags, t_flags;
4167 /* Moves from phi functions with highest indices have to be */
4168 /* inserted first, since this is the order as is used for */
4169 /* conflict resolution */
4170 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
4171 t_a = ls->phi_moves[bptr->nr][i][0];
4172 s_a = ls->phi_moves[bptr->nr][i][1];
4173 #if defined(SSA_DEBUG_VERBOSE)
4175 printf("BB %3i Move %3i <- %3i ",bptr->nr,t_a,s_a);
4178 /* local var lifetimes */
4179 t_lt = ls->maxlifetimes + t_a;
4180 type = ls->lifetime[t_lt].type;
4183 type = ls->lifetime[t_lt].local_ss->s->type;
4184 /* stackslot lifetime */
4187 #if defined(SSA_DEBUG_VERBOSE)
4189 printf("...returning - phi lifetimes where joined\n");
4194 /* local var lifetimes */
4195 s_lt = ls->maxlifetimes + s_a;
4196 type = ls->lifetime[s_lt].type;
4199 type = ls->lifetime[s_lt].type;
4200 /* stackslot lifetime */
4203 #if defined(SSA_DEBUG_VERBOSE)
4205 printf("...returning - phi lifetimes where joined\n");
4211 t_inmemory = rd->locals[t_a][type].flags & INMEMORY;
4212 t_flags = rd->locals[t_a][type].flags;
4213 t_regoff = rd->locals[t_a][type].regoff;
4216 t_inmemory = ls->lifetime[t_lt].local_ss->s->flags & INMEMORY;
4217 t_flags = ls->lifetime[t_lt].local_ss->s->flags;
4218 t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
4222 /* local var move */
4224 s_inmemory = rd->locals[s_a][type].flags & INMEMORY;
4225 s_flags = rd->locals[s_a][type].flags;
4226 s_regoff = rd->locals[s_a][type].regoff;
4228 /* stackslot lifetime */
4229 s_inmemory = ls->lifetime[s_lt].local_ss->s->flags & INMEMORY;
4230 s_flags = ls->lifetime[s_lt].local_ss->s->flags;
4231 s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
4234 #if defined(SSA_DEBUG_VERBOSE)
4236 printf("...returning - phi lifetimes where joined\n");
4241 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
4243 #if defined(SSA_DEBUG_VERBOSE)
4244 if (compileverbose) {
4245 if ((t_inmemory) && (s_inmemory)) {
4247 printf("M%3i <- M%3i",t_regoff,s_regoff);
4248 } else if (s_inmemory) {
4250 printf("R%3i <- M%3i",t_regoff,s_regoff);
4251 } else if (t_inmemory) {
4253 printf("M%3i <- R%3i",t_regoff,s_regoff);
4256 printf("R%3i <- R%3i",t_regoff,s_regoff);
4260 #endif /* defined(SSA_DEBUG_VERBOSE) */
4264 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
4265 s4 dst_regoff, s4 dst_flags) {
4266 if ((dst_flags & INMEMORY) && (src_flags & INMEMORY)) {
4268 if (dst_regoff != src_regoff) {
4269 if (!IS_2_WORD_TYPE(type)) {
4270 if (IS_FLT_DBL_TYPE(type)) {
4271 emit_flds_membase(cd, REG_SP, src_regoff * 4);
4272 emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
4274 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
4276 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
4278 } else { /* LONG OR DOUBLE */
4279 if (IS_FLT_DBL_TYPE(type)) {
4280 emit_fldl_membase( cd, REG_SP, src_regoff * 4);
4281 emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
4283 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
4285 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
4286 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
4288 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP,
4289 dst_regoff * 4 + 4);
4294 if (IS_FLT_DBL_TYPE(type)) {
4295 log_text("cg_move: flt/dbl type have to be in memory\n");
4298 if (IS_2_WORD_TYPE(type)) {
4299 log_text("cg_move: longs have to be in memory\n");
4302 if (src_flags & INMEMORY) {
4304 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
4305 } else if (dst_flags & INMEMORY) {
4307 emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
4310 /* only ints can be in regs on i386 */
4311 M_INTMOVE(src_regoff,dst_regoff);
4315 #endif /* defined(ENABLE_SSA) */
4317 /* createcompilerstub **********************************************************
4319 Creates a stub routine which calls the compiler.
4321 *******************************************************************************/
4323 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
4324 #define COMPILERSTUB_CODESIZE 12
4326 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4329 u1 *createcompilerstub(methodinfo *m)
4331 u1 *s; /* memory to hold the stub */
4337 s = CNEW(u1, COMPILERSTUB_SIZE);
4339 /* set data pointer and code pointer */
4342 s = s + COMPILERSTUB_DATASIZE;
4344 /* mark start of dump memory area */
4346 dumpsize = dump_size();
4348 cd = DNEW(codegendata);
4351 /* Store the codeinfo pointer in the same place as in the
4352 methodheader for compiled methods. */
4354 code = code_codeinfo_new(m);
4356 d[0] = (ptrint) asm_call_jit_compiler;
4358 d[2] = (ptrint) code;
4360 /* code for the stub */
4362 M_MOV_IMM(m, REG_ITMP1); /* method info */
4363 M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
4366 #if defined(ENABLE_STATISTICS)
4368 count_cstub_len += COMPILERSTUB_SIZE;
4371 /* release dump area */
4373 dump_release(dumpsize);
4379 /* createnativestub ************************************************************
4381 Creates a stub routine which calls a native method.
4383 *******************************************************************************/
4385 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4393 s4 i, j; /* count variables */
4397 /* get required compiler data */
4404 /* set some variables */
4407 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4409 /* calculate stackframe size */
4411 cd->stackframesize =
4412 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4413 sizeof(localref_table) / SIZEOF_VOID_P +
4414 1 + /* function pointer */
4415 4 * 4 + /* 4 arguments (start_native_call) */
4418 /* keep stack 16-byte aligned */
4420 cd->stackframesize |= 0x3;
4422 /* create method header */
4424 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
4425 (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
4426 (void) dseg_adds4(cd, 0); /* IsSync */
4427 (void) dseg_adds4(cd, 0); /* IsLeaf */
4428 (void) dseg_adds4(cd, 0); /* IntSave */
4429 (void) dseg_adds4(cd, 0); /* FltSave */
4430 (void) dseg_addlinenumbertablesize(cd);
4431 (void) dseg_adds4(cd, 0); /* ExTableSize */
4433 /* generate native method profiling code */
4435 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4436 /* count frequency */
4438 M_MOV_IMM(code, REG_ITMP1);
4439 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
4442 /* calculate stackframe size for native function */
4444 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
4446 #if !defined(NDEBUG)
4447 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4448 emit_verbosecall_enter(jd);
4451 /* get function address (this must happen before the stackframeinfo) */
4453 #if !defined(WITH_STATIC_CLASSPATH)
4455 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
4457 if (opt_showdisassemble) {
4458 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4463 M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
4465 /* Mark the whole fpu stack as free for native functions (only for saved */
4466 /* register count == 0). */
4468 emit_ffree_reg(cd, 0);
4469 emit_ffree_reg(cd, 1);
4470 emit_ffree_reg(cd, 2);
4471 emit_ffree_reg(cd, 3);
4472 emit_ffree_reg(cd, 4);
4473 emit_ffree_reg(cd, 5);
4474 emit_ffree_reg(cd, 6);
4475 emit_ffree_reg(cd, 7);
4477 /* prepare data structures for native function call */
4479 M_MOV(REG_SP, REG_ITMP1);
4480 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
4482 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4483 M_IST_IMM(0, REG_SP, 1 * 4);
4486 M_MOV(REG_SP, REG_ITMP2);
4487 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
4489 M_AST(REG_ITMP2, REG_SP, 2 * 4);
4490 M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
4491 M_AST(REG_ITMP3, REG_SP, 3 * 4);
4492 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
4495 M_ALD(REG_ITMP3, REG_SP, 4 * 4);
4497 /* copy arguments into new stackframe */
4499 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4500 t = md->paramtypes[i].type;
4502 if (!md->params[i].inmemory) {
4503 /* no integer argument registers */
4504 } else { /* float/double in memory can be copied like int/longs */
4505 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
4506 s2 = nmd->params[j].regoff * 4;
4508 M_ILD(REG_ITMP1, REG_SP, s1);
4509 M_IST(REG_ITMP1, REG_SP, s2);
4510 if (IS_2_WORD_TYPE(t)) {
4511 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
4512 M_IST(REG_ITMP1, REG_SP, s2 + 4);
4517 /* if function is static, put class into second argument */
4519 if (m->flags & ACC_STATIC)
4520 M_AST_IMM(m->class, REG_SP, 1 * 4);
4522 /* put env into first argument */
4524 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
4526 /* call the native function */
4530 /* save return value */
4532 if (md->returntype.type != TYPE_VOID) {
4533 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4534 if (IS_2_WORD_TYPE(md->returntype.type))
4535 M_IST(REG_RESULT2, REG_SP, 2 * 4);
4536 M_IST(REG_RESULT, REG_SP, 1 * 4);
4539 if (IS_2_WORD_TYPE(md->returntype.type))
4540 emit_fstl_membase(cd, REG_SP, 1 * 4);
4542 emit_fsts_membase(cd, REG_SP, 1 * 4);
4546 #if !defined(NDEBUG)
4547 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4548 emit_verbosecall_exit(jd);
4551 /* remove native stackframe info */
4553 M_MOV(REG_SP, REG_ITMP1);
4554 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
4556 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4557 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
4559 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
4561 /* restore return value */
4563 if (md->returntype.type != TYPE_VOID) {
4564 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4565 if (IS_2_WORD_TYPE(md->returntype.type))
4566 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4567 M_ILD(REG_RESULT, REG_SP, 1 * 4);
4570 if (IS_2_WORD_TYPE(md->returntype.type))
4571 emit_fldl_membase(cd, REG_SP, 1 * 4);
4573 emit_flds_membase(cd, REG_SP, 1 * 4);
4577 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
4579 /* check for exception */
4586 /* handle exception */
4588 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
4589 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
4590 M_ASUB_IMM(2, REG_ITMP2_XPC);
4592 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4596 /* generate patcher stubs */
4598 emit_patcher_stubs(jd);
4602 return code->entrypoint;
4607 * These are local overrides for various environment variables in Emacs.
4608 * Please do not remove this and leave it at the end of the file, where
4609 * Emacs will automagically detect them.
4610 * ---------------------------------------------------------------------
4613 * indent-tabs-mode: t
4617 * vim:noexpandtab:sw=4:ts=4: