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 5401 2006-09-07 12:52:31Z twisti $
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 unresolved_method *um;
114 builtintable_entry *bte;
116 rplpoint *replacementpoint;
118 #if defined(ENABLE_SSA)
120 bool last_cmd_was_goto;
122 last_cmd_was_goto = false;
126 /* get required compiler data */
133 /* prevent compiler warnings */
143 s4 savedregs_num = 0;
146 /* space to save used callee saved registers */
148 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
150 /* float register are saved on 2 4-byte stackslots */
151 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
153 cd->stackframesize = rd->memuse + savedregs_num;
156 #if defined(ENABLE_THREADS)
157 /* space to save argument of monitor_enter */
159 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
160 /* reserve 2 slots for long/double return values for monitorexit */
162 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
163 cd->stackframesize += 2;
165 cd->stackframesize++;
169 /* create method header */
171 /* Keep stack of non-leaf functions 16-byte aligned. */
173 if (!jd->isleafmethod)
174 cd->stackframesize |= 0x3;
176 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
177 (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
179 #if defined(ENABLE_THREADS)
180 /* IsSync contains the offset relative to the stack pointer for the
181 argument of monitor_exit used in the exception handler. Since the
182 offset could be zero and give a wrong meaning of the flag it is
186 if (checksync && (m->flags & ACC_SYNCHRONIZED))
187 (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
190 (void) dseg_adds4(cd, 0); /* IsSync */
192 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
193 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
194 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
196 /* adds a reference for the length of the line number counter. We don't
197 know the size yet, since we evaluate the information during code
198 generation, to save one additional iteration over the whole
199 instructions. During code optimization the position could have changed
200 to the information gotten from the class file */
201 (void) dseg_addlinenumbertablesize(cd);
203 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
205 /* create exception table */
207 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
208 dseg_addtarget(cd, ex->start);
209 dseg_addtarget(cd, ex->end);
210 dseg_addtarget(cd, ex->handler);
211 (void) dseg_addaddress(cd, ex->catchtype.cls);
214 /* generate method profiling code */
216 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
217 /* count frequency */
219 M_MOV_IMM(code, REG_ITMP3);
220 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
223 /* create stack frame (if necessary) */
225 if (cd->stackframesize)
226 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
228 /* save return address and used callee saved registers */
230 p = cd->stackframesize;
231 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
232 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
234 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
235 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
238 /* take arguments out of register or stack frame */
243 for (p = 0, l = 0; p < md->paramcount; p++) {
244 t = md->paramtypes[p].type;
245 #if defined(ENABLE_SSA)
250 var = &(rd->locals[l][t]);
252 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
256 s1 = md->params[p].regoff;
258 if (IS_INT_LNG_TYPE(t)) { /* integer args */
259 if (!md->params[p].inmemory) { /* register arguments */
260 log_text("integer register argument");
262 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
263 /* rd->argintregs[md->params[p].regoff -> var->regoff */
265 else { /* reg arg -> spilled */
266 /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
269 else { /* stack arguments */
270 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
271 emit_mov_membase_reg( /* + 4 for return address */
272 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->regoff);
273 /* + 4 for return address */
275 else { /* stack arg -> spilled */
276 if (!IS_2_WORD_TYPE(t)) {
277 #if defined(ENABLE_SSA)
278 /* no copy avoiding by now possible with SSA */
280 emit_mov_membase_reg( /* + 4 for return address */
281 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
283 emit_mov_reg_membase(
284 cd, REG_ITMP1, REG_SP, var->regoff * 4);
287 #endif /*defined(ENABLE_SSA)*/
288 /* reuse Stackslotand avoid copying */
289 var->regoff = cd->stackframesize + s1 + 1;
293 #if defined(ENABLE_SSA)
294 /* no copy avoiding by now possible with SSA */
296 emit_mov_membase_reg( /* + 4 for return address */
297 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
299 emit_mov_reg_membase(
300 cd, REG_ITMP1, REG_SP, var->regoff * 4);
301 emit_mov_membase_reg( /* + 4 for return address */
302 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
304 emit_mov_reg_membase(
305 cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
308 #endif /*defined(ENABLE_SSA)*/
309 /* reuse Stackslotand avoid copying */
310 var->regoff = cd->stackframesize + s1 + 1;
315 else { /* floating args */
316 if (!md->params[p].inmemory) { /* register arguments */
317 log_text("There are no float argument registers!");
319 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
320 /* rd->argfltregs[md->params[p].regoff -> var->regoff */
321 } else { /* reg arg -> spilled */
322 /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
326 else { /* stack arguments */
327 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
330 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
332 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
337 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
339 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
342 } else { /* stack-arg -> spilled */
343 #if defined(ENABLE_SSA)
344 /* no copy avoiding by now possible with SSA */
346 emit_mov_membase_reg(
347 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
348 emit_mov_reg_membase(
349 cd, REG_ITMP1, REG_SP, var->regoff * 4);
352 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
353 emit_fstps_membase(cd, REG_SP, var->regoff * 4);
357 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
358 emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
362 #endif /*defined(ENABLE_SSA)*/
363 /* reuse Stackslotand avoid copying */
364 var->regoff = cd->stackframesize + s1 + 1;
370 /* call monitorenter function */
372 #if defined(ENABLE_THREADS)
373 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
376 if (m->flags & ACC_STATIC) {
377 M_MOV_IMM(&m->class->object.header, REG_ITMP1);
380 M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
383 codegen_add_nullpointerexception_ref(cd);
386 M_AST(REG_ITMP1, REG_SP, s1 * 4);
387 M_AST(REG_ITMP1, REG_SP, 0 * 4);
388 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
394 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
395 emit_verbosecall_enter(jd);
400 #if defined(ENABLE_SSA)
401 /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
403 codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
406 /* end of header generation */
408 replacementpoint = jd->code->rplpoints;
410 /* walk through all basic blocks */
411 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
413 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
415 if (bptr->flags >= BBREACHED) {
417 /* branch resolving */
420 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
421 gen_resolvebranch(cd->mcodebase + brefs->branchpos,
427 /* handle replacement points */
429 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
430 replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
434 assert(cd->lastmcodeptr <= cd->mcodeptr);
435 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
439 /* copy interface registers to their destination */
445 /* generate basic block profiling code */
447 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
448 /* count frequency */
450 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
451 M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
455 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
456 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
459 # if defined(ENABLE_SSA)
461 last_cmd_was_goto = false;
465 src = bptr->invars[len];
466 if (bptr->type != BBTYPE_STD) {
467 if (!IS_2_WORD_TYPE(src->type)) {
468 if (bptr->type == BBTYPE_SBR) {
469 if (!IS_INMEMORY(src->flags))
474 emit_store(jd, NULL, src, d);
475 } else if (bptr->type == BBTYPE_EXH) {
476 if (!IS_INMEMORY(src->flags))
480 M_INTMOVE(REG_ITMP1, d);
481 emit_store(jd, NULL, src, d);
485 log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
492 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
496 src = bptr->invars[len];
497 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
498 if (!IS_2_WORD_TYPE(src->type)) {
499 if (bptr->type == BBTYPE_SBR) {
500 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
502 emit_store(jd, NULL, src, d);
504 } else if (bptr->type == BBTYPE_EXH) {
505 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
506 M_INTMOVE(REG_ITMP1, d);
507 emit_store(jd, NULL, src, d);
510 log_text("copy interface registers: longs have to be in \
517 assert(src->varkind == STACKVAR);
518 /* will be done directly in simplereg lateron */
519 /* for now codegen_reg_of_var has to be called here to */
520 /* set the regoff and flags for all bptr->invars[] */
521 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
523 if (IS_LNG_TYPE(src->type))
524 d = codegen_reg_of_var(rd, 0, src,
525 PACK_REGS(REG_ITMP1, REG_ITMP2));
527 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
528 /* d = codegen_reg_of_var(rd, 0, src, REG_IFTMP); */
530 if ((src->varkind != STACKVAR)) {
532 s1 = rd->interfaces[len][s2].regoff;
534 if (IS_FLT_DBL_TYPE(s2)) {
535 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
539 if (IS_2_WORD_TYPE(s2))
540 M_DLD(d, REG_SP, s1 * 4);
542 M_FLD(d, REG_SP, s1 * 4);
546 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
547 if (IS_2_WORD_TYPE(s2))
553 if (IS_2_WORD_TYPE(s2))
554 M_LLD(d, REG_SP, s1 * 4);
556 M_ILD(d, REG_SP, s1 * 4);
560 emit_store(jd, NULL, src, d);
567 /* walk through all instructions */
572 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
573 if (iptr->line != currentline) {
574 dseg_addlinenumber(cd, iptr->line);
575 currentline = iptr->line;
578 MCODECHECK(1024); /* 1kB should be enough */
581 case ICMD_INLINE_START:
584 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
585 #if defined(ENABLE_THREADS)
586 if (insinfo->synchronize) {
587 /* add monitor enter code */
588 if (insinfo->method->flags & ACC_STATIC) {
589 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
590 M_AST(REG_ITMP1, REG_SP, 0 * 4);
593 /* nullpointer check must have been performed before */
594 /* (XXX not done, yet) */
595 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
596 if (IS_INMEMORY(var->flags)) {
597 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
598 M_AST(REG_ITMP1, REG_SP, 0 * 4);
601 M_AST(var->regoff, REG_SP, 0 * 4);
605 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
609 dseg_addlinenumber_inline_start(cd, iptr);
614 case ICMD_INLINE_END:
617 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
619 dseg_addlinenumber_inline_end(cd, iptr);
620 dseg_addlinenumber(cd, iptr->line);
622 #if defined(ENABLE_THREADS)
623 if (insinfo->synchronize) {
624 /* add monitor exit code */
625 if (insinfo->method->flags & ACC_STATIC) {
626 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
627 M_AST(REG_ITMP1, REG_SP, 0 * 4);
630 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
631 if (IS_INMEMORY(var->flags)) {
632 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
633 M_AST(REG_ITMP1, REG_SP, 0 * 4);
636 M_AST(var->regoff, REG_SP, 0 * 4);
640 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
648 case ICMD_NOP: /* ... ==> ... */
651 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
656 codegen_add_nullpointerexception_ref(cd);
659 /* constant operations ************************************************/
661 case ICMD_ICONST: /* ... ==> ..., constant */
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
664 ICONST(d, iptr->sx.val.i);
665 emit_store_dst(jd, iptr, d);
668 case ICMD_LCONST: /* ... ==> ..., constant */
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
671 LCONST(d, iptr->sx.val.l);
672 emit_store_dst(jd, iptr, d);
675 case ICMD_FCONST: /* ... ==> ..., constant */
677 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
678 if (iptr->sx.val.f == 0.0) {
682 if (iptr->sx.val.i == 0x80000000) {
686 } else if (iptr->sx.val.f == 1.0) {
689 } else if (iptr->sx.val.f == 2.0) {
695 disp = dseg_addfloat(cd, iptr->sx.val.f);
696 emit_mov_imm_reg(cd, 0, REG_ITMP1);
698 emit_flds_membase(cd, REG_ITMP1, disp);
700 emit_store_dst(jd, iptr, d);
703 case ICMD_DCONST: /* ... ==> ..., constant */
705 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
706 if (iptr->sx.val.d == 0.0) {
710 if (iptr->sx.val.l == 0x8000000000000000LL) {
714 } else if (iptr->sx.val.d == 1.0) {
717 } else if (iptr->sx.val.d == 2.0) {
723 disp = dseg_adddouble(cd, iptr->sx.val.d);
724 emit_mov_imm_reg(cd, 0, REG_ITMP1);
726 emit_fldl_membase(cd, REG_ITMP1, disp);
728 emit_store_dst(jd, iptr, d);
731 case ICMD_ACONST: /* ... ==> ..., constant */
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
735 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
736 codegen_addpatchref(cd, PATCHER_aconst,
737 iptr->sx.val.c.ref, 0);
739 if (opt_showdisassemble) {
740 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
746 if (iptr->sx.val.anyptr == NULL)
749 M_MOV_IMM(iptr->sx.val.anyptr, d);
751 emit_store_dst(jd, iptr, d);
755 /* load/store operations **********************************************/
757 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
758 case ICMD_ALOAD: /* op1 = local variable */
760 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
761 if ((iptr->dst.var->varkind == LOCALVAR) &&
762 (iptr->dst.var->varnum == iptr->s1.localindex))
764 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
765 if (IS_INMEMORY(var->flags))
766 M_ILD(d, REG_SP, var->regoff * 4);
768 M_INTMOVE(var->regoff, d);
769 emit_store_dst(jd, iptr, d);
772 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
773 /* s1.localindex = local variable */
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
776 if ((iptr->dst.var->varkind == LOCALVAR) &&
777 (iptr->dst.var->varnum == iptr->s1.localindex))
779 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
780 if (IS_INMEMORY(var->flags))
781 M_LLD(d, REG_SP, var->regoff * 4);
783 M_LNGMOVE(var->regoff, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
788 /* s1.localindex = local variable */
790 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
791 if ((iptr->dst.var->varkind == LOCALVAR) &&
792 (iptr->dst.var->varnum == iptr->s1.localindex))
794 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
795 if (IS_INMEMORY(var->flags))
796 M_FLD(d, REG_SP, var->regoff * 4);
798 M_FLTMOVE(var->regoff, d);
799 emit_store_dst(jd, iptr, d);
802 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
803 /* s1.localindex = local variable */
805 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
806 if ((iptr->dst.var->varkind == LOCALVAR) &&
807 (iptr->dst.var->varnum == iptr->s1.localindex))
809 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
810 if (IS_INMEMORY(var->flags))
811 M_DLD(d, REG_SP, var->regoff * 4);
813 M_FLTMOVE(var->regoff, d);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_ISTORE: /* ..., value ==> ... */
818 case ICMD_ASTORE: /* op1 = local variable */
820 if ((iptr->s1.var->varkind == LOCALVAR) &&
821 (iptr->s1.var->varnum == iptr->dst.localindex))
823 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
824 if (IS_INMEMORY(var->flags)) {
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 M_IST(s1, REG_SP, var->regoff * 4);
829 s1 = emit_load_s1(jd, iptr, var->regoff);
830 M_INTMOVE(s1, var->regoff);
834 case ICMD_LSTORE: /* ..., value ==> ... */
835 /* dst.localindex = local variable */
837 if ((iptr->s1.var->varkind == LOCALVAR) &&
838 (iptr->s1.var->varnum == iptr->dst.localindex))
840 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
841 if (IS_INMEMORY(var->flags)) {
842 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
843 M_LST(s1, REG_SP, var->regoff * 4);
846 s1 = emit_load_s1(jd, iptr, var->regoff);
847 M_LNGMOVE(s1, var->regoff);
851 case ICMD_FSTORE: /* ..., value ==> ... */
852 /* dst.localindex = local variable */
854 if ((iptr->s1.var->varkind == LOCALVAR) &&
855 (iptr->s1.var->varnum == iptr->dst.localindex))
857 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
858 if (IS_INMEMORY(var->flags)) {
859 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
860 M_FST(s1, REG_SP, var->regoff * 4);
863 s1 = emit_load_s1(jd, iptr, var->regoff);
864 M_FLTMOVE(s1, var->regoff);
868 case ICMD_DSTORE: /* ..., value ==> ... */
869 /* dst.localindex = local variable */
871 if ((iptr->s1.var->varkind == LOCALVAR) &&
872 (iptr->s1.var->varnum == iptr->dst.localindex))
874 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
875 if (IS_INMEMORY(var->flags)) {
876 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
877 M_DST(s1, REG_SP, var->regoff * 4);
880 s1 = emit_load_s1(jd, iptr, var->regoff);
881 M_FLTMOVE(s1, var->regoff);
886 /* pop/dup/swap operations ********************************************/
888 /* attention: double and longs are only one entry in CACAO ICMDs */
890 case ICMD_POP: /* ..., value ==> ... */
891 case ICMD_POP2: /* ..., value, value ==> ... */
894 case ICMD_DUP: /* ..., a ==> ..., a, a */
896 M_COPY(iptr->s1.var, iptr->dst.var);
899 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
901 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
902 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
903 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
906 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
908 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
909 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
910 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
911 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
914 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
916 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
917 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
920 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
922 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
923 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
924 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
925 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
926 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
929 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
931 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
932 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
933 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
934 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
935 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
936 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
939 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
941 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
942 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
947 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
949 M_COPY(src, iptr->dst);
950 M_COPY(src->prev, iptr->dst->prev);
951 #if defined(ENABLE_SSA)
952 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
953 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
955 M_COPY(iptr->dst, iptr->dst->prev->prev);
956 #if defined(ENABLE_SSA)
958 M_COPY(src, iptr->dst->prev->prev);
963 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
965 M_COPY(src, iptr->dst);
966 M_COPY(src->prev, iptr->dst->prev);
967 M_COPY(src->prev->prev, iptr->dst->prev->prev);
968 #if defined(ENABLE_SSA)
969 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
970 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
972 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
973 #if defined(ENABLE_SSA)
975 M_COPY(src, iptr->dst->prev->prev->prev);
981 /* integer operations *************************************************/
983 case ICMD_INEG: /* ..., value ==> ..., - value */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
989 emit_store_dst(jd, iptr, d);
992 case ICMD_LNEG: /* ..., value ==> ..., - value */
994 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
997 M_NEG(GET_LOW_REG(d));
998 M_IADDC_IMM(0, GET_HIGH_REG(d));
999 M_NEG(GET_HIGH_REG(d));
1000 emit_store_dst(jd, iptr, d);
1003 case ICMD_I2L: /* ..., value ==> ..., value */
1005 s1 = emit_load_s1(jd, iptr, EAX);
1006 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1009 M_LNGMOVE(EAX_EDX_PACKED, d);
1010 emit_store_dst(jd, iptr, d);
1013 case ICMD_L2I: /* ..., value ==> ..., value */
1015 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
1023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1024 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1028 emit_store_dst(jd, iptr, d);
1031 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1036 emit_store_dst(jd, iptr, d);
1039 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
1041 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1042 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1044 emit_store_dst(jd, iptr, d);
1048 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1052 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
1063 /* sx.val.i = constant */
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1068 M_IADD_IMM(iptr->sx.val.i, d);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1074 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1075 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1077 M_INTMOVE(s1, GET_LOW_REG(d));
1078 M_IADD(s2, GET_LOW_REG(d));
1079 /* don't use REG_ITMP1 */
1080 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1081 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1082 M_INTMOVE(s1, GET_HIGH_REG(d));
1083 M_IADDC(s2, GET_HIGH_REG(d));
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1088 /* sx.val.l = constant */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1093 M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1094 M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1104 M_INTMOVE(s1, REG_ITMP1);
1105 M_ISUB(s2, REG_ITMP1);
1106 M_INTMOVE(REG_ITMP1, d);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1116 /* sx.val.i = constant */
1118 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1119 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1121 M_ISUB_IMM(iptr->sx.val.i, d);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1127 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1128 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1129 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1130 if (s2 == GET_LOW_REG(d)) {
1131 M_INTMOVE(s1, REG_ITMP1);
1132 M_ISUB(s2, REG_ITMP1);
1133 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
1136 M_INTMOVE(s1, GET_LOW_REG(d));
1137 M_ISUB(s2, GET_LOW_REG(d));
1139 /* don't use REG_ITMP1 */
1140 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1141 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1142 if (s2 == GET_HIGH_REG(d)) {
1143 M_INTMOVE(s1, REG_ITMP2);
1144 M_ISUBB(s2, REG_ITMP2);
1145 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
1148 M_INTMOVE(s1, GET_HIGH_REG(d));
1149 M_ISUBB(s2, GET_HIGH_REG(d));
1151 emit_store_dst(jd, iptr, d);
1154 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1155 /* sx.val.l = constant */
1157 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1158 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1160 M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1161 M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1162 emit_store_dst(jd, iptr, d);
1165 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1167 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1168 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1169 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1176 emit_store_dst(jd, iptr, d);
1179 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1180 /* sx.val.i = constant */
1182 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1183 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1184 M_IMUL_IMM(s1, iptr->sx.val.i, d);
1185 emit_store_dst(jd, iptr, d);
1188 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1190 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1191 s2 = emit_load_s2_low(jd, iptr, EDX);
1192 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1194 M_INTMOVE(s1, REG_ITMP2);
1195 M_IMUL(s2, REG_ITMP2);
1197 s1 = emit_load_s1_low(jd, iptr, EAX);
1198 s2 = emit_load_s2_high(jd, iptr, EDX);
1201 M_IADD(EDX, REG_ITMP2);
1203 s1 = emit_load_s1_low(jd, iptr, EAX);
1204 s2 = emit_load_s2_low(jd, iptr, EDX);
1207 M_INTMOVE(EAX, GET_LOW_REG(d));
1208 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
1210 emit_store_dst(jd, iptr, d);
1213 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1214 /* sx.val.l = constant */
1216 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1217 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1218 ICONST(EAX, iptr->sx.val.l);
1220 M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
1221 M_IADD(REG_ITMP2, EDX);
1222 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1223 M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
1224 M_IADD(REG_ITMP2, EDX);
1225 M_LNGMOVE(EAX_EDX_PACKED, d);
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1231 s1 = emit_load_s1(jd, iptr, EAX);
1232 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1233 d = codegen_reg_of_dst(jd, iptr, EAX);
1238 codegen_add_arithmeticexception_ref(cd);
1241 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1243 /* check as described in jvm spec */
1245 M_CMP_IMM(0x80000000, EAX);
1252 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1258 s1 = emit_load_s1(jd, iptr, EAX);
1259 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1260 d = codegen_reg_of_dst(jd, iptr, EDX);
1265 codegen_add_arithmeticexception_ref(cd);
1268 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1270 /* check as described in jvm spec */
1272 M_CMP_IMM(0x80000000, EAX);
1280 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1285 /* sx.val.i = constant */
1287 /* TODO: optimize for `/ 2' */
1288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1289 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1293 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d); /* 32-bit for jump off. */
1294 M_SRA_IMM(iptr->sx.val.i, d);
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1299 /* sx.val.i = constant */
1301 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1304 M_MOV(s1, REG_ITMP1);
1308 M_AND_IMM(iptr->sx.val.i, d);
1310 M_BGE(2 + 2 + 6 + 2);
1311 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
1313 M_AND_IMM32(iptr->sx.val.i, d); /* use 32-bit for jump offset */
1315 emit_store_dst(jd, iptr, d);
1318 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1319 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1321 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1322 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1324 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1325 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1327 codegen_add_arithmeticexception_ref(cd);
1329 bte = iptr->sx.s23.s3.bte;
1332 M_LST(s2, REG_SP, 2 * 4);
1334 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1335 M_LST(s1, REG_SP, 0 * 4);
1337 M_MOV_IMM(bte->fp, REG_ITMP3);
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1343 /* sx.val.i = constant */
1345 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1346 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1348 M_TEST(GET_HIGH_REG(d));
1350 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
1351 M_IADDC_IMM(0, GET_HIGH_REG(d));
1352 M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1353 M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
1354 emit_store_dst(jd, iptr, d);
1358 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1359 /* sx.val.l = constant */
1361 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1362 if (IS_INMEMORY(iptr->dst.var->flags)) {
1363 if (IS_INMEMORY(iptr->s1.var->flags)) {
1364 /* Alpha algorithm */
1366 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
1368 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4 + 4);
1374 /* TODO: hmm, don't know if this is always correct */
1376 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
1378 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
1384 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
1385 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
1387 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1388 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1389 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->regoff * 4 + 4);
1390 emit_jcc(cd, CC_GE, disp);
1392 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
1393 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
1395 emit_neg_reg(cd, REG_ITMP1);
1396 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1397 emit_neg_reg(cd, REG_ITMP2);
1399 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1400 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1402 emit_neg_reg(cd, REG_ITMP1);
1403 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1404 emit_neg_reg(cd, REG_ITMP2);
1406 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->regoff * 4);
1407 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->regoff * 4 + 4);
1411 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1412 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1414 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1415 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1416 M_TEST(GET_LOW_REG(s1));
1422 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1425 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1427 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1434 /* sx.val.i = constant */
1436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1437 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1439 M_SLL_IMM(iptr->sx.val.i, d);
1440 emit_store_dst(jd, iptr, d);
1443 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1446 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1448 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1451 emit_store_dst(jd, iptr, d);
1454 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1455 /* sx.val.i = constant */
1457 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1460 M_SRA_IMM(iptr->sx.val.i, d);
1461 emit_store_dst(jd, iptr, d);
1464 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1467 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1469 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1472 emit_store_dst(jd, iptr, d);
1475 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1476 /* sx.val.i = constant */
1478 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1481 M_SRL_IMM(iptr->sx.val.i, d);
1482 emit_store_dst(jd, iptr, d);
1485 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1487 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1488 s2 = emit_load_s2(jd, iptr, ECX);
1489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1492 M_TEST_IMM(32, ECX);
1494 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1495 M_CLR(GET_LOW_REG(d));
1496 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1497 M_SLL(GET_LOW_REG(d));
1498 emit_store_dst(jd, iptr, d);
1501 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1502 /* sx.val.i = constant */
1504 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1505 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1507 if (iptr->sx.val.i & 0x20) {
1508 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1509 M_CLR(GET_LOW_REG(d));
1510 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1513 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
1514 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1522 s2 = emit_load_s2(jd, iptr, ECX);
1523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1526 M_TEST_IMM(32, ECX);
1528 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1529 M_SRA_IMM(31, GET_HIGH_REG(d));
1530 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1531 M_SRA(GET_HIGH_REG(d));
1532 emit_store_dst(jd, iptr, d);
1535 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1536 /* sx.val.i = constant */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1541 if (iptr->sx.val.i & 0x20) {
1542 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1543 M_SRA_IMM(31, GET_HIGH_REG(d));
1544 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1548 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1550 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1552 emit_store_dst(jd, iptr, d);
1555 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1557 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1558 s2 = emit_load_s2(jd, iptr, ECX);
1559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1562 M_TEST_IMM(32, ECX);
1564 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1565 M_CLR(GET_HIGH_REG(d));
1566 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1567 M_SRL(GET_HIGH_REG(d));
1568 emit_store_dst(jd, iptr, d);
1571 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1572 /* sx.val.l = constant */
1574 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1575 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1577 if (iptr->sx.val.i & 0x20) {
1578 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1579 M_CLR(GET_HIGH_REG(d));
1580 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1584 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1586 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1588 emit_store_dst(jd, iptr, d);
1591 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1594 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1602 emit_store_dst(jd, iptr, d);
1605 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1606 /* sx.val.i = constant */
1608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1611 M_AND_IMM(iptr->sx.val.i, d);
1612 emit_store_dst(jd, iptr, d);
1615 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1617 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1618 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1620 if (s2 == GET_LOW_REG(d))
1621 M_AND(s1, GET_LOW_REG(d));
1623 M_INTMOVE(s1, GET_LOW_REG(d));
1624 M_AND(s2, GET_LOW_REG(d));
1626 /* REG_ITMP1 probably contains low 32-bit of destination */
1627 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1628 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1629 if (s2 == GET_HIGH_REG(d))
1630 M_AND(s1, GET_HIGH_REG(d));
1632 M_INTMOVE(s1, GET_HIGH_REG(d));
1633 M_AND(s2, GET_HIGH_REG(d));
1635 emit_store_dst(jd, iptr, d);
1638 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1639 /* sx.val.l = constant */
1641 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1644 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1645 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1646 emit_store_dst(jd, iptr, d);
1649 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1660 emit_store_dst(jd, iptr, d);
1663 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1664 /* sx.val.i = constant */
1666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1669 M_OR_IMM(iptr->sx.val.i, d);
1670 emit_store_dst(jd, iptr, d);
1673 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1675 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1676 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1678 if (s2 == GET_LOW_REG(d))
1679 M_OR(s1, GET_LOW_REG(d));
1681 M_INTMOVE(s1, GET_LOW_REG(d));
1682 M_OR(s2, GET_LOW_REG(d));
1684 /* REG_ITMP1 probably contains low 32-bit of destination */
1685 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1686 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1687 if (s2 == GET_HIGH_REG(d))
1688 M_OR(s1, GET_HIGH_REG(d));
1690 M_INTMOVE(s1, GET_HIGH_REG(d));
1691 M_OR(s2, GET_HIGH_REG(d));
1693 emit_store_dst(jd, iptr, d);
1696 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1697 /* sx.val.l = constant */
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1702 M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1703 M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1704 emit_store_dst(jd, iptr, d);
1707 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1718 emit_store_dst(jd, iptr, d);
1721 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1722 /* sx.val.i = constant */
1724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1727 M_XOR_IMM(iptr->sx.val.i, d);
1728 emit_store_dst(jd, iptr, d);
1731 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1733 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1734 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1736 if (s2 == GET_LOW_REG(d))
1737 M_XOR(s1, GET_LOW_REG(d));
1739 M_INTMOVE(s1, GET_LOW_REG(d));
1740 M_XOR(s2, GET_LOW_REG(d));
1742 /* REG_ITMP1 probably contains low 32-bit of destination */
1743 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1744 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1745 if (s2 == GET_HIGH_REG(d))
1746 M_XOR(s1, GET_HIGH_REG(d));
1748 M_INTMOVE(s1, GET_HIGH_REG(d));
1749 M_XOR(s2, GET_HIGH_REG(d));
1751 emit_store_dst(jd, iptr, d);
1754 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1755 /* sx.val.l = constant */
1757 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1760 M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1761 M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1762 emit_store_dst(jd, iptr, d);
1765 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1766 /* s1.localindex = variable, sx.val.i = constant */
1768 #if defined(ENABLE_SSA)
1773 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1774 var_t = &(rd->locals[iptr->val._i.op1_t][TYPE_INT]);
1776 /* set s1 to reg of destination or REG_ITMP1 */
1777 if (IS_INMEMORY(var_t->flags))
1782 /* move source value to s1 */
1783 if (IS_INMEMORY(var->flags))
1784 M_ILD( s1, REG_SP, var->regoff * 4);
1786 M_INTMOVE(var->regoff, s1);
1788 /* `inc reg' is slower on p4's (regarding to ia32
1789 optimization reference manual and benchmarks) and as
1790 fast on athlon's. */
1792 M_IADD_IMM(iptr->val._i.i, s1);
1794 if (IS_INMEMORY(var_t->flags))
1795 M_IST(s1, REG_SP, var_t->regoff * 4);
1798 #endif /* defined(ENABLE_SSA) */
1800 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1801 if (IS_INMEMORY(var->flags)) {
1803 M_ILD(s1, REG_SP, var->regoff * 4);
1808 /* `inc reg' is slower on p4's (regarding to ia32
1809 optimization reference manual and benchmarks) and as
1810 fast on athlon's. */
1812 M_IADD_IMM(iptr->sx.val.i, s1);
1814 if (IS_INMEMORY(var->flags))
1815 M_IST(s1, REG_SP, var->regoff * 4);
1820 /* floating operations ************************************************/
1822 case ICMD_FNEG: /* ..., value ==> ..., - value */
1824 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1825 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1827 emit_store_dst(jd, iptr, d);
1830 case ICMD_DNEG: /* ..., value ==> ..., - value */
1832 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1833 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1835 emit_store_dst(jd, iptr, d);
1838 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1840 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1841 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1842 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1844 emit_store_dst(jd, iptr, d);
1847 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1849 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1850 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1851 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1853 emit_store_dst(jd, iptr, d);
1856 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1858 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1859 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1860 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1862 emit_store_dst(jd, iptr, d);
1865 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1867 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1868 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1869 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1871 emit_store_dst(jd, iptr, d);
1874 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1876 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1877 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1878 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1880 emit_store_dst(jd, iptr, d);
1883 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1885 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1886 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1887 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1889 emit_store_dst(jd, iptr, d);
1892 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1894 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1895 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1896 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1898 emit_store_dst(jd, iptr, d);
1901 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1903 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1904 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1905 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1907 emit_store_dst(jd, iptr, d);
1910 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1912 /* exchanged to skip fxch */
1913 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1914 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1915 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1916 /* emit_fxch(cd); */
1921 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1922 emit_store_dst(jd, iptr, d);
1923 emit_ffree_reg(cd, 0);
1927 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1929 /* exchanged to skip fxch */
1930 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1931 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1932 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1933 /* emit_fxch(cd); */
1938 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1939 emit_store_dst(jd, iptr, d);
1940 emit_ffree_reg(cd, 0);
1944 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1945 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1947 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1948 if (IS_INMEMORY(iptr->s1.var->flags)) {
1949 emit_fildl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
1952 disp = dseg_adds4(cd, 0);
1953 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1955 emit_mov_reg_membase(cd, iptr->s1.var->regoff, REG_ITMP1, disp);
1956 emit_fildl_membase(cd, REG_ITMP1, disp);
1958 emit_store_dst(jd, iptr, d);
1961 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1962 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1964 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1965 if (IS_INMEMORY(iptr->s1.var->flags)) {
1966 emit_fildll_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
1969 log_text("L2F: longs have to be in memory");
1972 emit_store_dst(jd, iptr, d);
1975 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1977 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1978 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1980 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1983 /* Round to zero, 53-bit mode, exception masked */
1984 disp = dseg_adds4(cd, 0x0e7f);
1985 emit_fldcw_membase(cd, REG_ITMP1, disp);
1987 if (IS_INMEMORY(iptr->dst.var->flags)) {
1988 emit_fistpl_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
1990 /* Round to nearest, 53-bit mode, exceptions masked */
1991 disp = dseg_adds4(cd, 0x027f);
1992 emit_fldcw_membase(cd, REG_ITMP1, disp);
1994 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4);
1997 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
1999 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2002 disp = dseg_adds4(cd, 0);
2003 emit_fistpl_membase(cd, REG_ITMP1, disp);
2004 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst.var->regoff);
2006 /* Round to nearest, 53-bit mode, exceptions masked */
2007 disp = dseg_adds4(cd, 0x027f);
2008 emit_fldcw_membase(cd, REG_ITMP1, disp);
2010 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst.var->regoff);
2013 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2014 disp += 5 + 2 + ((REG_RESULT == iptr->dst.var->regoff) ? 0 : 2);
2017 emit_jcc(cd, CC_NE, disp);
2019 /* XXX: change this when we use registers */
2020 emit_flds_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
2021 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
2022 emit_call_reg(cd, REG_ITMP1);
2024 if (IS_INMEMORY(iptr->dst.var->flags)) {
2025 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
2028 M_INTMOVE(REG_RESULT, iptr->dst.var->regoff);
2032 case ICMD_D2I: /* ..., value ==> ..., (int) value */
2034 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2035 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
2037 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2040 /* Round to zero, 53-bit mode, exception masked */
2041 disp = dseg_adds4(cd, 0x0e7f);
2042 emit_fldcw_membase(cd, REG_ITMP1, disp);
2044 if (IS_INMEMORY(iptr->dst.var->flags)) {
2045 emit_fistpl_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
2047 /* Round to nearest, 53-bit mode, exceptions masked */
2048 disp = dseg_adds4(cd, 0x027f);
2049 emit_fldcw_membase(cd, REG_ITMP1, disp);
2051 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4);
2054 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2056 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2059 disp = dseg_adds4(cd, 0);
2060 emit_fistpl_membase(cd, REG_ITMP1, disp);
2061 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst.var->regoff);
2063 /* Round to nearest, 53-bit mode, exceptions masked */
2064 disp = dseg_adds4(cd, 0x027f);
2065 emit_fldcw_membase(cd, REG_ITMP1, disp);
2067 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst.var->regoff);
2070 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2071 disp += 5 + 2 + ((REG_RESULT == iptr->dst.var->regoff) ? 0 : 2);
2074 emit_jcc(cd, CC_NE, disp);
2076 /* XXX: change this when we use registers */
2077 emit_fldl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
2078 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
2079 emit_call_reg(cd, REG_ITMP1);
2081 if (IS_INMEMORY(iptr->dst.var->flags)) {
2082 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
2084 M_INTMOVE(REG_RESULT, iptr->dst.var->regoff);
2088 case ICMD_F2L: /* ..., value ==> ..., (long) value */
2090 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2091 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
2093 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2096 /* Round to zero, 53-bit mode, exception masked */
2097 disp = dseg_adds4(cd, 0x0e7f);
2098 emit_fldcw_membase(cd, REG_ITMP1, disp);
2100 if (IS_INMEMORY(iptr->dst.var->flags)) {
2101 emit_fistpll_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
2103 /* Round to nearest, 53-bit mode, exceptions masked */
2104 disp = dseg_adds4(cd, 0x027f);
2105 emit_fldcw_membase(cd, REG_ITMP1, disp);
2107 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4 + 4);
2110 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2112 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2115 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2117 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4 + 4);
2119 emit_jcc(cd, CC_NE, disp);
2121 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst.var->regoff * 4);
2124 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2126 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2128 emit_jcc(cd, CC_NE, disp);
2130 /* XXX: change this when we use registers */
2131 emit_flds_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
2132 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
2133 emit_call_reg(cd, REG_ITMP1);
2134 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
2135 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst.var->regoff * 4 + 4);
2138 log_text("F2L: longs have to be in memory");
2143 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2146 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
2148 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2151 /* Round to zero, 53-bit mode, exception masked */
2152 disp = dseg_adds4(cd, 0x0e7f);
2153 emit_fldcw_membase(cd, REG_ITMP1, disp);
2155 if (IS_INMEMORY(iptr->dst.var->flags)) {
2156 emit_fistpll_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
2158 /* Round to nearest, 53-bit mode, exceptions masked */
2159 disp = dseg_adds4(cd, 0x027f);
2160 emit_fldcw_membase(cd, REG_ITMP1, disp);
2162 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4 + 4);
2165 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2167 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2170 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2172 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4 + 4);
2174 emit_jcc(cd, CC_NE, disp);
2176 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst.var->regoff * 4);
2179 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
2181 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
2183 emit_jcc(cd, CC_NE, disp);
2185 /* XXX: change this when we use registers */
2186 emit_fldl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
2187 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
2188 emit_call_reg(cd, REG_ITMP1);
2189 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
2190 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst.var->regoff * 4 + 4);
2193 log_text("D2L: longs have to be in memory");
2198 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2200 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2201 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2203 emit_store_dst(jd, iptr, d);
2206 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2208 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2211 emit_store_dst(jd, iptr, d);
2214 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2217 /* exchanged to skip fxch */
2218 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
2219 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
2220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2221 /* emit_fxch(cd); */
2224 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
2225 emit_jcc(cd, CC_E, 6);
2226 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
2228 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2229 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2230 emit_jcc(cd, CC_B, 3 + 5);
2231 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2232 emit_jmp_imm(cd, 3);
2233 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2234 emit_store_dst(jd, iptr, d);
2237 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2240 /* exchanged to skip fxch */
2241 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
2242 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
2243 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2244 /* emit_fxch(cd); */
2247 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
2248 emit_jcc(cd, CC_E, 3);
2249 emit_movb_imm_reg(cd, 1, REG_AH);
2251 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2252 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2253 emit_jcc(cd, CC_B, 3 + 5);
2254 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2255 emit_jmp_imm(cd, 3);
2256 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2257 emit_store_dst(jd, iptr, d);
2261 /* memory operations **************************************************/
2263 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2267 gen_nullptr_check(s1);
2268 M_ILD(d, s1, OFFSET(java_arrayheader, size));
2269 emit_store_dst(jd, iptr, d);
2272 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2274 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2275 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2276 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2277 if (INSTRUCTION_MUST_CHECK(iptr)) {
2278 gen_nullptr_check(s1);
2281 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
2282 emit_store_dst(jd, iptr, d);
2285 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2288 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2289 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2290 if (INSTRUCTION_MUST_CHECK(iptr)) {
2291 gen_nullptr_check(s1);
2294 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
2295 emit_store_dst(jd, iptr, d);
2298 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2303 if (INSTRUCTION_MUST_CHECK(iptr)) {
2304 gen_nullptr_check(s1);
2307 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
2308 emit_store_dst(jd, iptr, d);
2311 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2314 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2315 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2316 if (INSTRUCTION_MUST_CHECK(iptr)) {
2317 gen_nullptr_check(s1);
2320 emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
2321 emit_store_dst(jd, iptr, d);
2324 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2326 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2327 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2328 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2329 if (INSTRUCTION_MUST_CHECK(iptr)) {
2330 gen_nullptr_check(s1);
2333 assert(IS_INMEMORY(iptr->dst.var->flags));
2334 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
2335 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst.var->regoff * 4);
2336 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
2337 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst.var->regoff * 4 + 4);
2340 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2343 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2344 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2345 if (INSTRUCTION_MUST_CHECK(iptr)) {
2346 gen_nullptr_check(s1);
2349 emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2350 emit_store_dst(jd, iptr, d);
2353 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2356 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2357 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2358 if (INSTRUCTION_MUST_CHECK(iptr)) {
2359 gen_nullptr_check(s1);
2362 emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2363 emit_store_dst(jd, iptr, d);
2366 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2369 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2371 if (INSTRUCTION_MUST_CHECK(iptr)) {
2372 gen_nullptr_check(s1);
2375 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
2376 emit_store_dst(jd, iptr, d);
2380 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2383 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2384 if (INSTRUCTION_MUST_CHECK(iptr)) {
2385 gen_nullptr_check(s1);
2388 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2389 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
2390 M_INTMOVE(s3, REG_ITMP3);
2393 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2396 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2399 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2400 if (INSTRUCTION_MUST_CHECK(iptr)) {
2401 gen_nullptr_check(s1);
2404 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2405 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
2408 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2411 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2412 if (INSTRUCTION_MUST_CHECK(iptr)) {
2413 gen_nullptr_check(s1);
2416 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2417 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2420 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2422 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2423 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2424 if (INSTRUCTION_MUST_CHECK(iptr)) {
2425 gen_nullptr_check(s1);
2428 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2429 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
2432 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2434 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2435 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2436 if (INSTRUCTION_MUST_CHECK(iptr)) {
2437 gen_nullptr_check(s1);
2440 assert(IS_INMEMORY(iptr->sx.s23.s3.var->flags));
2441 emit_mov_membase_reg(cd, REG_SP, iptr->sx.s23.s3.var->regoff * 4, REG_ITMP3);
2442 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2443 emit_mov_membase_reg(cd, REG_SP, iptr->sx.s23.s3.var->regoff * 4 + 4, REG_ITMP3);
2444 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2447 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2451 if (INSTRUCTION_MUST_CHECK(iptr)) {
2452 gen_nullptr_check(s1);
2455 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2456 emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2459 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2462 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2463 if (INSTRUCTION_MUST_CHECK(iptr)) {
2464 gen_nullptr_check(s1);
2467 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2468 emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2471 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2473 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2475 if (INSTRUCTION_MUST_CHECK(iptr)) {
2476 gen_nullptr_check(s1);
2479 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2481 M_AST(s1, REG_SP, 0 * 4);
2482 M_AST(s3, REG_SP, 1 * 4);
2483 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2487 codegen_add_arraystoreexception_ref(cd);
2489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2490 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2491 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2492 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2495 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2498 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2499 if (INSTRUCTION_MUST_CHECK(iptr)) {
2500 gen_nullptr_check(s1);
2503 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2506 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2509 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2510 if (INSTRUCTION_MUST_CHECK(iptr)) {
2511 gen_nullptr_check(s1);
2514 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
2517 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2520 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2521 if (INSTRUCTION_MUST_CHECK(iptr)) {
2522 gen_nullptr_check(s1);
2525 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2528 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2531 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2532 if (INSTRUCTION_MUST_CHECK(iptr)) {
2533 gen_nullptr_check(s1);
2536 emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
2539 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2543 if (INSTRUCTION_MUST_CHECK(iptr)) {
2544 gen_nullptr_check(s1);
2547 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2548 emit_mov_imm_memindex(cd, ((s4)iptr->sx.s23.s3.constval) >> 31, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2551 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2554 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2555 if (INSTRUCTION_MUST_CHECK(iptr)) {
2556 gen_nullptr_check(s1);
2559 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
2563 case ICMD_GETSTATIC: /* ... ==> ..., value */
2565 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2566 unresolved_field *uf = iptr->sx.s23.s3.uf;
2568 fieldtype = uf->fieldref->parseddesc.fd->type;
2570 codegen_addpatchref(cd, PATCHER_get_putstatic,
2571 iptr->sx.s23.s3.uf, 0);
2573 if (opt_showdisassemble) {
2574 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2581 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2583 fieldtype = fi->type;
2585 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2586 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2588 if (opt_showdisassemble) {
2589 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2593 disp = (ptrint) &(fi->value);
2596 M_MOV_IMM(disp, REG_ITMP1);
2597 switch (fieldtype) {
2600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2601 M_ILD(d, REG_ITMP1, 0);
2604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2605 M_LLD(d, REG_ITMP1, 0);
2608 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2609 M_FLD(d, REG_ITMP1, 0);
2612 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2613 M_DLD(d, REG_ITMP1, 0);
2616 emit_store_dst(jd, iptr, d);
2619 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2621 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2622 unresolved_field *uf = iptr->sx.s23.s3.uf;
2624 fieldtype = uf->fieldref->parseddesc.fd->type;
2626 codegen_addpatchref(cd, PATCHER_get_putstatic,
2627 iptr->sx.s23.s3.uf, 0);
2629 if (opt_showdisassemble) {
2630 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2637 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2639 fieldtype = fi->type;
2641 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2642 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2644 if (opt_showdisassemble) {
2645 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2649 disp = (ptrint) &(fi->value);
2652 M_MOV_IMM(disp, REG_ITMP1);
2653 switch (fieldtype) {
2656 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2657 M_IST(s1, REG_ITMP1, 0);
2660 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2661 M_LST(s1, REG_ITMP1, 0);
2664 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2665 emit_fstps_membase(cd, REG_ITMP1, 0);
2668 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2669 emit_fstpl_membase(cd, REG_ITMP1, 0);
2674 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2675 /* val = value (in current instruction) */
2676 /* following NOP) */
2678 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2679 unresolved_field *uf = iptr->sx.s23.s3.uf;
2681 fieldtype = uf->fieldref->parseddesc.fd->type;
2683 codegen_addpatchref(cd, PATCHER_get_putstatic,
2686 if (opt_showdisassemble) {
2687 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2694 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2696 fieldtype = fi->type;
2698 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2699 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2701 if (opt_showdisassemble) {
2702 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2706 disp = (ptrint) &(fi->value);
2709 M_MOV_IMM(disp, REG_ITMP1);
2710 switch (fieldtype) {
2713 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2716 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2717 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2724 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2727 gen_nullptr_check(s1);
2729 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2730 unresolved_field *uf = iptr->sx.s23.s3.uf;
2732 fieldtype = uf->fieldref->parseddesc.fd->type;
2734 codegen_addpatchref(cd, PATCHER_getfield,
2735 iptr->sx.s23.s3.uf, 0);
2737 if (opt_showdisassemble) {
2738 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2745 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2747 fieldtype = fi->type;
2751 switch (fieldtype) {
2754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2755 M_ILD32(d, s1, disp);
2758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2759 M_LLD32(d, s1, disp);
2762 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2763 M_FLD32(d, s1, disp);
2766 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2767 M_DLD32(d, s1, disp);
2770 emit_store_dst(jd, iptr, d);
2773 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2776 gen_nullptr_check(s1);
2778 /* must be done here because of code patching */
2780 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2781 unresolved_field *uf = iptr->sx.s23.s3.uf;
2783 fieldtype = uf->fieldref->parseddesc.fd->type;
2786 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2788 fieldtype = fi->type;
2791 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2792 if (IS_2_WORD_TYPE(fieldtype))
2793 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2795 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2798 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2800 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2801 unresolved_field *uf = iptr->sx.s23.s3.uf;
2803 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
2805 if (opt_showdisassemble) {
2806 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2813 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2818 switch (fieldtype) {
2821 M_IST32(s2, s1, disp);
2824 M_LST32(s2, s1, disp);
2827 emit_fstps_membase32(cd, s1, disp);
2830 emit_fstpl_membase32(cd, s1, disp);
2835 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2836 /* val = value (in current instruction) */
2837 /* following NOP) */
2839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2840 gen_nullptr_check(s1);
2842 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2843 unresolved_field *uf = iptr->sx.s23.s3.uf;
2845 fieldtype = uf->fieldref->parseddesc.fd->type;
2847 codegen_addpatchref(cd, PATCHER_putfieldconst,
2850 if (opt_showdisassemble) {
2851 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2859 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2861 fieldtype = fi->type;
2866 switch (fieldtype) {
2869 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2872 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2873 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2881 /* branch operations **************************************************/
2883 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2886 M_INTMOVE(s1, REG_ITMP1_XPTR);
2888 #ifdef ENABLE_VERIFIER
2889 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2890 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2891 iptr->sx.s23.s2.uc, 0);
2893 if (opt_showdisassemble) {
2894 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2897 #endif /* ENABLE_VERIFIER */
2899 M_CALL_IMM(0); /* passing exception pc */
2900 M_POP(REG_ITMP2_XPC);
2902 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2906 case ICMD_INLINE_GOTO:
2908 M_COPY(src, iptr->dst.var);
2912 case ICMD_GOTO: /* ... ==> ... */
2914 #if defined(ENABLE_SSA)
2916 last_cmd_was_goto = true;
2917 /* In case of a Goto phimoves have to be inserted before the */
2919 codegen_insert_phi_moves(cd, rd, ls, bptr);
2923 codegen_addreference(cd, iptr->dst.block);
2927 case ICMD_JSR: /* ... ==> ... */
2930 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2933 case ICMD_RET: /* ... ==> ... */
2934 /* s1.localindex = local variable */
2936 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2937 if (IS_INMEMORY(var->flags)) {
2938 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2945 case ICMD_IFNULL: /* ..., value ==> ... */
2947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2950 codegen_addreference(cd, iptr->dst.block);
2953 case ICMD_IFNONNULL: /* ..., value ==> ... */
2955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2958 codegen_addreference(cd, iptr->dst.block);
2961 case ICMD_IFEQ: /* ..., value ==> ... */
2963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2964 M_CMP_IMM(iptr->sx.val.i, s1);
2966 codegen_addreference(cd, iptr->dst.block);
2969 case ICMD_IFLT: /* ..., value ==> ... */
2971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2972 M_CMP_IMM(iptr->sx.val.i, s1);
2974 codegen_addreference(cd, iptr->dst.block);
2977 case ICMD_IFLE: /* ..., value ==> ... */
2979 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2980 M_CMP_IMM(iptr->sx.val.i, s1);
2982 codegen_addreference(cd, iptr->dst.block);
2985 case ICMD_IFNE: /* ..., value ==> ... */
2987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2988 M_CMP_IMM(iptr->sx.val.i, s1);
2990 codegen_addreference(cd, iptr->dst.block);
2993 case ICMD_IFGT: /* ..., value ==> ... */
2995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2996 M_CMP_IMM(iptr->sx.val.i, s1);
2998 codegen_addreference(cd, iptr->dst.block);
3001 case ICMD_IFGE: /* ..., value ==> ... */
3003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3004 M_CMP_IMM(iptr->sx.val.i, s1);
3006 codegen_addreference(cd, iptr->dst.block);
3009 case ICMD_IF_LEQ: /* ..., value ==> ... */
3011 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3012 if (iptr->sx.val.l == 0) {
3013 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3014 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3017 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3018 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
3019 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
3020 M_OR(REG_ITMP2, REG_ITMP1);
3023 codegen_addreference(cd, iptr->dst.block);
3026 case ICMD_IF_LLT: /* ..., value ==> ... */
3028 if (iptr->sx.val.l == 0) {
3029 /* If high 32-bit are less than zero, then the 64-bits
3031 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3036 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3037 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3039 codegen_addreference(cd, iptr->dst.block);
3041 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3044 codegen_addreference(cd, iptr->dst.block);
3047 case ICMD_IF_LLE: /* ..., value ==> ... */
3049 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3050 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3052 codegen_addreference(cd, iptr->dst.block);
3054 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3056 codegen_addreference(cd, iptr->dst.block);
3059 case ICMD_IF_LNE: /* ..., value ==> ... */
3061 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3062 if (iptr->sx.val.l == 0) {
3063 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3064 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3067 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3068 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
3069 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
3070 M_OR(REG_ITMP2, REG_ITMP1);
3073 codegen_addreference(cd, iptr->dst.block);
3076 case ICMD_IF_LGT: /* ..., value ==> ... */
3078 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3079 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3081 codegen_addreference(cd, iptr->dst.block);
3083 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3085 codegen_addreference(cd, iptr->dst.block);
3088 case ICMD_IF_LGE: /* ..., value ==> ... */
3090 if (iptr->sx.val.l == 0) {
3091 /* If high 32-bit are greater equal zero, then the
3093 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3098 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3099 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3101 codegen_addreference(cd, iptr->dst.block);
3103 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3106 codegen_addreference(cd, iptr->dst.block);
3109 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3110 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3116 codegen_addreference(cd, iptr->dst.block);
3119 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3121 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3122 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3123 M_INTMOVE(s1, REG_ITMP1);
3124 M_XOR(s2, REG_ITMP1);
3125 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3126 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
3127 M_INTMOVE(s1, REG_ITMP2);
3128 M_XOR(s2, REG_ITMP2);
3129 M_OR(REG_ITMP1, REG_ITMP2);
3131 codegen_addreference(cd, iptr->dst.block);
3134 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3135 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3138 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3141 codegen_addreference(cd, iptr->dst.block);
3144 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3146 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3147 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3148 M_INTMOVE(s1, REG_ITMP1);
3149 M_XOR(s2, REG_ITMP1);
3150 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3151 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
3152 M_INTMOVE(s1, REG_ITMP2);
3153 M_XOR(s2, REG_ITMP2);
3154 M_OR(REG_ITMP1, REG_ITMP2);
3156 codegen_addreference(cd, iptr->dst.block);
3159 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3162 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3165 codegen_addreference(cd, iptr->dst.block);
3168 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3170 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3171 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3174 codegen_addreference(cd, iptr->dst.block);
3175 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3176 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3180 codegen_addreference(cd, iptr->dst.block);
3183 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3185 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3186 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3189 codegen_addreference(cd, iptr->dst.block);
3192 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3194 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3195 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3198 codegen_addreference(cd, iptr->dst.block);
3199 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3200 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3204 codegen_addreference(cd, iptr->dst.block);
3207 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3210 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3213 codegen_addreference(cd, iptr->dst.block);
3216 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3218 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3219 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3222 codegen_addreference(cd, iptr->dst.block);
3223 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3224 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3228 codegen_addreference(cd, iptr->dst.block);
3231 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3234 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3237 codegen_addreference(cd, iptr->dst.block);
3240 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3242 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3243 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3246 codegen_addreference(cd, iptr->dst.block);
3247 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3248 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3252 codegen_addreference(cd, iptr->dst.block);
3256 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3258 s1 = emit_load_s1(jd, iptr, REG_RESULT);
3259 M_INTMOVE(s1, REG_RESULT);
3260 goto nowperformreturn;
3262 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3264 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
3265 M_LNGMOVE(s1, REG_RESULT_PACKED);
3266 goto nowperformreturn;
3268 case ICMD_ARETURN: /* ..., retvalue ==> ... */
3270 s1 = emit_load_s1(jd, iptr, REG_RESULT);
3271 M_INTMOVE(s1, REG_RESULT);
3273 #ifdef ENABLE_VERIFIER
3274 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3275 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3276 iptr->sx.s23.s2.uc, 0);
3278 if (opt_showdisassemble) {
3279 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3282 #endif /* ENABLE_VERIFIER */
3283 goto nowperformreturn;
3285 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3288 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
3289 goto nowperformreturn;
3291 case ICMD_RETURN: /* ... ==> ... */
3297 p = cd->stackframesize;
3299 #if !defined(NDEBUG)
3300 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3301 emit_verbosecall_exit(jd);
3304 #if defined(ENABLE_THREADS)
3305 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3306 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3308 /* we need to save the proper return value */
3309 switch (iptr->opc) {
3312 M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3316 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3320 emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3324 emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3328 M_AST(REG_ITMP2, REG_SP, 0);
3329 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3332 /* and now restore the proper return value */
3333 switch (iptr->opc) {
3336 M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3340 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3344 emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3348 emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3354 /* restore saved registers */
3356 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3357 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3360 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3362 emit_fldl_membase(cd, REG_SP, p * 4);
3363 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3365 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3368 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3372 /* deallocate stack */
3374 if (cd->stackframesize)
3375 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3382 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3385 branch_target_t *table;
3387 table = iptr->dst.table;
3389 l = iptr->sx.s23.s2.tablelow;
3390 i = iptr->sx.s23.s3.tablehigh;
3392 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3393 M_INTMOVE(s1, REG_ITMP1);
3396 M_ISUB_IMM(l, REG_ITMP1);
3401 M_CMP_IMM(i - 1, REG_ITMP1);
3404 codegen_addreference(cd, table[0].block); /* default target */
3406 /* build jump table top down and use address of lowest entry */
3411 dseg_addtarget(cd, table->block);
3415 /* length of dataseg after last dseg_addtarget is used
3418 M_MOV_IMM(0, REG_ITMP2);
3420 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3426 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3429 lookup_target_t *lookup;
3431 lookup = iptr->dst.lookup;
3433 i = iptr->sx.s23.s2.lookupcount;
3435 MCODECHECK((i<<2)+8);
3436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3439 M_CMP_IMM(lookup->value, s1);
3441 codegen_addreference(cd, lookup->target.block);
3447 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
3451 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
3453 bte = iptr->sx.s23.s3.bte;
3457 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3459 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3460 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3461 case ICMD_INVOKEINTERFACE:
3463 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3465 um = iptr->sx.s23.s3.um;
3466 md = um->methodref->parseddesc.md;
3469 lm = iptr->sx.s23.s3.fmiref->p.method;
3471 md = lm->parseddesc;
3475 s3 = md->paramcount;
3477 MCODECHECK((s3 << 1) + 64);
3479 /* copy arguments to registers or stack location */
3481 for (s3 = s3 - 1; s3 >= 0; s3--) {
3482 src = iptr->sx.s23.s2.args[s3];
3484 if (src->varkind == ARGVAR)
3487 if (IS_INT_LNG_TYPE(src->type)) {
3488 if (!md->params[s3].inmemory) {
3489 log_text("No integer argument registers available!");
3493 if (IS_2_WORD_TYPE(src->type)) {
3494 d = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
3495 M_LST(d, REG_SP, md->params[s3].regoff * 4);
3498 d = emit_load(jd, iptr, src, REG_ITMP1);
3499 M_IST(d, REG_SP, md->params[s3].regoff * 4);
3504 if (!md->params[s3].inmemory) {
3505 s1 = rd->argfltregs[md->params[s3].regoff];
3506 d = emit_load(jd, iptr, src, s1);
3510 d = emit_load(jd, iptr, src, REG_FTMP1);
3511 if (IS_2_WORD_TYPE(src->type))
3512 M_DST(d, REG_SP, md->params[s3].regoff * 4);
3514 M_FST(d, REG_SP, md->params[s3].regoff * 4);
3519 switch (iptr->opc) {
3521 M_MOV_IMM(bte->fp, REG_ITMP1);
3524 if (INSTRUCTION_MUST_CHECK(iptr)) {
3527 codegen_add_fillinstacktrace_ref(cd);
3531 case ICMD_INVOKESPECIAL:
3532 M_ALD(REG_ITMP1, REG_SP, 0);
3535 codegen_add_nullpointerexception_ref(cd);
3539 case ICMD_INVOKESTATIC:
3541 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3544 if (opt_showdisassemble) {
3545 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3551 disp = (ptrint) lm->stubroutine;
3553 M_MOV_IMM(disp, REG_ITMP2);
3557 case ICMD_INVOKEVIRTUAL:
3558 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3559 gen_nullptr_check(REG_ITMP1);
3562 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3564 if (opt_showdisassemble) {
3565 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3571 s1 = OFFSET(vftbl_t, table[0]) +
3572 sizeof(methodptr) * lm->vftblindex;
3574 M_ALD(REG_METHODPTR, REG_ITMP1,
3575 OFFSET(java_objectheader, vftbl));
3576 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3580 case ICMD_INVOKEINTERFACE:
3581 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3582 gen_nullptr_check(REG_ITMP1);
3585 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3587 if (opt_showdisassemble) {
3588 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3595 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3596 sizeof(methodptr) * lm->class->index;
3598 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3601 M_ALD(REG_METHODPTR, REG_ITMP1,
3602 OFFSET(java_objectheader, vftbl));
3603 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3604 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3609 /* store return value */
3611 d = md->returntype.type;
3613 if (d != TYPE_VOID) {
3614 #if defined(ENABLE_SSA)
3615 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
3616 (ls->lifetime[-iptr->dst->varnum-1].type != -1))
3617 /* a "living" stackslot */
3620 if (IS_INT_LNG_TYPE(d)) {
3621 if (IS_2_WORD_TYPE(d)) {
3622 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3623 M_LNGMOVE(REG_RESULT_PACKED, s1);
3626 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3627 M_INTMOVE(REG_RESULT, s1);
3631 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3633 emit_store_dst(jd, iptr, s1);
3639 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3640 /* val.a: (classinfo*) superclass */
3642 /* superclass is an interface:
3644 * OK if ((sub == NULL) ||
3645 * (sub->vftbl->interfacetablelength > super->index) &&
3646 * (sub->vftbl->interfacetable[-super->index] != NULL));
3648 * superclass is a class:
3650 * OK if ((sub == NULL) || (0
3651 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3652 * super->vftbl->diffval));
3655 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3656 /* object type cast-check */
3659 vftbl_t *supervftbl;
3662 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3668 super = iptr->sx.s23.s3.c.cls;
3669 superindex = super->index;
3670 supervftbl = super->vftbl;
3673 #if defined(ENABLE_THREADS)
3674 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3678 /* calculate interface checkcast code size */
3680 s2 = 2; /* mov_membase_reg */
3681 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3683 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3684 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3685 2 /* test */ + 6 /* jcc */);
3688 s2 += (opt_showdisassemble ? 5 : 0);
3690 /* calculate class checkcast code size */
3692 s3 = 2; /* mov_membase_reg */
3693 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3695 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3698 if (s1 != REG_ITMP1) {
3700 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3703 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3710 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3711 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3712 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3715 s3 += 2 /* cmp */ + 6 /* jcc */;
3718 s3 += (opt_showdisassemble ? 5 : 0);
3720 /* if class is not resolved, check which code to call */
3722 if (super == NULL) {
3724 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3726 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3727 iptr->sx.s23.s3.c.ref, 0);
3729 if (opt_showdisassemble) {
3730 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3733 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3734 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3738 /* interface checkcast code */
3740 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3741 if (super != NULL) {
3746 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3748 if (super == NULL) {
3749 codegen_addpatchref(cd,
3750 PATCHER_checkcast_instanceof_interface,
3751 iptr->sx.s23.s3.c.ref,
3754 if (opt_showdisassemble) {
3755 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3760 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3761 M_ISUB_IMM32(superindex, REG_ITMP3);
3764 codegen_add_classcastexception_ref(cd, s1);
3765 M_ALD32(REG_ITMP3, REG_ITMP2,
3766 OFFSET(vftbl_t, interfacetable[0]) -
3767 superindex * sizeof(methodptr*));
3770 codegen_add_classcastexception_ref(cd, s1);
3776 /* class checkcast code */
3778 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3779 if (super != NULL) {
3784 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3786 if (super == NULL) {
3787 codegen_addpatchref(cd, PATCHER_checkcast_class,
3788 iptr->sx.s23.s3.c.ref,
3791 if (opt_showdisassemble) {
3792 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3796 M_MOV_IMM(supervftbl, REG_ITMP3);
3797 #if defined(ENABLE_THREADS)
3798 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3800 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3802 /* if (s1 != REG_ITMP1) { */
3803 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3804 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3805 /* #if defined(ENABLE_THREADS) */
3806 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3808 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3811 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3812 M_ISUB(REG_ITMP3, REG_ITMP2);
3813 M_MOV_IMM(supervftbl, REG_ITMP3);
3814 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3815 #if defined(ENABLE_THREADS)
3816 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3820 M_CMP(REG_ITMP3, REG_ITMP2);
3821 M_BA(0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3822 codegen_add_classcastexception_ref(cd, s1);
3825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3828 /* array type cast-check */
3830 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3831 M_AST(s1, REG_SP, 0 * 4);
3833 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3834 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3835 iptr->sx.s23.s3.c.ref, 0);
3837 if (opt_showdisassemble) {
3838 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3842 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3843 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3846 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3849 codegen_add_classcastexception_ref(cd, s1);
3851 d = codegen_reg_of_dst(jd, iptr, s1);
3855 emit_store_dst(jd, iptr, d);
3858 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3859 /* val.a: (classinfo*) superclass */
3861 /* superclass is an interface:
3863 * return (sub != NULL) &&
3864 * (sub->vftbl->interfacetablelength > super->index) &&
3865 * (sub->vftbl->interfacetable[-super->index] != NULL);
3867 * superclass is a class:
3869 * return ((sub != NULL) && (0
3870 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3871 * super->vftbl->diffvall));
3876 vftbl_t *supervftbl;
3879 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3885 super = iptr->sx.s23.s3.c.cls;
3886 superindex = super->index;
3887 supervftbl = super->vftbl;
3890 #if defined(ENABLE_THREADS)
3891 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3897 M_INTMOVE(s1, REG_ITMP1);
3901 /* calculate interface instanceof code size */
3903 s2 = 2; /* mov_membase_reg */
3904 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3906 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3907 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3908 2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3911 s2 += (opt_showdisassemble ? 5 : 0);
3913 /* calculate class instanceof code size */
3915 s3 = 2; /* mov_membase_reg */
3916 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3917 s3 += 5; /* mov_imm_reg */
3919 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3921 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3923 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3925 s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3926 2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3929 s3 += (opt_showdisassemble ? 5 : 0);
3933 /* if class is not resolved, check which code to call */
3937 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3939 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3940 iptr->sx.s23.s3.c.ref, 0);
3942 if (opt_showdisassemble) {
3943 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3946 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
3947 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3951 /* interface instanceof code */
3953 if (!super || (super->flags & ACC_INTERFACE)) {
3959 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3962 codegen_addpatchref(cd,
3963 PATCHER_checkcast_instanceof_interface,
3964 iptr->sx.s23.s3.c.ref, 0);
3966 if (opt_showdisassemble) {
3967 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3972 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3973 M_ISUB_IMM32(superindex, REG_ITMP3);
3976 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3977 6 /* jcc */ + 5 /* mov_imm_reg */);
3980 M_ALD32(REG_ITMP1, REG_ITMP1,
3981 OFFSET(vftbl_t, interfacetable[0]) -
3982 superindex * sizeof(methodptr*));
3984 /* emit_setcc_reg(cd, CC_A, d); */
3985 /* emit_jcc(cd, CC_BE, 5); */
3993 /* class instanceof code */
3995 if (!super || !(super->flags & ACC_INTERFACE)) {
4001 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
4004 codegen_addpatchref(cd, PATCHER_instanceof_class,
4005 iptr->sx.s23.s3.c.ref, 0);
4007 if (opt_showdisassemble) {
4008 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4012 M_MOV_IMM(supervftbl, REG_ITMP2);
4013 #if defined(ENABLE_THREADS)
4014 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
4016 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
4017 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
4018 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
4019 #if defined(ENABLE_THREADS)
4020 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
4022 M_ISUB(REG_ITMP2, REG_ITMP1);
4023 M_CLR(d); /* may be REG_ITMP2 */
4024 M_CMP(REG_ITMP3, REG_ITMP1);
4028 emit_store_dst(jd, iptr, d);
4034 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
4036 /* check for negative sizes and copy sizes to stack if necessary */
4038 MCODECHECK((iptr->s1.argcount << 1) + 64);
4040 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
4041 /* copy SAVEDVAR sizes to stack */
4042 src = iptr->sx.s23.s2.args[s1];
4044 if (src->varkind != ARGVAR) {
4045 if (IS_INMEMORY(src->flags)) {
4046 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
4047 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
4050 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
4054 /* is a patcher function set? */
4056 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
4057 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4058 iptr->sx.s23.s3.c.ref, 0);
4060 if (opt_showdisassemble) {
4061 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4068 disp = (ptrint) iptr->sx.s23.s3.c.cls;
4070 /* a0 = dimension count */
4072 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
4074 /* a1 = arraydescriptor */
4076 M_IST_IMM(disp, REG_SP, 1 * 4);
4078 /* a2 = pointer to dimensions = stack pointer */
4080 M_MOV(REG_SP, REG_ITMP1);
4081 M_AADD_IMM(3 * 4, REG_ITMP1);
4082 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4084 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4087 /* check for exception before result assignment */
4091 codegen_add_fillinstacktrace_ref(cd);
4093 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
4094 M_INTMOVE(REG_RESULT, s1);
4095 emit_store_dst(jd, iptr, s1);
4100 new_internalerror("Unknown ICMD %d", iptr->opc);
4104 } /* for instruction */
4106 /* copy values to interface registers */
4108 len = bptr->outdepth;
4110 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4113 #if defined(ENABLE_SSA)
4115 /* by edge splitting, in Blocks with phi moves there can only */
4116 /* be a goto as last command, no other Jump/Branch Command */
4117 if (!last_cmd_was_goto)
4118 codegen_insert_phi_moves(cd, rd, ls, bptr);
4120 #if !defined(NEW_VAR)
4124 #if !defined(NEW_VAR)
4127 src = bptr->outvars[len];
4128 if ((src->varkind != STACKVAR)) {
4130 if (IS_FLT_DBL_TYPE(s2)) {
4131 s1 = emit_load(jd, iptr, src, REG_FTMP1);
4132 if (!IS_INMEMORY(rd->interfaces[len][s2].flags))
4133 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
4135 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4138 if (IS_2_WORD_TYPE(s2))
4140 /* s1 = emit_load(jd, iptr, src,
4141 PACK_REGS(REG_ITMP1, REG_ITMP2)); */
4143 s1 = emit_load(jd, iptr, src, REG_ITMP1);
4145 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
4146 if (IS_2_WORD_TYPE(s2))
4147 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
4149 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
4152 if (IS_2_WORD_TYPE(s2))
4153 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4155 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
4163 /* At the end of a basic block we may have to append some nops,
4164 because the patcher stub calling code might be longer than the
4165 actual instruction. So codepatching does not change the
4166 following block unintentionally. */
4168 if (cd->mcodeptr < cd->lastmcodeptr) {
4169 while (cd->mcodeptr < cd->lastmcodeptr) {
4174 } /* if (bptr -> flags >= BBREACHED) */
4175 } /* for basic block */
4177 dseg_createlinenumbertable(cd);
4180 /* generate exception and patcher stubs */
4182 emit_exception_stubs(jd);
4183 emit_patcher_stubs(jd);
4185 emit_replacement_stubs(jd);
4190 /* everything's ok */
4195 #if defined(ENABLE_SSA)
4196 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls, basicblock *bptr) {
4197 /* look for phi moves */
4198 int t_a,s_a,i, type;
4199 int t_lt, s_lt; /* lifetime indices of phi_moves */
4200 bool t_inmemory, s_inmemory;
4201 s4 t_regoff, s_regoff, s_flags, t_flags;
4204 /* Moves from phi functions with highest indices have to be */
4205 /* inserted first, since this is the order as is used for */
4206 /* conflict resolution */
4207 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
4208 t_a = ls->phi_moves[bptr->nr][i][0];
4209 s_a = ls->phi_moves[bptr->nr][i][1];
4210 #if defined(SSA_DEBUG_VERBOSE)
4212 printf("BB %3i Move %3i <- %3i ",bptr->nr,t_a,s_a);
4215 /* local var lifetimes */
4216 t_lt = ls->maxlifetimes + t_a;
4217 type = ls->lifetime[t_lt].type;
4220 type = ls->lifetime[t_lt].local_ss->s->type;
4221 /* stackslot lifetime */
4224 #if defined(SSA_DEBUG_VERBOSE)
4226 printf("...returning - phi lifetimes where joined\n");
4231 /* local var lifetimes */
4232 s_lt = ls->maxlifetimes + s_a;
4233 type = ls->lifetime[s_lt].type;
4236 type = ls->lifetime[s_lt].type;
4237 /* stackslot lifetime */
4240 #if defined(SSA_DEBUG_VERBOSE)
4242 printf("...returning - phi lifetimes where joined\n");
4248 t_inmemory = rd->locals[t_a][type].flags & INMEMORY;
4249 t_flags = rd->locals[t_a][type].flags;
4250 t_regoff = rd->locals[t_a][type].regoff;
4253 t_inmemory = ls->lifetime[t_lt].local_ss->s->flags & INMEMORY;
4254 t_flags = ls->lifetime[t_lt].local_ss->s->flags;
4255 t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
4259 /* local var move */
4261 s_inmemory = rd->locals[s_a][type].flags & INMEMORY;
4262 s_flags = rd->locals[s_a][type].flags;
4263 s_regoff = rd->locals[s_a][type].regoff;
4265 /* stackslot lifetime */
4266 s_inmemory = ls->lifetime[s_lt].local_ss->s->flags & INMEMORY;
4267 s_flags = ls->lifetime[s_lt].local_ss->s->flags;
4268 s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
4271 #if defined(SSA_DEBUG_VERBOSE)
4273 printf("...returning - phi lifetimes where joined\n");
4278 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
4280 #if defined(SSA_DEBUG_VERBOSE)
4281 if (compileverbose) {
4282 if ((t_inmemory) && (s_inmemory)) {
4284 printf("M%3i <- M%3i",t_regoff,s_regoff);
4285 } else if (s_inmemory) {
4287 printf("R%3i <- M%3i",t_regoff,s_regoff);
4288 } else if (t_inmemory) {
4290 printf("M%3i <- R%3i",t_regoff,s_regoff);
4293 printf("R%3i <- R%3i",t_regoff,s_regoff);
4297 #endif /* defined(SSA_DEBUG_VERBOSE) */
4301 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
4302 s4 dst_regoff, s4 dst_flags) {
4303 if ((IS_INMEMORY(dst_flags)) && (IS_INMEMORY(src_flags))) {
4305 if (dst_regoff != src_regoff) {
4306 if (!IS_2_WORD_TYPE(type)) {
4307 if (IS_FLT_DBL_TYPE(type)) {
4308 emit_flds_membase(cd, REG_SP, src_regoff * 4);
4309 emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
4311 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
4313 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
4315 } else { /* LONG OR DOUBLE */
4316 if (IS_FLT_DBL_TYPE(type)) {
4317 emit_fldl_membase( cd, REG_SP, src_regoff * 4);
4318 emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
4320 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
4322 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
4323 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
4325 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP,
4326 dst_regoff * 4 + 4);
4331 if (IS_FLT_DBL_TYPE(type)) {
4332 log_text("cg_move: flt/dbl type have to be in memory\n");
4335 if (IS_2_WORD_TYPE(type)) {
4336 log_text("cg_move: longs have to be in memory\n");
4339 if (IS_INMEMORY(src_flags)) {
4341 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
4342 } else if (IS_INMEMORY(dst_flags)) {
4344 emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
4347 /* only ints can be in regs on i386 */
4348 M_INTMOVE(src_regoff,dst_regoff);
4352 #endif /* defined(ENABLE_SSA) */
4354 /* createcompilerstub **********************************************************
4356 Creates a stub routine which calls the compiler.
4358 *******************************************************************************/
4360 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
4361 #define COMPILERSTUB_CODESIZE 12
4363 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4366 u1 *createcompilerstub(methodinfo *m)
4368 u1 *s; /* memory to hold the stub */
4374 s = CNEW(u1, COMPILERSTUB_SIZE);
4376 /* set data pointer and code pointer */
4379 s = s + COMPILERSTUB_DATASIZE;
4381 /* mark start of dump memory area */
4383 dumpsize = dump_size();
4385 cd = DNEW(codegendata);
4388 /* Store the codeinfo pointer in the same place as in the
4389 methodheader for compiled methods. */
4391 code = code_codeinfo_new(m);
4393 d[0] = (ptrint) asm_call_jit_compiler;
4395 d[2] = (ptrint) code;
4397 /* code for the stub */
4399 M_MOV_IMM(m, REG_ITMP1); /* method info */
4400 M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
4403 #if defined(ENABLE_STATISTICS)
4405 count_cstub_len += COMPILERSTUB_SIZE;
4408 /* release dump area */
4410 dump_release(dumpsize);
4416 /* createnativestub ************************************************************
4418 Creates a stub routine which calls a native method.
4420 *******************************************************************************/
4422 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4430 s4 i, j; /* count variables */
4434 /* get required compiler data */
4441 /* set some variables */
4444 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4446 /* calculate stackframe size */
4448 cd->stackframesize =
4449 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4450 sizeof(localref_table) / SIZEOF_VOID_P +
4451 1 + /* function pointer */
4452 4 * 4 + /* 4 arguments (start_native_call) */
4455 /* keep stack 16-byte aligned */
4457 cd->stackframesize |= 0x3;
4459 /* create method header */
4461 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
4462 (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
4463 (void) dseg_adds4(cd, 0); /* IsSync */
4464 (void) dseg_adds4(cd, 0); /* IsLeaf */
4465 (void) dseg_adds4(cd, 0); /* IntSave */
4466 (void) dseg_adds4(cd, 0); /* FltSave */
4467 (void) dseg_addlinenumbertablesize(cd);
4468 (void) dseg_adds4(cd, 0); /* ExTableSize */
4470 /* generate native method profiling code */
4472 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4473 /* count frequency */
4475 M_MOV_IMM(code, REG_ITMP1);
4476 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
4479 /* calculate stackframe size for native function */
4481 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
4483 #if !defined(NDEBUG)
4484 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4485 emit_verbosecall_enter(jd);
4488 /* get function address (this must happen before the stackframeinfo) */
4490 #if !defined(WITH_STATIC_CLASSPATH)
4492 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
4494 if (opt_showdisassemble) {
4495 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4500 M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
4502 /* Mark the whole fpu stack as free for native functions (only for saved */
4503 /* register count == 0). */
4505 emit_ffree_reg(cd, 0);
4506 emit_ffree_reg(cd, 1);
4507 emit_ffree_reg(cd, 2);
4508 emit_ffree_reg(cd, 3);
4509 emit_ffree_reg(cd, 4);
4510 emit_ffree_reg(cd, 5);
4511 emit_ffree_reg(cd, 6);
4512 emit_ffree_reg(cd, 7);
4514 /* prepare data structures for native function call */
4516 M_MOV(REG_SP, REG_ITMP1);
4517 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
4519 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4520 M_IST_IMM(0, REG_SP, 1 * 4);
4523 M_MOV(REG_SP, REG_ITMP2);
4524 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
4526 M_AST(REG_ITMP2, REG_SP, 2 * 4);
4527 M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
4528 M_AST(REG_ITMP3, REG_SP, 3 * 4);
4529 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
4532 M_ALD(REG_ITMP3, REG_SP, 4 * 4);
4534 /* copy arguments into new stackframe */
4536 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4537 t = md->paramtypes[i].type;
4539 if (!md->params[i].inmemory) {
4540 /* no integer argument registers */
4541 } else { /* float/double in memory can be copied like int/longs */
4542 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
4543 s2 = nmd->params[j].regoff * 4;
4545 M_ILD(REG_ITMP1, REG_SP, s1);
4546 M_IST(REG_ITMP1, REG_SP, s2);
4547 if (IS_2_WORD_TYPE(t)) {
4548 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
4549 M_IST(REG_ITMP1, REG_SP, s2 + 4);
4554 /* if function is static, put class into second argument */
4556 if (m->flags & ACC_STATIC)
4557 M_AST_IMM(m->class, REG_SP, 1 * 4);
4559 /* put env into first argument */
4561 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
4563 /* call the native function */
4567 /* save return value */
4569 if (md->returntype.type != TYPE_VOID) {
4570 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4571 if (IS_2_WORD_TYPE(md->returntype.type))
4572 M_IST(REG_RESULT2, REG_SP, 2 * 4);
4573 M_IST(REG_RESULT, REG_SP, 1 * 4);
4576 if (IS_2_WORD_TYPE(md->returntype.type))
4577 emit_fstl_membase(cd, REG_SP, 1 * 4);
4579 emit_fsts_membase(cd, REG_SP, 1 * 4);
4583 #if !defined(NDEBUG)
4584 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4585 emit_verbosecall_exit(jd);
4588 /* remove native stackframe info */
4590 M_MOV(REG_SP, REG_ITMP1);
4591 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
4593 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4594 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
4596 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
4598 /* restore return value */
4600 if (md->returntype.type != TYPE_VOID) {
4601 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4602 if (IS_2_WORD_TYPE(md->returntype.type))
4603 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
4604 M_ILD(REG_RESULT, REG_SP, 1 * 4);
4607 if (IS_2_WORD_TYPE(md->returntype.type))
4608 emit_fldl_membase(cd, REG_SP, 1 * 4);
4610 emit_flds_membase(cd, REG_SP, 1 * 4);
4614 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
4616 /* check for exception */
4623 /* handle exception */
4625 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
4626 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
4627 M_ASUB_IMM(2, REG_ITMP2_XPC);
4629 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4633 /* generate patcher stubs */
4635 emit_patcher_stubs(jd);
4639 return code->entrypoint;
4644 * These are local overrides for various environment variables in Emacs.
4645 * Please do not remove this and leave it at the end of the file, where
4646 * Emacs will automagically detect them.
4647 * ---------------------------------------------------------------------
4650 * indent-tabs-mode: t
4654 * vim:noexpandtab:sw=4:ts=4: