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 5404 2006-09-07 13:29:05Z christian $
46 #include "vm/jit/i386/md-abi.h"
48 #include "vm/jit/i386/codegen.h"
49 #include "vm/jit/i386/md-emit.h"
51 #include "mm/memory.h"
52 #include "native/jni.h"
53 #include "native/native.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/lock.h"
59 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
78 # include "vm/jit/allocator/lsra.h"
80 #if defined(ENABLE_SSA)
81 # include "vm/jit/optimizing/lsra.h"
82 # include "vm/jit/optimizing/ssa.h"
86 /* codegen *********************************************************************
88 Generates machine code.
90 *******************************************************************************/
92 #if defined(ENABLE_SSA)
93 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
94 s4 dst_regoff, s4 dst_flags);
95 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls,
100 bool codegen(jitdata *jd)
106 s4 len, s1, s2, s3, d, disp;
112 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
113 builtintable_entry *bte;
115 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 = &(jd->var[jd->local_map[l * 5 + 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 (!(var->flags & INMEMORY)) { /* 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 (!(var->flags & INMEMORY)) { /* 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 (!(var->flags & INMEMORY)) { /* 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 (!(var->flags & INMEMORY)) { /* 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 (!(src->flags & INMEMORY))
474 emit_store(jd, NULL, src, d);
475 } else if (bptr->type == BBTYPE_EXH) {
476 if (!(src->flags & INMEMORY))
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 varindex = bptr->invars[len];
497 var = &(jd->var[varindex]);
498 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
499 if (!IS_2_WORD_TYPE(var->type)) {
500 if (bptr->type == BBTYPE_SBR) {
501 d = codegen_reg_of_var(0, var, REG_ITMP1);
503 emit_store(jd, NULL, var, d);
505 } else if (bptr->type == BBTYPE_EXH) {
506 d = codegen_reg_of_var(0, var, REG_ITMP1);
507 M_INTMOVE(REG_ITMP1, d);
508 emit_store(jd, NULL, var, d);
511 log_text("copy interface registers: longs have to be in \
517 printf("block %i var %i\n",bptr->nr, varindex);
518 assert((var->flags & OUTVAR));
519 /* will be done directly in simplereg lateron */
520 /* for now codegen_reg_of_var has to be called here to */
521 /* set the regoff and flags for all bptr->invars[] */
522 d = codegen_reg_of_var(0, var, REG_ITMP1);
528 /* walk through all instructions */
533 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
534 if (iptr->line != currentline) {
535 dseg_addlinenumber(cd, iptr->line);
536 currentline = iptr->line;
539 MCODECHECK(1024); /* 1kB should be enough */
542 case ICMD_INLINE_START:
545 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
546 #if defined(ENABLE_THREADS)
547 if (insinfo->synchronize) {
548 /* add monitor enter code */
549 if (insinfo->method->flags & ACC_STATIC) {
550 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
551 M_AST(REG_ITMP1, REG_SP, 0 * 4);
554 /* nullpointer check must have been performed before */
555 /* (XXX not done, yet) */
556 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
557 if (var->flags & INMEMORY) {
558 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
559 M_AST(REG_ITMP1, REG_SP, 0 * 4);
562 M_AST(var->regoff, REG_SP, 0 * 4);
566 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
570 dseg_addlinenumber_inline_start(cd, iptr);
575 case ICMD_INLINE_END:
578 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
580 dseg_addlinenumber_inline_end(cd, iptr);
581 dseg_addlinenumber(cd, iptr->line);
583 #if defined(ENABLE_THREADS)
584 if (insinfo->synchronize) {
585 /* add monitor exit code */
586 if (insinfo->method->flags & ACC_STATIC) {
587 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
588 M_AST(REG_ITMP1, REG_SP, 0 * 4);
591 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
592 if (var->flags & INMEMORY) {
593 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
594 M_AST(REG_ITMP1, REG_SP, 0 * 4);
597 M_AST(var->regoff, REG_SP, 0 * 4);
601 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
609 case ICMD_NOP: /* ... ==> ... */
612 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 codegen_add_nullpointerexception_ref(cd);
620 /* constant operations ************************************************/
622 case ICMD_ICONST: /* ... ==> ..., constant */
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
625 ICONST(d, iptr->sx.val.i);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_LCONST: /* ... ==> ..., constant */
631 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
632 LCONST(d, iptr->sx.val.l);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_FCONST: /* ... ==> ..., constant */
638 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
639 if (iptr->sx.val.f == 0.0) {
643 if (iptr->sx.val.i == 0x80000000) {
647 } else if (iptr->sx.val.f == 1.0) {
650 } else if (iptr->sx.val.f == 2.0) {
656 disp = dseg_addfloat(cd, iptr->sx.val.f);
657 emit_mov_imm_reg(cd, 0, REG_ITMP1);
659 emit_flds_membase(cd, REG_ITMP1, disp);
661 emit_store_dst(jd, iptr, d);
664 case ICMD_DCONST: /* ... ==> ..., constant */
666 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
667 if (iptr->sx.val.d == 0.0) {
671 if (iptr->sx.val.l == 0x8000000000000000LL) {
675 } else if (iptr->sx.val.d == 1.0) {
678 } else if (iptr->sx.val.d == 2.0) {
684 disp = dseg_adddouble(cd, iptr->sx.val.d);
685 emit_mov_imm_reg(cd, 0, REG_ITMP1);
687 emit_fldl_membase(cd, REG_ITMP1, disp);
689 emit_store_dst(jd, iptr, d);
692 case ICMD_ACONST: /* ... ==> ..., constant */
694 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
696 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
697 codegen_addpatchref(cd, PATCHER_aconst,
698 iptr->sx.val.c.ref, 0);
700 if (opt_showdisassemble) {
701 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
707 if (iptr->sx.val.anyptr == NULL)
710 M_MOV_IMM(iptr->sx.val.anyptr, d);
712 emit_store_dst(jd, iptr, d);
716 /* load/store operations **********************************************/
718 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
719 case ICMD_ALOAD: /* op1 = local variable */
721 if ( iptr->dst.varindex == iptr->s1.varindex)
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
726 s1 = emit_load_s1(jd, iptr, d);
728 emit_store_dst(jd, iptr, d);
732 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
733 /* s1.localindex = local variable */
735 if ( iptr->dst.varindex == iptr->s1.varindex)
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
740 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
742 emit_store_dst(jd, iptr, d);
747 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
748 /* s1.localindex = local variable */
750 if ( iptr->dst.varindex == iptr->s1.varindex)
752 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
754 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
756 emit_store_dst(jd, iptr, d);
761 case ICMD_ISTORE: /* ..., value ==> ... */
762 case ICMD_ASTORE: /* op1 = local variable */
764 if ( iptr->s1.varindex == iptr->dst.varindex)
766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 emit_store_dst(jd, iptr, d);
775 case ICMD_LSTORE: /* ..., value ==> ... */
776 /* dst.localindex = local variable */
778 if ( iptr->dst.varindex == iptr->dst.varindex)
781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
783 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
785 emit_store_dst(jd, iptr, d);
789 case ICMD_FSTORE: /* ..., value ==> ... */
790 /* dst.localindex = local variable */
792 if ( iptr->dst.varindex == iptr->s1.varindex)
794 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
796 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
798 emit_store_dst(jd, iptr, d);
802 case ICMD_DSTORE: /* ..., value ==> ... */
803 /* dst.localindex = local variable */
805 if ( iptr->dst.varindex == iptr->s1.varindex)
807 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
809 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
811 emit_store_dst(jd, iptr, d);
816 /* pop/dup/swap operations ********************************************/
818 /* attention: double and longs are only one entry in CACAO ICMDs */
820 case ICMD_POP: /* ..., value ==> ... */
821 case ICMD_POP2: /* ..., value, value ==> ... */
824 case ICMD_DUP: /* ..., a ==> ..., a, a */
826 M_COPY(iptr->s1.varindex, iptr->dst.varindex);
829 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
831 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
832 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
833 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
836 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
838 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
839 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
840 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
841 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
844 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
846 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
847 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
850 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
852 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
853 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
854 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
855 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
856 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
859 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
861 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
862 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
863 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
864 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
865 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
866 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
869 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
871 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
872 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
877 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
879 M_COPY(src, iptr->dst);
880 M_COPY(src->prev, iptr->dst->prev);
881 #if defined(ENABLE_SSA)
882 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
883 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
885 M_COPY(iptr->dst, iptr->dst->prev->prev);
886 #if defined(ENABLE_SSA)
888 M_COPY(src, iptr->dst->prev->prev);
893 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
895 M_COPY(src, iptr->dst);
896 M_COPY(src->prev, iptr->dst->prev);
897 M_COPY(src->prev->prev, iptr->dst->prev->prev);
898 #if defined(ENABLE_SSA)
899 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
900 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
902 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
903 #if defined(ENABLE_SSA)
905 M_COPY(src, iptr->dst->prev->prev->prev);
911 /* integer operations *************************************************/
913 case ICMD_INEG: /* ..., value ==> ..., - value */
915 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
916 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
919 emit_store_dst(jd, iptr, d);
922 case ICMD_LNEG: /* ..., value ==> ..., - value */
924 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
927 M_NEG(GET_LOW_REG(d));
928 M_IADDC_IMM(0, GET_HIGH_REG(d));
929 M_NEG(GET_HIGH_REG(d));
930 emit_store_dst(jd, iptr, d);
933 case ICMD_I2L: /* ..., value ==> ..., value */
935 s1 = emit_load_s1(jd, iptr, EAX);
936 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
939 M_LNGMOVE(EAX_EDX_PACKED, d);
940 emit_store_dst(jd, iptr, d);
943 case ICMD_L2I: /* ..., value ==> ..., value */
945 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
948 emit_store_dst(jd, iptr, d);
951 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
964 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
966 emit_store_dst(jd, iptr, d);
969 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
972 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974 emit_store_dst(jd, iptr, d);
978 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
980 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
981 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
982 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
989 emit_store_dst(jd, iptr, d);
992 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
993 /* sx.val.i = constant */
995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
996 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
998 M_IADD_IMM(iptr->sx.val.i, d);
999 emit_store_dst(jd, iptr, d);
1002 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1004 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1005 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1006 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1007 M_INTMOVE(s1, GET_LOW_REG(d));
1008 M_IADD(s2, GET_LOW_REG(d));
1009 /* don't use REG_ITMP1 */
1010 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1011 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1012 M_INTMOVE(s1, GET_HIGH_REG(d));
1013 M_IADDC(s2, GET_HIGH_REG(d));
1014 emit_store_dst(jd, iptr, d);
1017 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
1018 /* sx.val.l = constant */
1020 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1021 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1023 M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1024 M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1025 emit_store_dst(jd, iptr, d);
1028 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1030 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1031 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1032 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1034 M_INTMOVE(s1, REG_ITMP1);
1035 M_ISUB(s2, REG_ITMP1);
1036 M_INTMOVE(REG_ITMP1, d);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
1046 /* sx.val.i = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1051 M_ISUB_IMM(iptr->sx.val.i, d);
1052 emit_store_dst(jd, iptr, d);
1055 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1057 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1058 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1059 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1060 if (s2 == GET_LOW_REG(d)) {
1061 M_INTMOVE(s1, REG_ITMP1);
1062 M_ISUB(s2, REG_ITMP1);
1063 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
1066 M_INTMOVE(s1, GET_LOW_REG(d));
1067 M_ISUB(s2, GET_LOW_REG(d));
1069 /* don't use REG_ITMP1 */
1070 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1071 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1072 if (s2 == GET_HIGH_REG(d)) {
1073 M_INTMOVE(s1, REG_ITMP2);
1074 M_ISUBB(s2, REG_ITMP2);
1075 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
1078 M_INTMOVE(s1, GET_HIGH_REG(d));
1079 M_ISUBB(s2, GET_HIGH_REG(d));
1081 emit_store_dst(jd, iptr, d);
1084 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
1085 /* sx.val.l = constant */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1090 M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1091 M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1092 emit_store_dst(jd, iptr, d);
1095 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1097 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1098 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1099 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1106 emit_store_dst(jd, iptr, d);
1109 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1110 /* sx.val.i = constant */
1112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1113 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1114 M_IMUL_IMM(s1, iptr->sx.val.i, d);
1115 emit_store_dst(jd, iptr, d);
1118 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1120 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1121 s2 = emit_load_s2_low(jd, iptr, EDX);
1122 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1124 M_INTMOVE(s1, REG_ITMP2);
1125 M_IMUL(s2, REG_ITMP2);
1127 s1 = emit_load_s1_low(jd, iptr, EAX);
1128 s2 = emit_load_s2_high(jd, iptr, EDX);
1131 M_IADD(EDX, REG_ITMP2);
1133 s1 = emit_load_s1_low(jd, iptr, EAX);
1134 s2 = emit_load_s2_low(jd, iptr, EDX);
1137 M_INTMOVE(EAX, GET_LOW_REG(d));
1138 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1144 /* sx.val.l = constant */
1146 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1147 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
1148 ICONST(EAX, iptr->sx.val.l);
1150 M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
1151 M_IADD(REG_ITMP2, EDX);
1152 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1153 M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
1154 M_IADD(REG_ITMP2, EDX);
1155 M_LNGMOVE(EAX_EDX_PACKED, d);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1161 s1 = emit_load_s1(jd, iptr, EAX);
1162 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1163 d = codegen_reg_of_dst(jd, iptr, EAX);
1168 codegen_add_arithmeticexception_ref(cd);
1171 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1173 /* check as described in jvm spec */
1175 M_CMP_IMM(0x80000000, EAX);
1182 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
1183 emit_store_dst(jd, iptr, d);
1186 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1188 s1 = emit_load_s1(jd, iptr, EAX);
1189 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1190 d = codegen_reg_of_dst(jd, iptr, EDX);
1195 codegen_add_arithmeticexception_ref(cd);
1198 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
1200 /* check as described in jvm spec */
1202 M_CMP_IMM(0x80000000, EAX);
1210 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
1211 emit_store_dst(jd, iptr, d);
1214 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1215 /* sx.val.i = constant */
1217 /* TODO: optimize for `/ 2' */
1218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1223 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
1224 M_SRA_IMM(iptr->sx.val.i, d);
1225 emit_store_dst(jd, iptr, d);
1228 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1229 /* sx.val.i = constant */
1231 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1232 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1234 M_MOV(s1, REG_ITMP1);
1238 M_AND_IMM(iptr->sx.val.i, d);
1240 M_BGE(2 + 2 + 6 + 2);
1241 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
1243 M_AND_IMM32(iptr->sx.val.i, d); /* use 32-bit for jump offset */
1245 emit_store_dst(jd, iptr, d);
1248 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1249 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1251 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1252 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1254 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1255 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1257 codegen_add_arithmeticexception_ref(cd);
1259 bte = iptr->sx.s23.s3.bte;
1262 M_LST(s2, REG_SP, 2 * 4);
1264 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1265 M_LST(s1, REG_SP, 0 * 4);
1267 M_MOV_IMM(bte->fp, REG_ITMP3);
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1273 /* sx.val.i = constant */
1275 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1276 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1278 M_TEST(GET_HIGH_REG(d));
1280 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
1281 M_IADDC_IMM(0, GET_HIGH_REG(d));
1282 M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1283 M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
1284 emit_store_dst(jd, iptr, d);
1288 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1289 /* sx.val.l = constant */
1291 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1292 if (iptr->dst.var->flags & INMEMORY) {
1293 if (iptr->s1.var->flags & INMEMORY) {
1294 /* Alpha algorithm */
1296 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
1298 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4 + 4);
1304 /* TODO: hmm, don't know if this is always correct */
1306 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
1308 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
1314 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
1315 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
1317 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1318 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1319 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->regoff * 4 + 4);
1320 emit_jcc(cd, CC_GE, disp);
1322 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
1323 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
1325 emit_neg_reg(cd, REG_ITMP1);
1326 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1327 emit_neg_reg(cd, REG_ITMP2);
1329 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1330 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1332 emit_neg_reg(cd, REG_ITMP1);
1333 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1334 emit_neg_reg(cd, REG_ITMP2);
1336 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->regoff * 4);
1337 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->regoff * 4 + 4);
1341 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1342 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1344 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1345 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1346 M_TEST(GET_LOW_REG(s1));
1352 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1354 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1355 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1356 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1357 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1360 emit_store_dst(jd, iptr, d);
1363 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1364 /* sx.val.i = constant */
1366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1369 M_SLL_IMM(iptr->sx.val.i, d);
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1375 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1376 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1378 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1381 emit_store_dst(jd, iptr, d);
1384 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1385 /* sx.val.i = constant */
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1390 M_SRA_IMM(iptr->sx.val.i, d);
1391 emit_store_dst(jd, iptr, d);
1394 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1396 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1399 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1402 emit_store_dst(jd, iptr, d);
1405 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1406 /* sx.val.i = constant */
1408 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1411 M_SRL_IMM(iptr->sx.val.i, d);
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1417 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1418 s2 = emit_load_s2(jd, iptr, ECX);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1422 M_TEST_IMM(32, ECX);
1424 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1425 M_CLR(GET_LOW_REG(d));
1426 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1427 M_SLL(GET_LOW_REG(d));
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1432 /* sx.val.i = constant */
1434 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1437 if (iptr->sx.val.i & 0x20) {
1438 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1439 M_CLR(GET_LOW_REG(d));
1440 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1444 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1446 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1453 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1454 s2 = emit_load_s2(jd, iptr, ECX);
1455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1458 M_TEST_IMM(32, ECX);
1460 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1461 M_SRA_IMM(31, GET_HIGH_REG(d));
1462 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1463 M_SRA(GET_HIGH_REG(d));
1464 emit_store_dst(jd, iptr, d);
1467 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1468 /* sx.val.i = constant */
1470 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1473 if (iptr->sx.val.i & 0x20) {
1474 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1475 M_SRA_IMM(31, GET_HIGH_REG(d));
1476 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1480 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1482 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1484 emit_store_dst(jd, iptr, d);
1487 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1489 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1490 s2 = emit_load_s2(jd, iptr, ECX);
1491 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1494 M_TEST_IMM(32, ECX);
1496 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1497 M_CLR(GET_HIGH_REG(d));
1498 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1499 M_SRL(GET_HIGH_REG(d));
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1504 /* sx.val.l = constant */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1509 if (iptr->sx.val.i & 0x20) {
1510 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1511 M_CLR(GET_HIGH_REG(d));
1512 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1516 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1518 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1520 emit_store_dst(jd, iptr, d);
1523 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1534 emit_store_dst(jd, iptr, d);
1537 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1538 /* sx.val.i = constant */
1540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1543 M_AND_IMM(iptr->sx.val.i, d);
1544 emit_store_dst(jd, iptr, d);
1547 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1549 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1550 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1552 if (s2 == GET_LOW_REG(d))
1553 M_AND(s1, GET_LOW_REG(d));
1555 M_INTMOVE(s1, GET_LOW_REG(d));
1556 M_AND(s2, GET_LOW_REG(d));
1558 /* REG_ITMP1 probably contains low 32-bit of destination */
1559 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1560 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1561 if (s2 == GET_HIGH_REG(d))
1562 M_AND(s1, GET_HIGH_REG(d));
1564 M_INTMOVE(s1, GET_HIGH_REG(d));
1565 M_AND(s2, GET_HIGH_REG(d));
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1571 /* sx.val.l = constant */
1573 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1576 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1577 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1578 emit_store_dst(jd, iptr, d);
1581 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1584 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1592 emit_store_dst(jd, iptr, d);
1595 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1596 /* sx.val.i = constant */
1598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1601 M_OR_IMM(iptr->sx.val.i, d);
1602 emit_store_dst(jd, iptr, d);
1605 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1607 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1608 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1610 if (s2 == GET_LOW_REG(d))
1611 M_OR(s1, GET_LOW_REG(d));
1613 M_INTMOVE(s1, GET_LOW_REG(d));
1614 M_OR(s2, GET_LOW_REG(d));
1616 /* REG_ITMP1 probably contains low 32-bit of destination */
1617 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1618 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1619 if (s2 == GET_HIGH_REG(d))
1620 M_OR(s1, GET_HIGH_REG(d));
1622 M_INTMOVE(s1, GET_HIGH_REG(d));
1623 M_OR(s2, GET_HIGH_REG(d));
1625 emit_store_dst(jd, iptr, d);
1628 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1629 /* sx.val.l = constant */
1631 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1634 M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1635 M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1636 emit_store_dst(jd, iptr, d);
1639 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1642 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1650 emit_store_dst(jd, iptr, d);
1653 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1654 /* sx.val.i = constant */
1656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1659 M_XOR_IMM(iptr->sx.val.i, d);
1660 emit_store_dst(jd, iptr, d);
1663 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1665 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1666 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1668 if (s2 == GET_LOW_REG(d))
1669 M_XOR(s1, GET_LOW_REG(d));
1671 M_INTMOVE(s1, GET_LOW_REG(d));
1672 M_XOR(s2, GET_LOW_REG(d));
1674 /* REG_ITMP1 probably contains low 32-bit of destination */
1675 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1676 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1677 if (s2 == GET_HIGH_REG(d))
1678 M_XOR(s1, GET_HIGH_REG(d));
1680 M_INTMOVE(s1, GET_HIGH_REG(d));
1681 M_XOR(s2, GET_HIGH_REG(d));
1683 emit_store_dst(jd, iptr, d);
1686 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1687 /* sx.val.l = constant */
1689 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1692 M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1693 M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1694 emit_store_dst(jd, iptr, d);
1697 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1698 /* s1.localindex = variable, sx.val.i = constant*/
1700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1703 /* `inc reg' is slower on p4's (regarding to ia32
1704 optimization reference manual and benchmarks) and as
1705 fast on athlon's. */
1708 M_IADD_IMM(iptr->sx.val.i, d);
1710 emit_store_dst(jd, iptr, d);
1715 /* floating operations ************************************************/
1717 case ICMD_FNEG: /* ..., value ==> ..., - value */
1719 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1720 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1722 emit_store_dst(jd, iptr, d);
1725 case ICMD_DNEG: /* ..., value ==> ..., - value */
1727 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1728 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1730 emit_store_dst(jd, iptr, d);
1733 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1735 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1736 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1737 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1739 emit_store_dst(jd, iptr, d);
1742 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1744 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1745 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1746 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1748 emit_store_dst(jd, iptr, d);
1751 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1753 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1754 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1755 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1757 emit_store_dst(jd, iptr, d);
1760 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1762 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1763 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1764 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1766 emit_store_dst(jd, iptr, d);
1769 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1771 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1772 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1773 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1775 emit_store_dst(jd, iptr, d);
1778 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1780 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1781 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1782 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1784 emit_store_dst(jd, iptr, d);
1787 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1789 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1790 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1791 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1793 emit_store_dst(jd, iptr, d);
1796 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1798 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1799 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1800 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1802 emit_store_dst(jd, iptr, d);
1805 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1807 /* exchanged to skip fxch */
1808 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1809 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1810 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1811 /* emit_fxch(cd); */
1816 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1817 emit_store_dst(jd, iptr, d);
1818 emit_ffree_reg(cd, 0);
1822 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1824 /* exchanged to skip fxch */
1825 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1826 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1827 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1828 /* emit_fxch(cd); */
1833 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1834 emit_store_dst(jd, iptr, d);
1835 emit_ffree_reg(cd, 0);
1839 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1840 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1842 var = &(jd->var[iptr->s1.varindex]);
1843 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1845 if (var->flags & INMEMORY) {
1846 emit_fildl_membase(cd, REG_SP, var->regoff * 4);
1848 disp = dseg_adds4(cd, 0);
1849 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1851 emit_mov_reg_membase(cd, var->regoff, REG_ITMP1, disp);
1852 emit_fildl_membase(cd, REG_ITMP1, disp);
1855 emit_store_dst(jd, iptr, d);
1858 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1859 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1861 var = &(jd->var[iptr->s1.varindex]);
1862 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1863 if (var->flags & INMEMORY) {
1864 emit_fildll_membase(cd, REG_SP, var->regoff * 4);
1867 log_text("L2F: longs have to be in memory");
1870 emit_store_dst(jd, iptr, d);
1873 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1875 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1876 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1878 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1881 /* Round to zero, 53-bit mode, exception masked */
1882 disp = dseg_adds4(cd, 0x0e7f);
1883 emit_fldcw_membase(cd, REG_ITMP1, disp);
1885 var = &(jd->var[iptr->dst.varindex]);
1886 var1 = &(jd->var[iptr->s1.varindex]);
1888 if (var->flags & INMEMORY) {
1889 emit_fistpl_membase(cd, REG_SP, var->regoff * 4);
1891 /* Round to nearest, 53-bit mode, exceptions masked */
1892 disp = dseg_adds4(cd, 0x027f);
1893 emit_fldcw_membase(cd, REG_ITMP1, disp);
1895 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1896 REG_SP, var->regoff * 4);
1899 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1901 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
1904 disp = dseg_adds4(cd, 0);
1905 emit_fistpl_membase(cd, REG_ITMP1, disp);
1906 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->regoff);
1908 /* Round to nearest, 53-bit mode, exceptions masked */
1909 disp = dseg_adds4(cd, 0x027f);
1910 emit_fldcw_membase(cd, REG_ITMP1, disp);
1912 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->regoff);
1915 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1916 disp += 5 + 2 + ((REG_RESULT == var->regoff) ? 0 : 2);
1919 emit_jcc(cd, CC_NE, disp);
1921 /* XXX: change this when we use registers */
1922 emit_flds_membase(cd, REG_SP, var1->regoff * 4);
1923 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1924 emit_call_reg(cd, REG_ITMP1);
1926 if (var->flags & INMEMORY) {
1927 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
1930 M_INTMOVE(REG_RESULT, var->regoff);
1934 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1936 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1937 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1939 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1942 /* Round to zero, 53-bit mode, exception masked */
1943 disp = dseg_adds4(cd, 0x0e7f);
1944 emit_fldcw_membase(cd, REG_ITMP1, disp);
1946 var = &(jd->var[iptr->dst.varindex]);
1947 var1 = &(jd->var[iptr->s1.varindex]);
1949 if (var->flags & INMEMORY) {
1950 emit_fistpl_membase(cd, REG_SP, var->regoff * 4);
1952 /* Round to nearest, 53-bit mode, exceptions masked */
1953 disp = dseg_adds4(cd, 0x027f);
1954 emit_fldcw_membase(cd, REG_ITMP1, disp);
1956 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1957 REG_SP, var->regoff * 4);
1960 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1962 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
1965 disp = dseg_adds4(cd, 0);
1966 emit_fistpl_membase(cd, REG_ITMP1, disp);
1967 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->regoff);
1969 /* Round to nearest, 53-bit mode, exceptions masked */
1970 disp = dseg_adds4(cd, 0x027f);
1971 emit_fldcw_membase(cd, REG_ITMP1, disp);
1973 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->regoff);
1976 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
1977 disp += 5 + 2 + ((REG_RESULT == var->regoff) ? 0 : 2);
1980 emit_jcc(cd, CC_NE, disp);
1982 /* XXX: change this when we use registers */
1983 emit_fldl_membase(cd, REG_SP, var1->regoff * 4);
1984 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1985 emit_call_reg(cd, REG_ITMP1);
1987 if (var->flags & INMEMORY) {
1988 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
1990 M_INTMOVE(REG_RESULT, var->regoff);
1994 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1996 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1997 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1999 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2002 /* Round to zero, 53-bit mode, exception masked */
2003 disp = dseg_adds4(cd, 0x0e7f);
2004 emit_fldcw_membase(cd, REG_ITMP1, disp);
2006 var = &(jd->var[iptr->dst.varindex]);
2007 var1 = &(jd->var[iptr->s1.varindex]);
2009 if (var->flags & INMEMORY) {
2010 emit_fistpll_membase(cd, REG_SP, var->regoff * 4);
2012 /* Round to nearest, 53-bit mode, exceptions masked */
2013 disp = dseg_adds4(cd, 0x027f);
2014 emit_fldcw_membase(cd, REG_ITMP1, disp);
2016 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
2017 REG_SP, var->regoff * 4 + 4);
2020 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2022 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2025 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2027 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4 + 4);
2029 emit_jcc(cd, CC_NE, disp);
2031 emit_alu_imm_membase(cd, ALU_CMP, 0,
2032 REG_SP, var->regoff * 4);
2035 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2037 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2039 emit_jcc(cd, CC_NE, disp);
2041 /* XXX: change this when we use registers */
2042 emit_flds_membase(cd, REG_SP, var1->regoff * 4);
2043 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
2044 emit_call_reg(cd, REG_ITMP1);
2045 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
2046 emit_mov_reg_membase(cd, REG_RESULT2,
2047 REG_SP, var->regoff * 4 + 4);
2050 log_text("F2L: longs have to be in memory");
2055 case ICMD_D2L: /* ..., value ==> ..., (long) value */
2057 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2058 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
2060 emit_mov_imm_reg(cd, 0, REG_ITMP1);
2063 /* Round to zero, 53-bit mode, exception masked */
2064 disp = dseg_adds4(cd, 0x0e7f);
2065 emit_fldcw_membase(cd, REG_ITMP1, disp);
2067 var = &(jd->var[iptr->dst.varindex]);
2068 var1 = &(jd->var[iptr->s1.varindex]);
2070 if (var->flags & INMEMORY) {
2071 emit_fistpll_membase(cd, REG_SP, var->regoff * 4);
2073 /* Round to nearest, 53-bit mode, exceptions masked */
2074 disp = dseg_adds4(cd, 0x027f);
2075 emit_fldcw_membase(cd, REG_ITMP1, disp);
2077 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
2078 REG_SP, var->regoff * 4 + 4);
2081 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2083 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2086 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2088 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4 + 4);
2090 emit_jcc(cd, CC_NE, disp);
2092 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->regoff * 4);
2095 CALCOFFSETBYTES(disp, REG_SP, var1->regoff * 4);
2097 CALCOFFSETBYTES(disp, REG_SP, var->regoff * 4);
2099 emit_jcc(cd, CC_NE, disp);
2101 /* XXX: change this when we use registers */
2102 emit_fldl_membase(cd, REG_SP, var1->regoff * 4);
2103 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
2104 emit_call_reg(cd, REG_ITMP1);
2105 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->regoff * 4);
2106 emit_mov_reg_membase(cd, REG_RESULT2,
2107 REG_SP, var->regoff * 4 + 4);
2110 log_text("D2L: longs have to be in memory");
2115 case ICMD_F2D: /* ..., value ==> ..., (double) value */
2117 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2118 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2120 emit_store_dst(jd, iptr, d);
2123 case ICMD_D2F: /* ..., value ==> ..., (float) value */
2125 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2126 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2128 emit_store_dst(jd, iptr, d);
2131 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
2134 /* exchanged to skip fxch */
2135 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
2136 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
2137 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2138 /* emit_fxch(cd); */
2141 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
2142 emit_jcc(cd, CC_E, 6);
2143 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
2145 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2146 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2147 emit_jcc(cd, CC_B, 3 + 5);
2148 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2149 emit_jmp_imm(cd, 3);
2150 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2151 emit_store_dst(jd, iptr, d);
2154 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
2157 /* exchanged to skip fxch */
2158 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
2159 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
2160 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2161 /* emit_fxch(cd); */
2164 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
2165 emit_jcc(cd, CC_E, 3);
2166 emit_movb_imm_reg(cd, 1, REG_AH);
2168 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
2169 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
2170 emit_jcc(cd, CC_B, 3 + 5);
2171 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
2172 emit_jmp_imm(cd, 3);
2173 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
2174 emit_store_dst(jd, iptr, d);
2178 /* memory operations **************************************************/
2180 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
2182 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2183 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2184 gen_nullptr_check(s1);
2185 M_ILD(d, s1, OFFSET(java_arrayheader, size));
2186 emit_store_dst(jd, iptr, d);
2189 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
2191 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2192 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2193 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2194 if (INSTRUCTION_MUST_CHECK(iptr)) {
2195 gen_nullptr_check(s1);
2198 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]),
2200 emit_store_dst(jd, iptr, d);
2203 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
2205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2207 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2208 if (INSTRUCTION_MUST_CHECK(iptr)) {
2209 gen_nullptr_check(s1);
2212 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]),
2214 emit_store_dst(jd, iptr, d);
2217 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
2219 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2220 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2221 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2222 if (INSTRUCTION_MUST_CHECK(iptr)) {
2223 gen_nullptr_check(s1);
2226 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]),
2228 emit_store_dst(jd, iptr, d);
2231 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
2233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2234 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2236 if (INSTRUCTION_MUST_CHECK(iptr)) {
2237 gen_nullptr_check(s1);
2240 emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]),
2242 emit_store_dst(jd, iptr, d);
2245 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
2247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2248 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2250 if (INSTRUCTION_MUST_CHECK(iptr)) {
2251 gen_nullptr_check(s1);
2255 var = &(jd->var[iptr->dst.varindex]);
2257 assert(var->flags & INMEMORY);
2258 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]),
2259 s1, s2, 3, REG_ITMP3);
2260 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->regoff * 4);
2261 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4,
2262 s1, s2, 3, REG_ITMP3);
2263 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->regoff * 4 + 4);
2266 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
2268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2270 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2271 if (INSTRUCTION_MUST_CHECK(iptr)) {
2272 gen_nullptr_check(s1);
2275 emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2276 emit_store_dst(jd, iptr, d);
2279 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2282 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2283 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2284 if (INSTRUCTION_MUST_CHECK(iptr)) {
2285 gen_nullptr_check(s1);
2288 emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
2289 emit_store_dst(jd, iptr, d);
2292 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2295 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2296 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2297 if (INSTRUCTION_MUST_CHECK(iptr)) {
2298 gen_nullptr_check(s1);
2301 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
2303 emit_store_dst(jd, iptr, d);
2307 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2311 if (INSTRUCTION_MUST_CHECK(iptr)) {
2312 gen_nullptr_check(s1);
2315 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2317 /* because EBP, ESI, EDI have no xH and xL nibbles */
2318 M_INTMOVE(s3, REG_ITMP3);
2321 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]),
2325 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2329 if (INSTRUCTION_MUST_CHECK(iptr)) {
2330 gen_nullptr_check(s1);
2333 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2334 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
2338 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2342 if (INSTRUCTION_MUST_CHECK(iptr)) {
2343 gen_nullptr_check(s1);
2346 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2347 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
2351 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2355 if (INSTRUCTION_MUST_CHECK(iptr)) {
2356 gen_nullptr_check(s1);
2359 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2360 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
2364 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2367 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2368 if (INSTRUCTION_MUST_CHECK(iptr)) {
2369 gen_nullptr_check(s1);
2373 var = &(jd->var[iptr->sx.s23.s3.varindex]);
2375 assert(var->flags & INMEMORY);
2376 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP3);
2377 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0])
2379 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4 + 4, REG_ITMP3);
2380 emit_mov_reg_memindex(cd, REG_ITMP3,
2381 OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2384 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2387 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2388 if (INSTRUCTION_MUST_CHECK(iptr)) {
2389 gen_nullptr_check(s1);
2392 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2393 emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
2396 case ICMD_DASTORE: /* ..., 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_FTMP1);
2405 emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
2409 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2413 if (INSTRUCTION_MUST_CHECK(iptr)) {
2414 gen_nullptr_check(s1);
2417 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2419 M_AST(s1, REG_SP, 0 * 4);
2420 M_AST(s3, REG_SP, 1 * 4);
2421 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2425 codegen_add_arraystoreexception_ref(cd);
2427 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2428 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2429 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2430 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]),
2434 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2437 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2438 if (INSTRUCTION_MUST_CHECK(iptr)) {
2439 gen_nullptr_check(s1);
2442 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
2443 OFFSET(java_bytearray, data[0]), s1, s2, 0);
2446 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2448 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2449 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2450 if (INSTRUCTION_MUST_CHECK(iptr)) {
2451 gen_nullptr_check(s1);
2454 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2455 OFFSET(java_chararray, data[0]), s1, s2, 1);
2458 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2460 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2461 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2462 if (INSTRUCTION_MUST_CHECK(iptr)) {
2463 gen_nullptr_check(s1);
2466 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2467 OFFSET(java_shortarray, data[0]), s1, s2, 1);
2470 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2473 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2474 if (INSTRUCTION_MUST_CHECK(iptr)) {
2475 gen_nullptr_check(s1);
2478 emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
2479 OFFSET(java_intarray, data[0]), s1, s2, 2);
2482 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2485 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2486 if (INSTRUCTION_MUST_CHECK(iptr)) {
2487 gen_nullptr_check(s1);
2490 emit_mov_imm_memindex(cd,
2491 (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
2492 OFFSET(java_longarray, data[0]), s1, s2, 3);
2493 emit_mov_imm_memindex(cd,
2494 ((s4)iptr->sx.s23.s3.constval) >> 31,
2495 OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2498 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2501 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2502 if (INSTRUCTION_MUST_CHECK(iptr)) {
2503 gen_nullptr_check(s1);
2506 emit_mov_imm_memindex(cd, 0,
2507 OFFSET(java_objectarray, data[0]), s1, s2, 2);
2511 case ICMD_GETSTATIC: /* ... ==> ..., value */
2513 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2514 unresolved_field *uf = iptr->sx.s23.s3.uf;
2516 fieldtype = uf->fieldref->parseddesc.fd->type;
2518 codegen_addpatchref(cd, PATCHER_get_putstatic,
2519 iptr->sx.s23.s3.uf, 0);
2521 if (opt_showdisassemble) {
2522 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2529 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2531 fieldtype = fi->type;
2533 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2534 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2536 if (opt_showdisassemble) {
2537 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2541 disp = (ptrint) &(fi->value);
2544 M_MOV_IMM(disp, REG_ITMP1);
2545 switch (fieldtype) {
2548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2549 M_ILD(d, REG_ITMP1, 0);
2552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2553 M_LLD(d, REG_ITMP1, 0);
2556 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2557 M_FLD(d, REG_ITMP1, 0);
2560 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2561 M_DLD(d, REG_ITMP1, 0);
2564 emit_store_dst(jd, iptr, d);
2567 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2569 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2570 unresolved_field *uf = iptr->sx.s23.s3.uf;
2572 fieldtype = uf->fieldref->parseddesc.fd->type;
2574 codegen_addpatchref(cd, PATCHER_get_putstatic,
2575 iptr->sx.s23.s3.uf, 0);
2577 if (opt_showdisassemble) {
2578 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2585 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2587 fieldtype = fi->type;
2589 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2590 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2592 if (opt_showdisassemble) {
2593 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2597 disp = (ptrint) &(fi->value);
2600 M_MOV_IMM(disp, REG_ITMP1);
2601 switch (fieldtype) {
2604 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2605 M_IST(s1, REG_ITMP1, 0);
2608 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2609 M_LST(s1, REG_ITMP1, 0);
2612 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2613 emit_fstps_membase(cd, REG_ITMP1, 0);
2616 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2617 emit_fstpl_membase(cd, REG_ITMP1, 0);
2622 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2623 /* val = value (in current instruction) */
2624 /* following NOP) */
2626 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2627 unresolved_field *uf = iptr->sx.s23.s3.uf;
2629 fieldtype = uf->fieldref->parseddesc.fd->type;
2631 codegen_addpatchref(cd, PATCHER_get_putstatic,
2634 if (opt_showdisassemble) {
2635 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2642 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2644 fieldtype = fi->type;
2646 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2647 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2649 if (opt_showdisassemble) {
2650 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2654 disp = (ptrint) &(fi->value);
2657 M_MOV_IMM(disp, REG_ITMP1);
2658 switch (fieldtype) {
2661 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2664 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2665 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2672 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2675 gen_nullptr_check(s1);
2677 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2678 unresolved_field *uf = iptr->sx.s23.s3.uf;
2680 fieldtype = uf->fieldref->parseddesc.fd->type;
2682 codegen_addpatchref(cd, PATCHER_getfield,
2683 iptr->sx.s23.s3.uf, 0);
2685 if (opt_showdisassemble) {
2686 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2693 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2695 fieldtype = fi->type;
2699 switch (fieldtype) {
2702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2703 M_ILD32(d, s1, disp);
2706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2707 M_LLD32(d, s1, disp);
2710 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2711 M_FLD32(d, s1, disp);
2714 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2715 M_DLD32(d, s1, disp);
2718 emit_store_dst(jd, iptr, d);
2721 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2724 gen_nullptr_check(s1);
2726 /* must be done here because of code patching */
2728 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2729 unresolved_field *uf = iptr->sx.s23.s3.uf;
2731 fieldtype = uf->fieldref->parseddesc.fd->type;
2734 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2736 fieldtype = fi->type;
2739 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2740 if (IS_2_WORD_TYPE(fieldtype))
2741 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2746 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2748 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2749 unresolved_field *uf = iptr->sx.s23.s3.uf;
2751 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
2753 if (opt_showdisassemble) {
2754 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2761 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2766 switch (fieldtype) {
2769 M_IST32(s2, s1, disp);
2772 M_LST32(s2, s1, disp);
2775 emit_fstps_membase32(cd, s1, disp);
2778 emit_fstpl_membase32(cd, s1, disp);
2783 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2784 /* val = value (in current instruction) */
2785 /* following NOP) */
2787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2788 gen_nullptr_check(s1);
2790 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2791 unresolved_field *uf = iptr->sx.s23.s3.uf;
2793 fieldtype = uf->fieldref->parseddesc.fd->type;
2795 codegen_addpatchref(cd, PATCHER_putfieldconst,
2798 if (opt_showdisassemble) {
2799 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2807 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2809 fieldtype = fi->type;
2814 switch (fieldtype) {
2817 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2820 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2821 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2829 /* branch operations **************************************************/
2831 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2834 M_INTMOVE(s1, REG_ITMP1_XPTR);
2836 #ifdef ENABLE_VERIFIER
2837 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2838 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2839 iptr->sx.s23.s2.uc, 0);
2841 if (opt_showdisassemble) {
2842 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2845 #endif /* ENABLE_VERIFIER */
2847 M_CALL_IMM(0); /* passing exception pc */
2848 M_POP(REG_ITMP2_XPC);
2850 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2854 case ICMD_INLINE_GOTO:
2856 M_COPY(src, iptr->dst.var);
2860 case ICMD_GOTO: /* ... ==> ... */
2862 #if defined(ENABLE_SSA)
2864 last_cmd_was_goto = true;
2865 /* In case of a Goto phimoves have to be inserted before the */
2867 codegen_insert_phi_moves(cd, rd, ls, bptr);
2871 codegen_addreference(cd, iptr->dst.block);
2875 case ICMD_JSR: /* ... ==> ... */
2878 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2881 case ICMD_RET: /* ... ==> ... */
2882 /* s1.localindex = local variable */
2884 var = &(jd->var[iptr->s1.varindex]);
2885 if (var->flags & INMEMORY) {
2886 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2893 case ICMD_IFNULL: /* ..., value ==> ... */
2895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2898 codegen_addreference(cd, iptr->dst.block);
2901 case ICMD_IFNONNULL: /* ..., value ==> ... */
2903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2906 codegen_addreference(cd, iptr->dst.block);
2909 case ICMD_IFEQ: /* ..., value ==> ... */
2911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2912 M_CMP_IMM(iptr->sx.val.i, s1);
2914 codegen_addreference(cd, iptr->dst.block);
2917 case ICMD_IFLT: /* ..., value ==> ... */
2919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2920 M_CMP_IMM(iptr->sx.val.i, s1);
2922 codegen_addreference(cd, iptr->dst.block);
2925 case ICMD_IFLE: /* ..., value ==> ... */
2927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2928 M_CMP_IMM(iptr->sx.val.i, s1);
2930 codegen_addreference(cd, iptr->dst.block);
2933 case ICMD_IFNE: /* ..., value ==> ... */
2935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2936 M_CMP_IMM(iptr->sx.val.i, s1);
2938 codegen_addreference(cd, iptr->dst.block);
2941 case ICMD_IFGT: /* ..., value ==> ... */
2943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2944 M_CMP_IMM(iptr->sx.val.i, s1);
2946 codegen_addreference(cd, iptr->dst.block);
2949 case ICMD_IFGE: /* ..., value ==> ... */
2951 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2952 M_CMP_IMM(iptr->sx.val.i, s1);
2954 codegen_addreference(cd, iptr->dst.block);
2957 case ICMD_IF_LEQ: /* ..., value ==> ... */
2959 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2960 if (iptr->sx.val.l == 0) {
2961 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2962 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2965 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2966 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2967 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2968 M_OR(REG_ITMP2, REG_ITMP1);
2971 codegen_addreference(cd, iptr->dst.block);
2974 case ICMD_IF_LLT: /* ..., value ==> ... */
2976 if (iptr->sx.val.l == 0) {
2977 /* If high 32-bit are less than zero, then the 64-bits
2979 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2984 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2985 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2987 codegen_addreference(cd, iptr->dst.block);
2989 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2992 codegen_addreference(cd, iptr->dst.block);
2995 case ICMD_IF_LLE: /* ..., value ==> ... */
2997 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2998 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3000 codegen_addreference(cd, iptr->dst.block);
3002 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3004 codegen_addreference(cd, iptr->dst.block);
3007 case ICMD_IF_LNE: /* ..., value ==> ... */
3009 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3010 if (iptr->sx.val.l == 0) {
3011 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
3012 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
3015 M_LNGMOVE(s1, REG_ITMP12_PACKED);
3016 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
3017 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
3018 M_OR(REG_ITMP2, REG_ITMP1);
3021 codegen_addreference(cd, iptr->dst.block);
3024 case ICMD_IF_LGT: /* ..., value ==> ... */
3026 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3027 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3029 codegen_addreference(cd, iptr->dst.block);
3031 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3033 codegen_addreference(cd, iptr->dst.block);
3036 case ICMD_IF_LGE: /* ..., value ==> ... */
3038 if (iptr->sx.val.l == 0) {
3039 /* If high 32-bit are greater equal zero, then the
3041 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3046 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
3047 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
3049 codegen_addreference(cd, iptr->dst.block);
3051 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
3054 codegen_addreference(cd, iptr->dst.block);
3057 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
3058 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
3060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3061 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3064 codegen_addreference(cd, iptr->dst.block);
3067 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
3069 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3070 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3071 M_INTMOVE(s1, REG_ITMP1);
3072 M_XOR(s2, REG_ITMP1);
3073 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3074 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
3075 M_INTMOVE(s1, REG_ITMP2);
3076 M_XOR(s2, REG_ITMP2);
3077 M_OR(REG_ITMP1, REG_ITMP2);
3079 codegen_addreference(cd, iptr->dst.block);
3082 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
3083 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
3085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3086 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3089 codegen_addreference(cd, iptr->dst.block);
3092 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
3094 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3095 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3096 M_INTMOVE(s1, REG_ITMP1);
3097 M_XOR(s2, REG_ITMP1);
3098 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
3099 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
3100 M_INTMOVE(s1, REG_ITMP2);
3101 M_XOR(s2, REG_ITMP2);
3102 M_OR(REG_ITMP1, REG_ITMP2);
3104 codegen_addreference(cd, iptr->dst.block);
3107 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
3109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3110 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3113 codegen_addreference(cd, iptr->dst.block);
3116 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
3118 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3119 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3122 codegen_addreference(cd, iptr->dst.block);
3123 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3124 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3128 codegen_addreference(cd, iptr->dst.block);
3131 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
3133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3134 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3137 codegen_addreference(cd, iptr->dst.block);
3140 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
3142 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3143 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3146 codegen_addreference(cd, iptr->dst.block);
3147 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3148 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3152 codegen_addreference(cd, iptr->dst.block);
3155 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
3157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3158 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3161 codegen_addreference(cd, iptr->dst.block);
3164 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
3166 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3167 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3170 codegen_addreference(cd, iptr->dst.block);
3171 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3172 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3176 codegen_addreference(cd, iptr->dst.block);
3179 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
3181 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3182 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
3185 codegen_addreference(cd, iptr->dst.block);
3188 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
3190 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
3191 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
3194 codegen_addreference(cd, iptr->dst.block);
3195 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
3196 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
3200 codegen_addreference(cd, iptr->dst.block);
3204 case ICMD_IRETURN: /* ..., retvalue ==> ... */
3206 s1 = emit_load_s1(jd, iptr, REG_RESULT);
3207 M_INTMOVE(s1, REG_RESULT);
3208 goto nowperformreturn;
3210 case ICMD_LRETURN: /* ..., retvalue ==> ... */
3212 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
3213 M_LNGMOVE(s1, REG_RESULT_PACKED);
3214 goto nowperformreturn;
3216 case ICMD_ARETURN: /* ..., retvalue ==> ... */
3218 s1 = emit_load_s1(jd, iptr, REG_RESULT);
3219 M_INTMOVE(s1, REG_RESULT);
3221 #ifdef ENABLE_VERIFIER
3222 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3223 codegen_addpatchref(cd, PATCHER_athrow_areturn,
3224 iptr->sx.s23.s2.uc, 0);
3226 if (opt_showdisassemble) {
3227 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3230 #endif /* ENABLE_VERIFIER */
3231 goto nowperformreturn;
3233 case ICMD_FRETURN: /* ..., retvalue ==> ... */
3236 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
3237 goto nowperformreturn;
3239 case ICMD_RETURN: /* ... ==> ... */
3245 p = cd->stackframesize;
3247 #if !defined(NDEBUG)
3248 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3249 emit_verbosecall_exit(jd);
3252 #if defined(ENABLE_THREADS)
3253 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
3254 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
3256 /* we need to save the proper return value */
3257 switch (iptr->opc) {
3260 M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
3264 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3268 emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
3272 emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
3276 M_AST(REG_ITMP2, REG_SP, 0);
3277 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
3280 /* and now restore the proper return value */
3281 switch (iptr->opc) {
3284 M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
3288 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
3292 emit_flds_membase(cd, REG_SP, rd->memuse * 4);
3296 emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
3302 /* restore saved registers */
3304 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3305 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
3308 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3310 emit_fldl_membase(cd, REG_SP, p * 4);
3311 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
3313 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
3316 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
3320 /* deallocate stack */
3322 if (cd->stackframesize)
3323 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3330 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3333 branch_target_t *table;
3335 table = iptr->dst.table;
3337 l = iptr->sx.s23.s2.tablelow;
3338 i = iptr->sx.s23.s3.tablehigh;
3340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3341 M_INTMOVE(s1, REG_ITMP1);
3344 M_ISUB_IMM(l, REG_ITMP1);
3349 M_CMP_IMM(i - 1, REG_ITMP1);
3352 codegen_addreference(cd, table[0].block); /* default target */
3354 /* build jump table top down and use address of lowest entry */
3359 dseg_addtarget(cd, table->block);
3363 /* length of dataseg after last dseg_addtarget is used
3366 M_MOV_IMM(0, REG_ITMP2);
3368 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
3374 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3377 lookup_target_t *lookup;
3379 lookup = iptr->dst.lookup;
3381 i = iptr->sx.s23.s2.lookupcount;
3383 MCODECHECK((i<<2)+8);
3384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3387 M_CMP_IMM(lookup->value, s1);
3389 codegen_addreference(cd, lookup->target.block);
3395 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
3399 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
3401 bte = iptr->sx.s23.s3.bte;
3405 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3407 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3408 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3409 case ICMD_INVOKEINTERFACE:
3411 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3412 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
3416 lm = iptr->sx.s23.s3.fmiref->p.method;
3417 md = lm->parseddesc;
3421 s3 = md->paramcount;
3423 MCODECHECK((s3 << 1) + 64);
3425 /* copy arguments to registers or stack location */
3427 for (s3 = s3 - 1; s3 >= 0; s3--) {
3428 s1 = iptr->sx.s23.s2.args[s3];
3429 var1 = &(jd->var[s1]);
3431 /* Already Preallocated (ARGVAR) ? */
3432 if (var1->flags & PREALLOC)
3434 if (IS_INT_LNG_TYPE(var1->type)) {
3435 if (!md->params[s3].inmemory) {
3436 log_text("No integer argument registers available!");
3440 if (IS_2_WORD_TYPE(var1->type)) {
3441 d = emit_load(jd, iptr, var1, REG_ITMP12_PACKED);
3442 M_LST(d, REG_SP, md->params[s3].regoff * 4);
3444 d = emit_load(jd, iptr, var1, REG_ITMP1);
3445 M_IST(d, REG_SP, md->params[s3].regoff * 4);
3450 if (!md->params[s3].inmemory) {
3451 s1 = rd->argfltregs[md->params[s3].regoff];
3452 d = emit_load(jd, iptr, var1, s1);
3456 d = emit_load(jd, iptr, var1, REG_FTMP1);
3457 if (IS_2_WORD_TYPE(var1->type))
3458 M_DST(d, REG_SP, md->params[s3].regoff * 4);
3460 M_FST(d, REG_SP, md->params[s3].regoff * 4);
3465 switch (iptr->opc) {
3467 disp = (ptrint) bte->fp;
3468 d = md->returntype.type;
3470 M_MOV_IMM(disp, REG_ITMP1);
3474 if (INSTRUCTION_MUST_CHECK(iptr)) {
3477 codegen_add_fillinstacktrace_ref(cd);
3481 case ICMD_INVOKESPECIAL:
3482 M_ALD(REG_ITMP1, REG_SP, 0);
3485 codegen_add_nullpointerexception_ref(cd);
3489 case ICMD_INVOKESTATIC:
3491 unresolved_method *um = iptr->sx.s23.s3.um;
3493 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3496 if (opt_showdisassemble) {
3497 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3501 d = md->returntype.type;
3504 disp = (ptrint) lm->stubroutine;
3505 d = lm->parseddesc->returntype.type;
3508 M_MOV_IMM(disp, REG_ITMP2);
3512 case ICMD_INVOKEVIRTUAL:
3513 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3514 gen_nullptr_check(REG_ITMP1);
3517 unresolved_method *um = iptr->sx.s23.s3.um;
3519 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3521 if (opt_showdisassemble) {
3522 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3526 d = md->returntype.type;
3529 s1 = OFFSET(vftbl_t, table[0]) +
3530 sizeof(methodptr) * lm->vftblindex;
3531 d = md->returntype.type;
3534 M_ALD(REG_METHODPTR, REG_ITMP1,
3535 OFFSET(java_objectheader, vftbl));
3536 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3540 case ICMD_INVOKEINTERFACE:
3541 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3542 gen_nullptr_check(REG_ITMP1);
3545 unresolved_method *um = iptr->sx.s23.s3.um;
3547 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3549 if (opt_showdisassemble) {
3550 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3555 d = md->returntype.type;
3558 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3559 sizeof(methodptr) * lm->class->index;
3561 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3563 d = md->returntype.type;
3566 M_ALD(REG_METHODPTR, REG_ITMP1,
3567 OFFSET(java_objectheader, vftbl));
3568 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3569 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3574 /* d contains return type */
3576 if (d != TYPE_VOID) {
3577 #if defined(ENABLE_SSA)
3578 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
3579 (ls->lifetime[-iptr->dst->varnum-1].type != -1))
3580 /* a "living" stackslot */
3583 if (IS_INT_LNG_TYPE(d)) {
3584 if (IS_2_WORD_TYPE(d)) {
3585 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3586 M_LNGMOVE(REG_RESULT_PACKED, s1);
3589 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3590 M_INTMOVE(REG_RESULT, s1);
3594 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3596 emit_store_dst(jd, iptr, s1);
3602 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3603 /* val.a: (classinfo*) superclass */
3605 /* superclass is an interface:
3607 * OK if ((sub == NULL) ||
3608 * (sub->vftbl->interfacetablelength > super->index) &&
3609 * (sub->vftbl->interfacetable[-super->index] != NULL));
3611 * superclass is a class:
3613 * OK if ((sub == NULL) || (0
3614 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3615 * super->vftbl->diffval));
3618 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3619 /* object type cast-check */
3622 vftbl_t *supervftbl;
3625 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3631 super = iptr->sx.s23.s3.c.cls;
3632 superindex = super->index;
3633 supervftbl = super->vftbl;
3636 #if defined(ENABLE_THREADS)
3637 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3641 /* calculate interface checkcast code size */
3643 s2 = 2; /* mov_membase_reg */
3644 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3646 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
3647 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3648 2 /* test */ + 6 /* jcc */);
3651 s2 += (opt_showdisassemble ? 5 : 0);
3653 /* calculate class checkcast code size */
3655 s3 = 2; /* mov_membase_reg */
3656 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3658 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
3661 if (s1 != REG_ITMP1) {
3663 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3666 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3673 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
3674 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
3675 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3678 s3 += 2 /* cmp */ + 6 /* jcc */;
3681 s3 += (opt_showdisassemble ? 5 : 0);
3683 /* if class is not resolved, check which code to call */
3685 if (super == NULL) {
3687 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3689 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3690 iptr->sx.s23.s3.c.ref, 0);
3692 if (opt_showdisassemble) {
3693 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3696 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3697 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3701 /* interface checkcast code */
3703 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3704 if (super != NULL) {
3709 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3711 if (super == NULL) {
3712 codegen_addpatchref(cd,
3713 PATCHER_checkcast_instanceof_interface,
3714 iptr->sx.s23.s3.c.ref,
3717 if (opt_showdisassemble) {
3718 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3723 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3724 M_ISUB_IMM32(superindex, REG_ITMP3);
3727 codegen_add_classcastexception_ref(cd, s1);
3728 M_ALD32(REG_ITMP3, REG_ITMP2,
3729 OFFSET(vftbl_t, interfacetable[0]) -
3730 superindex * sizeof(methodptr*));
3733 codegen_add_classcastexception_ref(cd, s1);
3739 /* class checkcast code */
3741 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3742 if (super != NULL) {
3747 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3749 if (super == NULL) {
3750 codegen_addpatchref(cd, PATCHER_checkcast_class,
3751 iptr->sx.s23.s3.c.ref,
3754 if (opt_showdisassemble) {
3755 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3759 M_MOV_IMM(supervftbl, REG_ITMP3);
3760 #if defined(ENABLE_THREADS)
3761 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3763 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3765 /* if (s1 != REG_ITMP1) { */
3766 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3767 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3768 /* #if defined(ENABLE_THREADS) */
3769 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3771 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3774 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3775 M_ISUB(REG_ITMP3, REG_ITMP2);
3776 M_MOV_IMM(supervftbl, REG_ITMP3);
3777 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3778 #if defined(ENABLE_THREADS)
3779 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3783 M_CMP(REG_ITMP3, REG_ITMP2);
3784 M_BA(0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
3785 codegen_add_classcastexception_ref(cd, s1);
3788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3791 /* array type cast-check */
3793 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3794 M_AST(s1, REG_SP, 0 * 4);
3796 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3797 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3798 iptr->sx.s23.s3.c.ref, 0);
3800 if (opt_showdisassemble) {
3801 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3805 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3806 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3809 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3812 codegen_add_classcastexception_ref(cd, s1);
3814 d = codegen_reg_of_dst(jd, iptr, s1);
3818 emit_store_dst(jd, iptr, d);
3821 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3822 /* val.a: (classinfo*) superclass */
3824 /* superclass is an interface:
3826 * return (sub != NULL) &&
3827 * (sub->vftbl->interfacetablelength > super->index) &&
3828 * (sub->vftbl->interfacetable[-super->index] != NULL);
3830 * superclass is a class:
3832 * return ((sub != NULL) && (0
3833 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3834 * super->vftbl->diffvall));
3839 vftbl_t *supervftbl;
3842 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3848 super = iptr->sx.s23.s3.c.cls;
3849 superindex = super->index;
3850 supervftbl = super->vftbl;
3853 #if defined(ENABLE_THREADS)
3854 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3860 M_INTMOVE(s1, REG_ITMP1);
3864 /* calculate interface instanceof code size */
3866 s2 = 2; /* mov_membase_reg */
3867 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3869 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
3870 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
3871 2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3874 s2 += (opt_showdisassemble ? 5 : 0);
3876 /* calculate class instanceof code size */
3878 s3 = 2; /* mov_membase_reg */
3879 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3880 s3 += 5; /* mov_imm_reg */
3882 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3884 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3886 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3888 s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
3889 2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
3892 s3 += (opt_showdisassemble ? 5 : 0);
3896 /* if class is not resolved, check which code to call */
3900 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
3902 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3903 iptr->sx.s23.s3.c.ref, 0);
3905 if (opt_showdisassemble) {
3906 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3909 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
3910 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3914 /* interface instanceof code */
3916 if (!super || (super->flags & ACC_INTERFACE)) {
3922 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3925 codegen_addpatchref(cd,
3926 PATCHER_checkcast_instanceof_interface,
3927 iptr->sx.s23.s3.c.ref, 0);
3929 if (opt_showdisassemble) {
3930 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3935 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3936 M_ISUB_IMM32(superindex, REG_ITMP3);
3939 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3940 6 /* jcc */ + 5 /* mov_imm_reg */);
3943 M_ALD32(REG_ITMP1, REG_ITMP1,
3944 OFFSET(vftbl_t, interfacetable[0]) -
3945 superindex * sizeof(methodptr*));
3947 /* emit_setcc_reg(cd, CC_A, d); */
3948 /* emit_jcc(cd, CC_BE, 5); */
3956 /* class instanceof code */
3958 if (!super || !(super->flags & ACC_INTERFACE)) {
3964 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3967 codegen_addpatchref(cd, PATCHER_instanceof_class,
3968 iptr->sx.s23.s3.c.ref, 0);
3970 if (opt_showdisassemble) {
3971 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3975 M_MOV_IMM(supervftbl, REG_ITMP2);
3976 #if defined(ENABLE_THREADS)
3977 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3979 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3980 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3981 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3982 #if defined(ENABLE_THREADS)
3983 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3985 M_ISUB(REG_ITMP2, REG_ITMP1);
3986 M_CLR(d); /* may be REG_ITMP2 */
3987 M_CMP(REG_ITMP3, REG_ITMP1);
3991 emit_store_dst(jd, iptr, d);
3997 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3999 /* check for negative sizes and copy sizes to stack if necessary */
4001 MCODECHECK((iptr->s1.argcount << 1) + 64);
4003 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
4004 /* copy SAVEDVAR sizes to stack */
4005 s3 = iptr->sx.s23.s2.args[s1];
4006 var1 = &(jd->var[s3]);
4008 /* Already Preallocated (ARGVAR) ? */
4009 if (!(var1->flags & PREALLOC)) {
4010 if (var1->flags & INMEMORY) {
4011 M_ILD(REG_ITMP1, REG_SP, var1->regoff * 4);
4012 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
4015 M_IST(var1->regoff, REG_SP, (s1 + 3) * 4);
4019 /* is a patcher function set? */
4021 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
4022 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
4023 iptr->sx.s23.s3.c.ref, 0);
4025 if (opt_showdisassemble) {
4026 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4033 disp = (ptrint) iptr->sx.s23.s3.c.cls;
4035 /* a0 = dimension count */
4037 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
4039 /* a1 = arraydescriptor */
4041 M_IST_IMM(disp, REG_SP, 1 * 4);
4043 /* a2 = pointer to dimensions = stack pointer */
4045 M_MOV(REG_SP, REG_ITMP1);
4046 M_AADD_IMM(3 * 4, REG_ITMP1);
4047 M_AST(REG_ITMP1, REG_SP, 2 * 4);
4049 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
4052 /* check for exception before result assignment */
4056 codegen_add_fillinstacktrace_ref(cd);
4058 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
4059 M_INTMOVE(REG_RESULT, s1);
4060 emit_store_dst(jd, iptr, s1);
4065 new_internalerror("Unknown ICMD %d", iptr->opc);
4069 } /* for instruction */
4071 /* copy values to interface registers */
4073 len = bptr->outdepth;
4075 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4078 #if defined(ENABLE_SSA)
4080 /* by edge splitting, in Blocks with phi moves there can only */
4081 /* be a goto as last command, no other Jump/Branch Command */
4082 if (!last_cmd_was_goto)
4083 codegen_insert_phi_moves(cd, rd, ls, bptr);
4088 /* At the end of a basic block we may have to append some nops,
4089 because the patcher stub calling code might be longer than the
4090 actual instruction. So codepatching does not change the
4091 following block unintentionally. */
4093 if (cd->mcodeptr < cd->lastmcodeptr) {
4094 while (cd->mcodeptr < cd->lastmcodeptr) {
4099 } /* if (bptr -> flags >= BBREACHED) */
4100 } /* for basic block */
4102 dseg_createlinenumbertable(cd);
4105 /* generate exception and patcher stubs */
4107 emit_exception_stubs(jd);
4108 emit_patcher_stubs(jd);
4110 emit_replacement_stubs(jd);
4115 /* everything's ok */
4120 bool codegen(jitdata *jd)
4126 s4 len, s1, s2, s3, d, disp;
4133 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
4134 unresolved_method *um;
4135 builtintable_entry *bte;
4137 rplpoint *replacementpoint;
4139 #if defined(ENABLE_SSA)
4141 bool last_cmd_was_goto;
4143 last_cmd_was_goto = false;
4147 /* get required compiler data */
4154 /* prevent compiler warnings */
4164 s4 savedregs_num = 0;
4167 /* space to save used callee saved registers */
4169 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
4171 /* float register are saved on 2 4-byte stackslots */
4172 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
4174 cd->stackframesize = rd->memuse + savedregs_num;
4177 #if defined(ENABLE_THREADS)
4178 /* space to save argument of monitor_enter */
4180 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
4181 /* reserve 2 slots for long/double return values for monitorexit */
4183 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
4184 cd->stackframesize += 2;
4186 cd->stackframesize++;
4190 /* create method header */
4192 /* Keep stack of non-leaf functions 16-byte aligned. */
4194 if (!jd->isleafmethod)
4195 cd->stackframesize |= 0x3;
4197 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
4198 (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
4200 #if defined(ENABLE_THREADS)
4201 /* IsSync contains the offset relative to the stack pointer for the
4202 argument of monitor_exit used in the exception handler. Since the
4203 offset could be zero and give a wrong meaning of the flag it is
4207 if (checksync && (m->flags & ACC_SYNCHRONIZED))
4208 (void) dseg_adds4(cd, (rd->memuse + 1) * 4); /* IsSync */
4211 (void) dseg_adds4(cd, 0); /* IsSync */
4213 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
4214 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
4215 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
4217 /* adds a reference for the length of the line number counter. We don't
4218 know the size yet, since we evaluate the information during code
4219 generation, to save one additional iteration over the whole
4220 instructions. During code optimization the position could have changed
4221 to the information gotten from the class file */
4222 (void) dseg_addlinenumbertablesize(cd);
4224 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
4226 /* create exception table */
4228 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
4229 dseg_addtarget(cd, ex->start);
4230 dseg_addtarget(cd, ex->end);
4231 dseg_addtarget(cd, ex->handler);
4232 (void) dseg_addaddress(cd, ex->catchtype.cls);
4235 /* generate method profiling code */
4237 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4238 /* count frequency */
4240 M_MOV_IMM(code, REG_ITMP3);
4241 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
4244 /* create stack frame (if necessary) */
4246 if (cd->stackframesize)
4247 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
4249 /* save return address and used callee saved registers */
4251 p = cd->stackframesize;
4252 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
4253 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
4255 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
4256 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
4259 /* take arguments out of register or stack frame */
4264 for (p = 0, l = 0; p < md->paramcount; p++) {
4265 t = md->paramtypes[p].type;
4266 #if defined(ENABLE_SSA)
4271 var = &(rd->locals[l][t]);
4273 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
4277 s1 = md->params[p].regoff;
4279 if (IS_INT_LNG_TYPE(t)) { /* integer args */
4280 if (!md->params[p].inmemory) { /* register arguments */
4281 log_text("integer register argument");
4283 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
4284 /* rd->argintregs[md->params[p].regoff -> var->regoff */
4286 else { /* reg arg -> spilled */
4287 /* rd->argintregs[md->params[p].regoff -> var->regoff * 4 */
4290 else { /* stack arguments */
4291 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
4292 emit_mov_membase_reg( /* + 4 for return address */
4293 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->regoff);
4294 /* + 4 for return address */
4296 else { /* stack arg -> spilled */
4297 if (!IS_2_WORD_TYPE(t)) {
4298 #if defined(ENABLE_SSA)
4299 /* no copy avoiding by now possible with SSA */
4301 emit_mov_membase_reg( /* + 4 for return address */
4302 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
4304 emit_mov_reg_membase(
4305 cd, REG_ITMP1, REG_SP, var->regoff * 4);
4308 #endif /*defined(ENABLE_SSA)*/
4309 /* reuse Stackslotand avoid copying */
4310 var->regoff = cd->stackframesize + s1 + 1;
4314 #if defined(ENABLE_SSA)
4315 /* no copy avoiding by now possible with SSA */
4317 emit_mov_membase_reg( /* + 4 for return address */
4318 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
4320 emit_mov_reg_membase(
4321 cd, REG_ITMP1, REG_SP, var->regoff * 4);
4322 emit_mov_membase_reg( /* + 4 for return address */
4323 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
4325 emit_mov_reg_membase(
4326 cd, REG_ITMP1, REG_SP, var->regoff * 4 + 4);
4329 #endif /*defined(ENABLE_SSA)*/
4330 /* reuse Stackslotand avoid copying */
4331 var->regoff = cd->stackframesize + s1 + 1;
4336 else { /* floating args */
4337 if (!md->params[p].inmemory) { /* register arguments */
4338 log_text("There are no float argument registers!");
4340 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
4341 /* rd->argfltregs[md->params[p].regoff -> var->regoff */
4342 } else { /* reg arg -> spilled */
4343 /* rd->argfltregs[md->params[p].regoff -> var->regoff * 4 */
4347 else { /* stack arguments */
4348 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
4349 if (t == TYPE_FLT) {
4351 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4353 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
4358 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4360 /* emit_fstp_reg(cd, var->regoff + fpu_st_offset); */
4363 } else { /* stack-arg -> spilled */
4364 #if defined(ENABLE_SSA)
4365 /* no copy avoiding by now possible with SSA */
4367 emit_mov_membase_reg(
4368 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
4369 emit_mov_reg_membase(
4370 cd, REG_ITMP1, REG_SP, var->regoff * 4);
4371 if (t == TYPE_FLT) {
4373 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4374 emit_fstps_membase(cd, REG_SP, var->regoff * 4);
4378 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
4379 emit_fstpl_membase(cd, REG_SP, var->regoff * 4);
4383 #endif /*defined(ENABLE_SSA)*/
4384 /* reuse Stackslotand avoid copying */
4385 var->regoff = cd->stackframesize + s1 + 1;
4391 /* call monitorenter function */
4393 #if defined(ENABLE_THREADS)
4394 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
4397 if (m->flags & ACC_STATIC) {
4398 M_MOV_IMM(&m->class->object.header, REG_ITMP1);
4401 M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
4404 codegen_add_nullpointerexception_ref(cd);
4407 M_AST(REG_ITMP1, REG_SP, s1 * 4);
4408 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4409 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
4414 #if !defined(NDEBUG)
4415 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4416 emit_verbosecall_enter(jd);
4421 #if defined(ENABLE_SSA)
4422 /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
4424 codegen_insert_phi_moves(cd, rd, ls, ls->basicblocks[0]);
4427 /* end of header generation */
4429 replacementpoint = jd->code->rplpoints;
4431 /* walk through all basic blocks */
4432 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
4434 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
4436 if (bptr->flags >= BBREACHED) {
4438 /* branch resolving */
4441 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
4442 gen_resolvebranch(cd->mcodebase + brefs->branchpos,
4448 /* handle replacement points */
4450 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
4451 replacementpoint->pc = (u1*)bptr->mpc; /* will be resolved later */
4455 assert(cd->lastmcodeptr <= cd->mcodeptr);
4456 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
4460 /* copy interface registers to their destination */
4462 len = bptr->indepth;
4466 /* generate basic block profiling code */
4468 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
4469 /* count frequency */
4471 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
4472 M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
4476 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
4477 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
4480 # if defined(ENABLE_SSA)
4482 last_cmd_was_goto = false;
4486 src = bptr->invars[len];
4487 if (bptr->type != BBTYPE_STD) {
4488 if (!IS_2_WORD_TYPE(src->type)) {
4489 if (bptr->type == BBTYPE_SBR) {
4490 if (!IS_INMEMORY(src->flags))
4494 emit_pop_reg(cd, d);
4495 emit_store(jd, NULL, src, d);
4496 } else if (bptr->type == BBTYPE_EXH) {
4497 if (!IS_INMEMORY(src->flags))
4501 M_INTMOVE(REG_ITMP1, d);
4502 emit_store(jd, NULL, src, d);
4506 log_text("copy interface registers(EXH, SBR): longs have to be in memory (begin 1)");
4513 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
4517 src = bptr->invars[len];
4518 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
4519 if (!IS_2_WORD_TYPE(src->type)) {
4520 if (bptr->type == BBTYPE_SBR) {
4521 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4522 emit_pop_reg(cd, d);
4523 emit_store(jd, NULL, src, d);
4525 } else if (bptr->type == BBTYPE_EXH) {
4526 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4527 M_INTMOVE(REG_ITMP1, d);
4528 emit_store(jd, NULL, src, d);
4531 log_text("copy interface registers: longs have to be in \
4537 #if defined(NEW_VAR)
4538 assert(src->varkind == STACKVAR);
4539 /* will be done directly in simplereg lateron */
4540 /* for now codegen_reg_of_var has to be called here to */
4541 /* set the regoff and flags for all bptr->invars[] */
4542 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4544 if (IS_LNG_TYPE(src->type))
4545 d = codegen_reg_of_var(rd, 0, src,
4546 PACK_REGS(REG_ITMP1, REG_ITMP2));
4548 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
4549 /* d = codegen_reg_of_var(rd, 0, src, REG_IFTMP); */
4551 if ((src->varkind != STACKVAR)) {
4553 s1 = rd->interfaces[len][s2].regoff;
4555 if (IS_FLT_DBL_TYPE(s2)) {
4556 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
4560 if (IS_2_WORD_TYPE(s2))
4561 M_DLD(d, REG_SP, s1 * 4);
4563 M_FLD(d, REG_SP, s1 * 4);
4567 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
4568 if (IS_2_WORD_TYPE(s2))
4574 if (IS_2_WORD_TYPE(s2))
4575 M_LLD(d, REG_SP, s1 * 4);
4577 M_ILD(d, REG_SP, s1 * 4);
4581 emit_store(jd, NULL, src, d);
4588 /* walk through all instructions */
4593 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
4594 if (iptr->line != currentline) {
4595 dseg_addlinenumber(cd, iptr->line);
4596 currentline = iptr->line;
4599 MCODECHECK(1024); /* 1kB should be enough */
4601 switch (iptr->opc) {
4602 case ICMD_INLINE_START:
4605 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
4606 #if defined(ENABLE_THREADS)
4607 if (insinfo->synchronize) {
4608 /* add monitor enter code */
4609 if (insinfo->method->flags & ACC_STATIC) {
4610 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
4611 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4614 /* nullpointer check must have been performed before */
4615 /* (XXX not done, yet) */
4616 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
4617 if (IS_INMEMORY(var->flags)) {
4618 emit_mov_membase_reg(cd, REG_SP, var->regoff * 4, REG_ITMP1);
4619 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4622 M_AST(var->regoff, REG_SP, 0 * 4);
4626 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
4630 dseg_addlinenumber_inline_start(cd, iptr);
4635 case ICMD_INLINE_END:
4638 insinfo_inline *insinfo = (insinfo_inline *) iptr->target;
4640 dseg_addlinenumber_inline_end(cd, iptr);
4641 dseg_addlinenumber(cd, iptr->line);
4643 #if defined(ENABLE_THREADS)
4644 if (insinfo->synchronize) {
4645 /* add monitor exit code */
4646 if (insinfo->method->flags & ACC_STATIC) {
4647 M_MOV_IMM(&insinfo->method->class->object.header, REG_ITMP1);
4648 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4651 var = &(rd->locals[insinfo->synclocal][TYPE_ADR]);
4652 if (IS_INMEMORY(var->flags)) {
4653 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
4654 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4657 M_AST(var->regoff, REG_SP, 0 * 4);
4661 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
4669 case ICMD_NOP: /* ... ==> ... */
4672 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
4674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
4677 codegen_add_nullpointerexception_ref(cd);
4680 /* constant operations ************************************************/
4682 case ICMD_ICONST: /* ... ==> ..., constant */
4684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
4685 ICONST(d, iptr->sx.val.i);
4686 emit_store_dst(jd, iptr, d);
4689 case ICMD_LCONST: /* ... ==> ..., constant */
4691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
4692 LCONST(d, iptr->sx.val.l);
4693 emit_store_dst(jd, iptr, d);
4696 case ICMD_FCONST: /* ... ==> ..., constant */
4698 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4699 if (iptr->sx.val.f == 0.0) {
4703 if (iptr->sx.val.i == 0x80000000) {
4707 } else if (iptr->sx.val.f == 1.0) {
4710 } else if (iptr->sx.val.f == 2.0) {
4716 disp = dseg_addfloat(cd, iptr->sx.val.f);
4717 emit_mov_imm_reg(cd, 0, REG_ITMP1);
4719 emit_flds_membase(cd, REG_ITMP1, disp);
4721 emit_store_dst(jd, iptr, d);
4724 case ICMD_DCONST: /* ... ==> ..., constant */
4726 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4727 if (iptr->sx.val.d == 0.0) {
4731 if (iptr->sx.val.l == 0x8000000000000000LL) {
4735 } else if (iptr->sx.val.d == 1.0) {
4738 } else if (iptr->sx.val.d == 2.0) {
4744 disp = dseg_adddouble(cd, iptr->sx.val.d);
4745 emit_mov_imm_reg(cd, 0, REG_ITMP1);
4747 emit_fldl_membase(cd, REG_ITMP1, disp);
4749 emit_store_dst(jd, iptr, d);
4752 case ICMD_ACONST: /* ... ==> ..., constant */
4754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
4756 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
4757 codegen_addpatchref(cd, PATCHER_aconst,
4758 iptr->sx.val.c.ref, 0);
4760 if (opt_showdisassemble) {
4761 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
4767 if (iptr->sx.val.anyptr == NULL)
4770 M_MOV_IMM(iptr->sx.val.anyptr, d);
4772 emit_store_dst(jd, iptr, d);
4776 /* load/store operations **********************************************/
4778 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
4779 case ICMD_ALOAD: /* op1 = local variable */
4781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
4782 if ((iptr->dst.var->varkind == LOCALVAR) &&
4783 (iptr->dst.var->varnum == iptr->s1.localindex))
4785 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4786 if (IS_INMEMORY(var->flags))
4787 M_ILD(d, REG_SP, var->regoff * 4);
4789 M_INTMOVE(var->regoff, d);
4790 emit_store_dst(jd, iptr, d);
4793 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
4794 /* s1.localindex = local variable */
4796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
4797 if ((iptr->dst.var->varkind == LOCALVAR) &&
4798 (iptr->dst.var->varnum == iptr->s1.localindex))
4800 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4801 if (IS_INMEMORY(var->flags))
4802 M_LLD(d, REG_SP, var->regoff * 4);
4804 M_LNGMOVE(var->regoff, d);
4805 emit_store_dst(jd, iptr, d);
4808 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
4809 /* s1.localindex = local variable */
4811 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4812 if ((iptr->dst.var->varkind == LOCALVAR) &&
4813 (iptr->dst.var->varnum == iptr->s1.localindex))
4815 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4816 if (IS_INMEMORY(var->flags))
4817 M_FLD(d, REG_SP, var->regoff * 4);
4819 M_FLTMOVE(var->regoff, d);
4820 emit_store_dst(jd, iptr, d);
4823 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
4824 /* s1.localindex = local variable */
4826 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
4827 if ((iptr->dst.var->varkind == LOCALVAR) &&
4828 (iptr->dst.var->varnum == iptr->s1.localindex))
4830 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
4831 if (IS_INMEMORY(var->flags))
4832 M_DLD(d, REG_SP, var->regoff * 4);
4834 M_FLTMOVE(var->regoff, d);
4835 emit_store_dst(jd, iptr, d);
4838 case ICMD_ISTORE: /* ..., value ==> ... */
4839 case ICMD_ASTORE: /* op1 = local variable */
4841 if ((iptr->s1.var->varkind == LOCALVAR) &&
4842 (iptr->s1.var->varnum == iptr->dst.localindex))
4844 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4845 if (IS_INMEMORY(var->flags)) {
4846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
4847 M_IST(s1, REG_SP, var->regoff * 4);
4850 s1 = emit_load_s1(jd, iptr, var->regoff);
4851 M_INTMOVE(s1, var->regoff);
4855 case ICMD_LSTORE: /* ..., value ==> ... */
4856 /* dst.localindex = local variable */
4858 if ((iptr->s1.var->varkind == LOCALVAR) &&
4859 (iptr->s1.var->varnum == iptr->dst.localindex))
4861 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4862 if (IS_INMEMORY(var->flags)) {
4863 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
4864 M_LST(s1, REG_SP, var->regoff * 4);
4867 s1 = emit_load_s1(jd, iptr, var->regoff);
4868 M_LNGMOVE(s1, var->regoff);
4872 case ICMD_FSTORE: /* ..., value ==> ... */
4873 /* dst.localindex = local variable */
4875 if ((iptr->s1.var->varkind == LOCALVAR) &&
4876 (iptr->s1.var->varnum == iptr->dst.localindex))
4878 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4879 if (IS_INMEMORY(var->flags)) {
4880 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
4881 M_FST(s1, REG_SP, var->regoff * 4);
4884 s1 = emit_load_s1(jd, iptr, var->regoff);
4885 M_FLTMOVE(s1, var->regoff);
4889 case ICMD_DSTORE: /* ..., value ==> ... */
4890 /* dst.localindex = local variable */
4892 if ((iptr->s1.var->varkind == LOCALVAR) &&
4893 (iptr->s1.var->varnum == iptr->dst.localindex))
4895 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
4896 if (IS_INMEMORY(var->flags)) {
4897 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
4898 M_DST(s1, REG_SP, var->regoff * 4);
4901 s1 = emit_load_s1(jd, iptr, var->regoff);
4902 M_FLTMOVE(s1, var->regoff);
4907 /* pop/dup/swap operations ********************************************/
4909 /* attention: double and longs are only one entry in CACAO ICMDs */
4911 case ICMD_POP: /* ..., value ==> ... */
4912 case ICMD_POP2: /* ..., value, value ==> ... */
4915 case ICMD_DUP: /* ..., a ==> ..., a, a */
4917 M_COPY(iptr->s1.var, iptr->dst.var);
4920 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
4922 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
4923 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
4924 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
4927 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
4929 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
4930 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
4931 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
4932 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
4935 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
4937 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
4938 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
4941 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
4943 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
4944 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
4945 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
4946 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
4947 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
4950 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
4952 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
4953 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
4954 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
4955 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
4956 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
4957 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
4960 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
4962 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
4963 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
4968 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
4970 M_COPY(src, iptr->dst);
4971 M_COPY(src->prev, iptr->dst->prev);
4972 #if defined(ENABLE_SSA)
4973 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
4974 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
4976 M_COPY(iptr->dst, iptr->dst->prev->prev);
4977 #if defined(ENABLE_SSA)
4979 M_COPY(src, iptr->dst->prev->prev);
4984 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
4986 M_COPY(src, iptr->dst);
4987 M_COPY(src->prev, iptr->dst->prev);
4988 M_COPY(src->prev->prev, iptr->dst->prev->prev);
4989 #if defined(ENABLE_SSA)
4990 if ((ls==NULL) || (iptr->dst->varkind != TEMPVAR) ||
4991 (ls->lifetime[-iptr->dst->varnum-1].type != -1)) {
4993 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
4994 #if defined(ENABLE_SSA)
4996 M_COPY(src, iptr->dst->prev->prev->prev);
5002 /* integer operations *************************************************/
5004 case ICMD_INEG: /* ..., value ==> ..., - value */
5006 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5007 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5010 emit_store_dst(jd, iptr, d);
5013 case ICMD_LNEG: /* ..., value ==> ..., - value */
5015 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5018 M_NEG(GET_LOW_REG(d));
5019 M_IADDC_IMM(0, GET_HIGH_REG(d));
5020 M_NEG(GET_HIGH_REG(d));
5021 emit_store_dst(jd, iptr, d);
5024 case ICMD_I2L: /* ..., value ==> ..., value */
5026 s1 = emit_load_s1(jd, iptr, EAX);
5027 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
5030 M_LNGMOVE(EAX_EDX_PACKED, d);
5031 emit_store_dst(jd, iptr, d);
5034 case ICMD_L2I: /* ..., value ==> ..., value */
5036 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
5037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5039 emit_store_dst(jd, iptr, d);
5042 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
5044 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5045 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5049 emit_store_dst(jd, iptr, d);
5052 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
5054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5057 emit_store_dst(jd, iptr, d);
5060 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
5062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5065 emit_store_dst(jd, iptr, d);
5069 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
5071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5072 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5073 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5080 emit_store_dst(jd, iptr, d);
5083 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
5084 /* sx.val.i = constant */
5086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5089 M_IADD_IMM(iptr->sx.val.i, d);
5090 emit_store_dst(jd, iptr, d);
5093 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
5095 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5096 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5097 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5098 M_INTMOVE(s1, GET_LOW_REG(d));
5099 M_IADD(s2, GET_LOW_REG(d));
5100 /* don't use REG_ITMP1 */
5101 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5102 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5103 M_INTMOVE(s1, GET_HIGH_REG(d));
5104 M_IADDC(s2, GET_HIGH_REG(d));
5105 emit_store_dst(jd, iptr, d);
5108 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
5109 /* sx.val.l = constant */
5111 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5114 M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5115 M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5116 emit_store_dst(jd, iptr, d);
5119 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
5121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5122 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5123 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5125 M_INTMOVE(s1, REG_ITMP1);
5126 M_ISUB(s2, REG_ITMP1);
5127 M_INTMOVE(REG_ITMP1, d);
5133 emit_store_dst(jd, iptr, d);
5136 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
5137 /* sx.val.i = constant */
5139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5142 M_ISUB_IMM(iptr->sx.val.i, d);
5143 emit_store_dst(jd, iptr, d);
5146 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
5148 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5149 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5151 if (s2 == GET_LOW_REG(d)) {
5152 M_INTMOVE(s1, REG_ITMP1);
5153 M_ISUB(s2, REG_ITMP1);
5154 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
5157 M_INTMOVE(s1, GET_LOW_REG(d));
5158 M_ISUB(s2, GET_LOW_REG(d));
5160 /* don't use REG_ITMP1 */
5161 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5162 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5163 if (s2 == GET_HIGH_REG(d)) {
5164 M_INTMOVE(s1, REG_ITMP2);
5165 M_ISUBB(s2, REG_ITMP2);
5166 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
5169 M_INTMOVE(s1, GET_HIGH_REG(d));
5170 M_ISUBB(s2, GET_HIGH_REG(d));
5172 emit_store_dst(jd, iptr, d);
5175 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
5176 /* sx.val.l = constant */
5178 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5179 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5181 M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5182 M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5183 emit_store_dst(jd, iptr, d);
5186 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
5188 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5189 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5190 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5197 emit_store_dst(jd, iptr, d);
5200 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
5201 /* sx.val.i = constant */
5203 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5204 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5205 M_IMUL_IMM(s1, iptr->sx.val.i, d);
5206 emit_store_dst(jd, iptr, d);
5209 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
5211 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5212 s2 = emit_load_s2_low(jd, iptr, EDX);
5213 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
5215 M_INTMOVE(s1, REG_ITMP2);
5216 M_IMUL(s2, REG_ITMP2);
5218 s1 = emit_load_s1_low(jd, iptr, EAX);
5219 s2 = emit_load_s2_high(jd, iptr, EDX);
5222 M_IADD(EDX, REG_ITMP2);
5224 s1 = emit_load_s1_low(jd, iptr, EAX);
5225 s2 = emit_load_s2_low(jd, iptr, EDX);
5228 M_INTMOVE(EAX, GET_LOW_REG(d));
5229 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
5231 emit_store_dst(jd, iptr, d);
5234 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
5235 /* sx.val.l = constant */
5237 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
5238 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
5239 ICONST(EAX, iptr->sx.val.l);
5241 M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
5242 M_IADD(REG_ITMP2, EDX);
5243 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5244 M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
5245 M_IADD(REG_ITMP2, EDX);
5246 M_LNGMOVE(EAX_EDX_PACKED, d);
5247 emit_store_dst(jd, iptr, d);
5250 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
5252 s1 = emit_load_s1(jd, iptr, EAX);
5253 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5254 d = codegen_reg_of_dst(jd, iptr, EAX);
5259 codegen_add_arithmeticexception_ref(cd);
5262 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
5264 /* check as described in jvm spec */
5266 M_CMP_IMM(0x80000000, EAX);
5273 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
5274 emit_store_dst(jd, iptr, d);
5277 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
5279 s1 = emit_load_s1(jd, iptr, EAX);
5280 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5281 d = codegen_reg_of_dst(jd, iptr, EDX);
5286 codegen_add_arithmeticexception_ref(cd);
5289 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
5291 /* check as described in jvm spec */
5293 M_CMP_IMM(0x80000000, EAX);
5301 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
5302 emit_store_dst(jd, iptr, d);
5305 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
5306 /* sx.val.i = constant */
5308 /* TODO: optimize for `/ 2' */
5309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5310 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5314 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d); /* 32-bit for jump off. */
5315 M_SRA_IMM(iptr->sx.val.i, d);
5316 emit_store_dst(jd, iptr, d);
5319 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
5320 /* sx.val.i = constant */
5322 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5323 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5325 M_MOV(s1, REG_ITMP1);
5329 M_AND_IMM(iptr->sx.val.i, d);
5331 M_BGE(2 + 2 + 6 + 2);
5332 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
5334 M_AND_IMM32(iptr->sx.val.i, d); /* use 32-bit for jump offset */
5336 emit_store_dst(jd, iptr, d);
5339 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
5340 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
5342 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
5343 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
5345 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
5346 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
5348 codegen_add_arithmeticexception_ref(cd);
5350 bte = iptr->sx.s23.s3.bte;
5353 M_LST(s2, REG_SP, 2 * 4);
5355 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5356 M_LST(s1, REG_SP, 0 * 4);
5358 M_MOV_IMM(bte->fp, REG_ITMP3);
5360 emit_store_dst(jd, iptr, d);
5363 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
5364 /* sx.val.i = constant */
5366 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5367 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
5369 M_TEST(GET_HIGH_REG(d));
5371 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
5372 M_IADDC_IMM(0, GET_HIGH_REG(d));
5373 M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
5374 M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
5375 emit_store_dst(jd, iptr, d);
5379 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
5380 /* sx.val.l = constant */
5382 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
5383 if (IS_INMEMORY(iptr->dst.var->flags)) {
5384 if (IS_INMEMORY(iptr->s1.var->flags)) {
5385 /* Alpha algorithm */
5387 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
5389 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4 + 4);
5395 /* TODO: hmm, don't know if this is always correct */
5397 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
5399 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
5405 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
5406 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
5408 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
5409 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
5410 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->regoff * 4 + 4);
5411 emit_jcc(cd, CC_GE, disp);
5413 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4, REG_ITMP1);
5414 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->regoff * 4 + 4, REG_ITMP2);
5416 emit_neg_reg(cd, REG_ITMP1);
5417 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
5418 emit_neg_reg(cd, REG_ITMP2);
5420 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
5421 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
5423 emit_neg_reg(cd, REG_ITMP1);
5424 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
5425 emit_neg_reg(cd, REG_ITMP2);
5427 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->regoff * 4);
5428 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->regoff * 4 + 4);
5432 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5433 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
5435 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5436 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5437 M_TEST(GET_LOW_REG(s1));
5443 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
5445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5446 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5448 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
5451 emit_store_dst(jd, iptr, d);
5454 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
5455 /* sx.val.i = constant */
5457 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5460 M_SLL_IMM(iptr->sx.val.i, d);
5461 emit_store_dst(jd, iptr, d);
5464 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
5466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5467 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5469 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
5472 emit_store_dst(jd, iptr, d);
5475 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
5476 /* sx.val.i = constant */
5478 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5481 M_SRA_IMM(iptr->sx.val.i, d);
5482 emit_store_dst(jd, iptr, d);
5485 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
5487 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5488 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5490 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
5493 emit_store_dst(jd, iptr, d);
5496 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
5497 /* sx.val.i = constant */
5499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5502 M_SRL_IMM(iptr->sx.val.i, d);
5503 emit_store_dst(jd, iptr, d);
5506 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
5508 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
5509 s2 = emit_load_s2(jd, iptr, ECX);
5510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
5513 M_TEST_IMM(32, ECX);
5515 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
5516 M_CLR(GET_LOW_REG(d));
5517 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
5518 M_SLL(GET_LOW_REG(d));
5519 emit_store_dst(jd, iptr, d);
5522 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
5523 /* sx.val.i = constant */
5525 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5528 if (iptr->sx.val.i & 0x20) {
5529 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
5530 M_CLR(GET_LOW_REG(d));
5531 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
5534 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d), GET_HIGH_REG(d));
5535 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
5537 emit_store_dst(jd, iptr, d);
5540 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
5542 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
5543 s2 = emit_load_s2(jd, iptr, ECX);
5544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
5547 M_TEST_IMM(32, ECX);
5549 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5550 M_SRA_IMM(31, GET_HIGH_REG(d));
5551 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
5552 M_SRA(GET_HIGH_REG(d));
5553 emit_store_dst(jd, iptr, d);
5556 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
5557 /* sx.val.i = constant */
5559 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5562 if (iptr->sx.val.i & 0x20) {
5563 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5564 M_SRA_IMM(31, GET_HIGH_REG(d));
5565 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
5569 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
5571 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
5573 emit_store_dst(jd, iptr, d);
5576 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
5578 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
5579 s2 = emit_load_s2(jd, iptr, ECX);
5580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
5583 M_TEST_IMM(32, ECX);
5585 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5586 M_CLR(GET_HIGH_REG(d));
5587 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
5588 M_SRL(GET_HIGH_REG(d));
5589 emit_store_dst(jd, iptr, d);
5592 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
5593 /* sx.val.l = constant */
5595 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5598 if (iptr->sx.val.i & 0x20) {
5599 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
5600 M_CLR(GET_HIGH_REG(d));
5601 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
5605 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
5607 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
5609 emit_store_dst(jd, iptr, d);
5612 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
5614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5615 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5623 emit_store_dst(jd, iptr, d);
5626 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
5627 /* sx.val.i = constant */
5629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5632 M_AND_IMM(iptr->sx.val.i, d);
5633 emit_store_dst(jd, iptr, d);
5636 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
5638 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5639 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5641 if (s2 == GET_LOW_REG(d))
5642 M_AND(s1, GET_LOW_REG(d));
5644 M_INTMOVE(s1, GET_LOW_REG(d));
5645 M_AND(s2, GET_LOW_REG(d));
5647 /* REG_ITMP1 probably contains low 32-bit of destination */
5648 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5649 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5650 if (s2 == GET_HIGH_REG(d))
5651 M_AND(s1, GET_HIGH_REG(d));
5653 M_INTMOVE(s1, GET_HIGH_REG(d));
5654 M_AND(s2, GET_HIGH_REG(d));
5656 emit_store_dst(jd, iptr, d);
5659 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
5660 /* sx.val.l = constant */
5662 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5665 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5666 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5667 emit_store_dst(jd, iptr, d);
5670 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
5672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5681 emit_store_dst(jd, iptr, d);
5684 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
5685 /* sx.val.i = constant */
5687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5690 M_OR_IMM(iptr->sx.val.i, d);
5691 emit_store_dst(jd, iptr, d);
5694 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
5696 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5697 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5699 if (s2 == GET_LOW_REG(d))
5700 M_OR(s1, GET_LOW_REG(d));
5702 M_INTMOVE(s1, GET_LOW_REG(d));
5703 M_OR(s2, GET_LOW_REG(d));
5705 /* REG_ITMP1 probably contains low 32-bit of destination */
5706 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5707 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5708 if (s2 == GET_HIGH_REG(d))
5709 M_OR(s1, GET_HIGH_REG(d));
5711 M_INTMOVE(s1, GET_HIGH_REG(d));
5712 M_OR(s2, GET_HIGH_REG(d));
5714 emit_store_dst(jd, iptr, d);
5717 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
5718 /* sx.val.l = constant */
5720 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5723 M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5724 M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5725 emit_store_dst(jd, iptr, d);
5728 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
5730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
5732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
5739 emit_store_dst(jd, iptr, d);
5742 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
5743 /* sx.val.i = constant */
5745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
5746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
5748 M_XOR_IMM(iptr->sx.val.i, d);
5749 emit_store_dst(jd, iptr, d);
5752 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
5754 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
5755 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
5756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5757 if (s2 == GET_LOW_REG(d))
5758 M_XOR(s1, GET_LOW_REG(d));
5760 M_INTMOVE(s1, GET_LOW_REG(d));
5761 M_XOR(s2, GET_LOW_REG(d));
5763 /* REG_ITMP1 probably contains low 32-bit of destination */
5764 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
5765 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
5766 if (s2 == GET_HIGH_REG(d))
5767 M_XOR(s1, GET_HIGH_REG(d));
5769 M_INTMOVE(s1, GET_HIGH_REG(d));
5770 M_XOR(s2, GET_HIGH_REG(d));
5772 emit_store_dst(jd, iptr, d);
5775 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
5776 /* sx.val.l = constant */
5778 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
5779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
5781 M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
5782 M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
5783 emit_store_dst(jd, iptr, d);
5786 case ICMD_IINC: /* ..., value ==> ..., value + constant */
5787 /* s1.localindex = variable, sx.val.i = constant */
5789 #if defined(ENABLE_SSA)
5794 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
5795 var_t = &(rd->locals[iptr->val._i.op1_t][TYPE_INT]);
5797 /* set s1 to reg of destination or REG_ITMP1 */
5798 if (IS_INMEMORY(var_t->flags))
5803 /* move source value to s1 */
5804 if (IS_INMEMORY(var->flags))
5805 M_ILD( s1, REG_SP, var->regoff * 4);
5807 M_INTMOVE(var->regoff, s1);
5809 /* `inc reg' is slower on p4's (regarding to ia32
5810 optimization reference manual and benchmarks) and as
5811 fast on athlon's. */
5813 M_IADD_IMM(iptr->val._i.i, s1);
5815 if (IS_INMEMORY(var_t->flags))
5816 M_IST(s1, REG_SP, var_t->regoff * 4);
5819 #endif /* defined(ENABLE_SSA) */
5821 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
5822 if (IS_INMEMORY(var->flags)) {
5824 M_ILD(s1, REG_SP, var->regoff * 4);
5829 /* `inc reg' is slower on p4's (regarding to ia32
5830 optimization reference manual and benchmarks) and as
5831 fast on athlon's. */
5833 M_IADD_IMM(iptr->sx.val.i, s1);
5835 if (IS_INMEMORY(var->flags))
5836 M_IST(s1, REG_SP, var->regoff * 4);
5841 /* floating operations ************************************************/
5843 case ICMD_FNEG: /* ..., value ==> ..., - value */
5845 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5846 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5848 emit_store_dst(jd, iptr, d);
5851 case ICMD_DNEG: /* ..., value ==> ..., - value */
5853 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5854 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5856 emit_store_dst(jd, iptr, d);
5859 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
5861 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5862 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5863 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5865 emit_store_dst(jd, iptr, d);
5868 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
5870 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5871 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5872 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5874 emit_store_dst(jd, iptr, d);
5877 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
5879 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5880 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5881 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5883 emit_store_dst(jd, iptr, d);
5886 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
5888 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5889 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5890 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5892 emit_store_dst(jd, iptr, d);
5895 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
5897 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5898 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5899 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5901 emit_store_dst(jd, iptr, d);
5904 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
5906 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5907 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5908 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5910 emit_store_dst(jd, iptr, d);
5913 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
5915 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5916 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5917 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5919 emit_store_dst(jd, iptr, d);
5922 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
5924 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5925 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5926 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5928 emit_store_dst(jd, iptr, d);
5931 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
5933 /* exchanged to skip fxch */
5934 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5935 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5936 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5937 /* emit_fxch(cd); */
5942 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
5943 emit_store_dst(jd, iptr, d);
5944 emit_ffree_reg(cd, 0);
5948 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
5950 /* exchanged to skip fxch */
5951 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
5952 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5953 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
5954 /* emit_fxch(cd); */
5959 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
5960 emit_store_dst(jd, iptr, d);
5961 emit_ffree_reg(cd, 0);
5965 case ICMD_I2F: /* ..., value ==> ..., (float) value */
5966 case ICMD_I2D: /* ..., value ==> ..., (double) value */
5968 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
5969 if (IS_INMEMORY(iptr->s1.var->flags)) {
5970 emit_fildl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
5973 disp = dseg_adds4(cd, 0);
5974 emit_mov_imm_reg(cd, 0, REG_ITMP1);
5976 emit_mov_reg_membase(cd, iptr->s1.var->regoff, REG_ITMP1, disp);
5977 emit_fildl_membase(cd, REG_ITMP1, disp);
5979 emit_store_dst(jd, iptr, d);
5982 case ICMD_L2F: /* ..., value ==> ..., (float) value */
5983 case ICMD_L2D: /* ..., value ==> ..., (double) value */
5985 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
5986 if (IS_INMEMORY(iptr->s1.var->flags)) {
5987 emit_fildll_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
5990 log_text("L2F: longs have to be in memory");
5993 emit_store_dst(jd, iptr, d);
5996 case ICMD_F2I: /* ..., value ==> ..., (int) value */
5998 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
5999 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6001 emit_mov_imm_reg(cd, 0, REG_ITMP1);
6004 /* Round to zero, 53-bit mode, exception masked */
6005 disp = dseg_adds4(cd, 0x0e7f);
6006 emit_fldcw_membase(cd, REG_ITMP1, disp);
6008 if (IS_INMEMORY(iptr->dst.var->flags)) {
6009 emit_fistpl_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6011 /* Round to nearest, 53-bit mode, exceptions masked */
6012 disp = dseg_adds4(cd, 0x027f);
6013 emit_fldcw_membase(cd, REG_ITMP1, disp);
6015 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4);
6018 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6020 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6023 disp = dseg_adds4(cd, 0);
6024 emit_fistpl_membase(cd, REG_ITMP1, disp);
6025 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst.var->regoff);
6027 /* Round to nearest, 53-bit mode, exceptions masked */
6028 disp = dseg_adds4(cd, 0x027f);
6029 emit_fldcw_membase(cd, REG_ITMP1, disp);
6031 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst.var->regoff);
6034 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6035 disp += 5 + 2 + ((REG_RESULT == iptr->dst.var->regoff) ? 0 : 2);
6038 emit_jcc(cd, CC_NE, disp);
6040 /* XXX: change this when we use registers */
6041 emit_flds_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6042 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
6043 emit_call_reg(cd, REG_ITMP1);
6045 if (IS_INMEMORY(iptr->dst.var->flags)) {
6046 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6049 M_INTMOVE(REG_RESULT, iptr->dst.var->regoff);
6053 case ICMD_D2I: /* ..., value ==> ..., (int) value */
6055 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6056 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6058 emit_mov_imm_reg(cd, 0, REG_ITMP1);
6061 /* Round to zero, 53-bit mode, exception masked */
6062 disp = dseg_adds4(cd, 0x0e7f);
6063 emit_fldcw_membase(cd, REG_ITMP1, disp);
6065 if (IS_INMEMORY(iptr->dst.var->flags)) {
6066 emit_fistpl_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6068 /* Round to nearest, 53-bit mode, exceptions masked */
6069 disp = dseg_adds4(cd, 0x027f);
6070 emit_fldcw_membase(cd, REG_ITMP1, disp);
6072 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4);
6075 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6077 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6080 disp = dseg_adds4(cd, 0);
6081 emit_fistpl_membase(cd, REG_ITMP1, disp);
6082 emit_mov_membase_reg(cd, REG_ITMP1, disp, iptr->dst.var->regoff);
6084 /* Round to nearest, 53-bit mode, exceptions masked */
6085 disp = dseg_adds4(cd, 0x027f);
6086 emit_fldcw_membase(cd, REG_ITMP1, disp);
6088 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, iptr->dst.var->regoff);
6091 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6092 disp += 5 + 2 + ((REG_RESULT == iptr->dst.var->regoff) ? 0 : 2);
6095 emit_jcc(cd, CC_NE, disp);
6097 /* XXX: change this when we use registers */
6098 emit_fldl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6099 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
6100 emit_call_reg(cd, REG_ITMP1);
6102 if (IS_INMEMORY(iptr->dst.var->flags)) {
6103 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6105 M_INTMOVE(REG_RESULT, iptr->dst.var->regoff);
6109 case ICMD_F2L: /* ..., value ==> ..., (long) value */
6111 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6112 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6114 emit_mov_imm_reg(cd, 0, REG_ITMP1);
6117 /* Round to zero, 53-bit mode, exception masked */
6118 disp = dseg_adds4(cd, 0x0e7f);
6119 emit_fldcw_membase(cd, REG_ITMP1, disp);
6121 if (IS_INMEMORY(iptr->dst.var->flags)) {
6122 emit_fistpll_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6124 /* Round to nearest, 53-bit mode, exceptions masked */
6125 disp = dseg_adds4(cd, 0x027f);
6126 emit_fldcw_membase(cd, REG_ITMP1, disp);
6128 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4 + 4);
6131 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6133 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6136 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6138 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4 + 4);
6140 emit_jcc(cd, CC_NE, disp);
6142 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst.var->regoff * 4);
6145 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6147 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6149 emit_jcc(cd, CC_NE, disp);
6151 /* XXX: change this when we use registers */
6152 emit_flds_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6153 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
6154 emit_call_reg(cd, REG_ITMP1);
6155 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6156 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst.var->regoff * 4 + 4);
6159 log_text("F2L: longs have to be in memory");
6164 case ICMD_D2L: /* ..., value ==> ..., (long) value */
6166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6167 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
6169 emit_mov_imm_reg(cd, 0, REG_ITMP1);
6172 /* Round to zero, 53-bit mode, exception masked */
6173 disp = dseg_adds4(cd, 0x0e7f);
6174 emit_fldcw_membase(cd, REG_ITMP1, disp);
6176 if (IS_INMEMORY(iptr->dst.var->flags)) {
6177 emit_fistpll_membase(cd, REG_SP, iptr->dst.var->regoff * 4);
6179 /* Round to nearest, 53-bit mode, exceptions masked */
6180 disp = dseg_adds4(cd, 0x027f);
6181 emit_fldcw_membase(cd, REG_ITMP1, disp);
6183 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000, REG_SP, iptr->dst.var->regoff * 4 + 4);
6186 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6188 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6191 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6193 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4 + 4);
6195 emit_jcc(cd, CC_NE, disp);
6197 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->dst.var->regoff * 4);
6200 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->regoff * 4);
6202 CALCOFFSETBYTES(disp, REG_SP, iptr->dst.var->regoff * 4);
6204 emit_jcc(cd, CC_NE, disp);
6206 /* XXX: change this when we use registers */
6207 emit_fldl_membase(cd, REG_SP, iptr->s1.var->regoff * 4);
6208 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
6209 emit_call_reg(cd, REG_ITMP1);
6210 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, iptr->dst.var->regoff * 4);
6211 emit_mov_reg_membase(cd, REG_RESULT2, REG_SP, iptr->dst.var->regoff * 4 + 4);
6214 log_text("D2L: longs have to be in memory");
6219 case ICMD_F2D: /* ..., value ==> ..., (double) value */
6221 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6222 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
6224 emit_store_dst(jd, iptr, d);
6227 case ICMD_D2F: /* ..., value ==> ..., (float) value */
6229 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6230 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
6232 emit_store_dst(jd, iptr, d);
6235 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
6238 /* exchanged to skip fxch */
6239 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
6240 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
6241 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6242 /* emit_fxch(cd); */
6245 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
6246 emit_jcc(cd, CC_E, 6);
6247 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
6249 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
6250 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
6251 emit_jcc(cd, CC_B, 3 + 5);
6252 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
6253 emit_jmp_imm(cd, 3);
6254 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
6255 emit_store_dst(jd, iptr, d);
6258 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
6261 /* exchanged to skip fxch */
6262 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
6263 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
6264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6265 /* emit_fxch(cd); */
6268 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
6269 emit_jcc(cd, CC_E, 3);
6270 emit_movb_imm_reg(cd, 1, REG_AH);
6272 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
6273 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
6274 emit_jcc(cd, CC_B, 3 + 5);
6275 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
6276 emit_jmp_imm(cd, 3);
6277 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
6278 emit_store_dst(jd, iptr, d);
6282 /* memory operations **************************************************/
6284 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
6286 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6287 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6288 gen_nullptr_check(s1);
6289 M_ILD(d, s1, OFFSET(java_arrayheader, size));
6290 emit_store_dst(jd, iptr, d);
6293 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
6295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6296 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6297 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6298 if (INSTRUCTION_MUST_CHECK(iptr)) {
6299 gen_nullptr_check(s1);
6302 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
6303 emit_store_dst(jd, iptr, d);
6306 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
6308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6309 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6310 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6311 if (INSTRUCTION_MUST_CHECK(iptr)) {
6312 gen_nullptr_check(s1);
6315 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
6316 emit_store_dst(jd, iptr, d);
6319 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
6321 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6322 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6323 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6324 if (INSTRUCTION_MUST_CHECK(iptr)) {
6325 gen_nullptr_check(s1);
6328 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
6329 emit_store_dst(jd, iptr, d);
6332 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
6334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6337 if (INSTRUCTION_MUST_CHECK(iptr)) {
6338 gen_nullptr_check(s1);
6341 emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
6342 emit_store_dst(jd, iptr, d);
6345 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
6347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6348 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6349 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
6350 if (INSTRUCTION_MUST_CHECK(iptr)) {
6351 gen_nullptr_check(s1);
6354 assert(IS_INMEMORY(iptr->dst.var->flags));
6355 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, REG_ITMP3);
6356 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst.var->regoff * 4);
6357 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3, REG_ITMP3);
6358 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, iptr->dst.var->regoff * 4 + 4);
6361 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
6363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6365 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6366 if (INSTRUCTION_MUST_CHECK(iptr)) {
6367 gen_nullptr_check(s1);
6370 emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
6371 emit_store_dst(jd, iptr, d);
6374 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
6376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6377 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6378 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
6379 if (INSTRUCTION_MUST_CHECK(iptr)) {
6380 gen_nullptr_check(s1);
6383 emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
6384 emit_store_dst(jd, iptr, d);
6387 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
6389 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6390 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6391 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
6392 if (INSTRUCTION_MUST_CHECK(iptr)) {
6393 gen_nullptr_check(s1);
6396 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 2, d);
6397 emit_store_dst(jd, iptr, d);
6401 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
6403 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6404 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6405 if (INSTRUCTION_MUST_CHECK(iptr)) {
6406 gen_nullptr_check(s1);
6409 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6410 if (s3 >= EBP) { /* because EBP, ESI, EDI have no xH and xL nibbles */
6411 M_INTMOVE(s3, REG_ITMP3);
6414 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
6417 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
6419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6420 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6421 if (INSTRUCTION_MUST_CHECK(iptr)) {
6422 gen_nullptr_check(s1);
6425 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6426 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
6429 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
6431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6432 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6433 if (INSTRUCTION_MUST_CHECK(iptr)) {
6434 gen_nullptr_check(s1);
6437 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6438 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
6441 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
6443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6444 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6445 if (INSTRUCTION_MUST_CHECK(iptr)) {
6446 gen_nullptr_check(s1);
6449 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6450 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
6453 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
6455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6457 if (INSTRUCTION_MUST_CHECK(iptr)) {
6458 gen_nullptr_check(s1);
6461 assert(IS_INMEMORY(iptr->sx.s23.s3.var->flags));
6462 emit_mov_membase_reg(cd, REG_SP, iptr->sx.s23.s3.var->regoff * 4, REG_ITMP3);
6463 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]), s1, s2, 3);
6464 emit_mov_membase_reg(cd, REG_SP, iptr->sx.s23.s3.var->regoff * 4 + 4, REG_ITMP3);
6465 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
6468 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
6470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6471 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6472 if (INSTRUCTION_MUST_CHECK(iptr)) {
6473 gen_nullptr_check(s1);
6476 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
6477 emit_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
6480 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
6482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6484 if (INSTRUCTION_MUST_CHECK(iptr)) {
6485 gen_nullptr_check(s1);
6488 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
6489 emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3);
6492 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
6494 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6495 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6496 if (INSTRUCTION_MUST_CHECK(iptr)) {
6497 gen_nullptr_check(s1);
6500 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6502 M_AST(s1, REG_SP, 0 * 4);
6503 M_AST(s3, REG_SP, 1 * 4);
6504 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
6508 codegen_add_arraystoreexception_ref(cd);
6510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6512 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
6513 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 2);
6516 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
6518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6519 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6520 if (INSTRUCTION_MUST_CHECK(iptr)) {
6521 gen_nullptr_check(s1);
6524 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
6527 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
6529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6531 if (INSTRUCTION_MUST_CHECK(iptr)) {
6532 gen_nullptr_check(s1);
6535 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
6538 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
6540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6541 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6542 if (INSTRUCTION_MUST_CHECK(iptr)) {
6543 gen_nullptr_check(s1);
6546 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
6549 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
6551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6552 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6553 if (INSTRUCTION_MUST_CHECK(iptr)) {
6554 gen_nullptr_check(s1);
6557 emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
6560 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
6562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6563 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6564 if (INSTRUCTION_MUST_CHECK(iptr)) {
6565 gen_nullptr_check(s1);
6568 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
6569 emit_mov_imm_memindex(cd, ((s4)iptr->sx.s23.s3.constval) >> 31, OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
6572 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
6574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6575 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6576 if (INSTRUCTION_MUST_CHECK(iptr)) {
6577 gen_nullptr_check(s1);
6580 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 2);
6584 case ICMD_GETSTATIC: /* ... ==> ..., value */
6586 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6587 unresolved_field *uf = iptr->sx.s23.s3.uf;
6589 fieldtype = uf->fieldref->parseddesc.fd->type;
6591 codegen_addpatchref(cd, PATCHER_get_putstatic,
6592 iptr->sx.s23.s3.uf, 0);
6594 if (opt_showdisassemble) {
6595 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6602 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6604 fieldtype = fi->type;
6606 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
6607 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
6609 if (opt_showdisassemble) {
6610 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6614 disp = (ptrint) &(fi->value);
6617 M_MOV_IMM(disp, REG_ITMP1);
6618 switch (fieldtype) {
6621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
6622 M_ILD(d, REG_ITMP1, 0);
6625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
6626 M_LLD(d, REG_ITMP1, 0);
6629 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6630 M_FLD(d, REG_ITMP1, 0);
6633 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6634 M_DLD(d, REG_ITMP1, 0);
6637 emit_store_dst(jd, iptr, d);
6640 case ICMD_PUTSTATIC: /* ..., value ==> ... */
6642 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6643 unresolved_field *uf = iptr->sx.s23.s3.uf;
6645 fieldtype = uf->fieldref->parseddesc.fd->type;
6647 codegen_addpatchref(cd, PATCHER_get_putstatic,
6648 iptr->sx.s23.s3.uf, 0);
6650 if (opt_showdisassemble) {
6651 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6658 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6660 fieldtype = fi->type;
6662 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
6663 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
6665 if (opt_showdisassemble) {
6666 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6670 disp = (ptrint) &(fi->value);
6673 M_MOV_IMM(disp, REG_ITMP1);
6674 switch (fieldtype) {
6677 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
6678 M_IST(s1, REG_ITMP1, 0);
6681 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
6682 M_LST(s1, REG_ITMP1, 0);
6685 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6686 emit_fstps_membase(cd, REG_ITMP1, 0);
6689 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
6690 emit_fstpl_membase(cd, REG_ITMP1, 0);
6695 case ICMD_PUTSTATICCONST: /* ... ==> ... */
6696 /* val = value (in current instruction) */
6697 /* following NOP) */
6699 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6700 unresolved_field *uf = iptr->sx.s23.s3.uf;
6702 fieldtype = uf->fieldref->parseddesc.fd->type;
6704 codegen_addpatchref(cd, PATCHER_get_putstatic,
6707 if (opt_showdisassemble) {
6708 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6715 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6717 fieldtype = fi->type;
6719 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
6720 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
6722 if (opt_showdisassemble) {
6723 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6727 disp = (ptrint) &(fi->value);
6730 M_MOV_IMM(disp, REG_ITMP1);
6731 switch (fieldtype) {
6734 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
6737 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
6738 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
6745 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
6747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6748 gen_nullptr_check(s1);
6750 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6751 unresolved_field *uf = iptr->sx.s23.s3.uf;
6753 fieldtype = uf->fieldref->parseddesc.fd->type;
6755 codegen_addpatchref(cd, PATCHER_getfield,
6756 iptr->sx.s23.s3.uf, 0);
6758 if (opt_showdisassemble) {
6759 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6766 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6768 fieldtype = fi->type;
6772 switch (fieldtype) {
6775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
6776 M_ILD32(d, s1, disp);
6779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
6780 M_LLD32(d, s1, disp);
6783 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6784 M_FLD32(d, s1, disp);
6787 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
6788 M_DLD32(d, s1, disp);
6791 emit_store_dst(jd, iptr, d);
6794 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
6796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6797 gen_nullptr_check(s1);
6799 /* must be done here because of code patching */
6801 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6802 unresolved_field *uf = iptr->sx.s23.s3.uf;
6804 fieldtype = uf->fieldref->parseddesc.fd->type;
6807 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6809 fieldtype = fi->type;
6812 if (!IS_FLT_DBL_TYPE(fieldtype)) {
6813 if (IS_2_WORD_TYPE(fieldtype))
6814 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
6816 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
6819 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
6821 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6822 unresolved_field *uf = iptr->sx.s23.s3.uf;
6824 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
6826 if (opt_showdisassemble) {
6827 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6834 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6839 switch (fieldtype) {
6842 M_IST32(s2, s1, disp);
6845 M_LST32(s2, s1, disp);
6848 emit_fstps_membase32(cd, s1, disp);
6851 emit_fstpl_membase32(cd, s1, disp);
6856 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
6857 /* val = value (in current instruction) */
6858 /* following NOP) */
6860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6861 gen_nullptr_check(s1);
6863 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6864 unresolved_field *uf = iptr->sx.s23.s3.uf;
6866 fieldtype = uf->fieldref->parseddesc.fd->type;
6868 codegen_addpatchref(cd, PATCHER_putfieldconst,
6871 if (opt_showdisassemble) {
6872 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6880 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
6882 fieldtype = fi->type;
6887 switch (fieldtype) {
6890 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
6893 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
6894 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
6902 /* branch operations **************************************************/
6904 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
6906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6907 M_INTMOVE(s1, REG_ITMP1_XPTR);
6909 #ifdef ENABLE_VERIFIER
6910 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
6911 codegen_addpatchref(cd, PATCHER_athrow_areturn,
6912 iptr->sx.s23.s2.uc, 0);
6914 if (opt_showdisassemble) {
6915 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
6918 #endif /* ENABLE_VERIFIER */
6920 M_CALL_IMM(0); /* passing exception pc */
6921 M_POP(REG_ITMP2_XPC);
6923 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
6927 case ICMD_INLINE_GOTO:
6929 M_COPY(src, iptr->dst.var);
6933 case ICMD_GOTO: /* ... ==> ... */
6935 #if defined(ENABLE_SSA)
6937 last_cmd_was_goto = true;
6938 /* In case of a Goto phimoves have to be inserted before the */
6940 codegen_insert_phi_moves(cd, rd, ls, bptr);
6944 codegen_addreference(cd, iptr->dst.block);
6948 case ICMD_JSR: /* ... ==> ... */
6951 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
6954 case ICMD_RET: /* ... ==> ... */
6955 /* s1.localindex = local variable */
6957 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
6958 if (IS_INMEMORY(var->flags)) {
6959 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
6966 case ICMD_IFNULL: /* ..., value ==> ... */
6968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6971 codegen_addreference(cd, iptr->dst.block);
6974 case ICMD_IFNONNULL: /* ..., value ==> ... */
6976 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6979 codegen_addreference(cd, iptr->dst.block);
6982 case ICMD_IFEQ: /* ..., value ==> ... */
6984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6985 M_CMP_IMM(iptr->sx.val.i, s1);
6987 codegen_addreference(cd, iptr->dst.block);
6990 case ICMD_IFLT: /* ..., value ==> ... */
6992 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
6993 M_CMP_IMM(iptr->sx.val.i, s1);
6995 codegen_addreference(cd, iptr->dst.block);
6998 case ICMD_IFLE: /* ..., value ==> ... */
7000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7001 M_CMP_IMM(iptr->sx.val.i, s1);
7003 codegen_addreference(cd, iptr->dst.block);
7006 case ICMD_IFNE: /* ..., value ==> ... */
7008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7009 M_CMP_IMM(iptr->sx.val.i, s1);
7011 codegen_addreference(cd, iptr->dst.block);
7014 case ICMD_IFGT: /* ..., value ==> ... */
7016 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7017 M_CMP_IMM(iptr->sx.val.i, s1);
7019 codegen_addreference(cd, iptr->dst.block);
7022 case ICMD_IFGE: /* ..., value ==> ... */
7024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7025 M_CMP_IMM(iptr->sx.val.i, s1);
7027 codegen_addreference(cd, iptr->dst.block);
7030 case ICMD_IF_LEQ: /* ..., value ==> ... */
7032 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7033 if (iptr->sx.val.l == 0) {
7034 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
7035 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
7038 M_LNGMOVE(s1, REG_ITMP12_PACKED);
7039 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
7040 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
7041 M_OR(REG_ITMP2, REG_ITMP1);
7044 codegen_addreference(cd, iptr->dst.block);
7047 case ICMD_IF_LLT: /* ..., value ==> ... */
7049 if (iptr->sx.val.l == 0) {
7050 /* If high 32-bit are less than zero, then the 64-bits
7052 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7057 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7058 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7060 codegen_addreference(cd, iptr->dst.block);
7062 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7065 codegen_addreference(cd, iptr->dst.block);
7068 case ICMD_IF_LLE: /* ..., value ==> ... */
7070 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7071 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7073 codegen_addreference(cd, iptr->dst.block);
7075 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7077 codegen_addreference(cd, iptr->dst.block);
7080 case ICMD_IF_LNE: /* ..., value ==> ... */
7082 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7083 if (iptr->sx.val.l == 0) {
7084 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
7085 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
7088 M_LNGMOVE(s1, REG_ITMP12_PACKED);
7089 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
7090 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
7091 M_OR(REG_ITMP2, REG_ITMP1);
7094 codegen_addreference(cd, iptr->dst.block);
7097 case ICMD_IF_LGT: /* ..., value ==> ... */
7099 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7100 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7102 codegen_addreference(cd, iptr->dst.block);
7104 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7106 codegen_addreference(cd, iptr->dst.block);
7109 case ICMD_IF_LGE: /* ..., value ==> ... */
7111 if (iptr->sx.val.l == 0) {
7112 /* If high 32-bit are greater equal zero, then the
7114 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7119 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
7120 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
7122 codegen_addreference(cd, iptr->dst.block);
7124 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
7127 codegen_addreference(cd, iptr->dst.block);
7130 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
7131 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
7133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7134 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7137 codegen_addreference(cd, iptr->dst.block);
7140 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
7142 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7143 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7144 M_INTMOVE(s1, REG_ITMP1);
7145 M_XOR(s2, REG_ITMP1);
7146 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7147 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
7148 M_INTMOVE(s1, REG_ITMP2);
7149 M_XOR(s2, REG_ITMP2);
7150 M_OR(REG_ITMP1, REG_ITMP2);
7152 codegen_addreference(cd, iptr->dst.block);
7155 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
7156 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
7158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7159 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7162 codegen_addreference(cd, iptr->dst.block);
7165 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
7167 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7168 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7169 M_INTMOVE(s1, REG_ITMP1);
7170 M_XOR(s2, REG_ITMP1);
7171 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
7172 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
7173 M_INTMOVE(s1, REG_ITMP2);
7174 M_XOR(s2, REG_ITMP2);
7175 M_OR(REG_ITMP1, REG_ITMP2);
7177 codegen_addreference(cd, iptr->dst.block);
7180 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
7182 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7183 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7186 codegen_addreference(cd, iptr->dst.block);
7189 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
7191 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7192 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7195 codegen_addreference(cd, iptr->dst.block);
7196 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7197 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7201 codegen_addreference(cd, iptr->dst.block);
7204 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
7206 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7207 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7210 codegen_addreference(cd, iptr->dst.block);
7213 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
7215 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7216 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7219 codegen_addreference(cd, iptr->dst.block);
7220 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7221 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7225 codegen_addreference(cd, iptr->dst.block);
7228 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
7230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7231 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7234 codegen_addreference(cd, iptr->dst.block);
7237 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
7239 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7240 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7243 codegen_addreference(cd, iptr->dst.block);
7244 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7245 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7249 codegen_addreference(cd, iptr->dst.block);
7252 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
7254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7255 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
7258 codegen_addreference(cd, iptr->dst.block);
7261 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
7263 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
7264 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
7267 codegen_addreference(cd, iptr->dst.block);
7268 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
7269 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
7273 codegen_addreference(cd, iptr->dst.block);
7277 case ICMD_IRETURN: /* ..., retvalue ==> ... */
7279 s1 = emit_load_s1(jd, iptr, REG_RESULT);
7280 M_INTMOVE(s1, REG_RESULT);
7281 goto nowperformreturn;
7283 case ICMD_LRETURN: /* ..., retvalue ==> ... */
7285 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
7286 M_LNGMOVE(s1, REG_RESULT_PACKED);
7287 goto nowperformreturn;
7289 case ICMD_ARETURN: /* ..., retvalue ==> ... */
7291 s1 = emit_load_s1(jd, iptr, REG_RESULT);
7292 M_INTMOVE(s1, REG_RESULT);
7294 #ifdef ENABLE_VERIFIER
7295 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7296 codegen_addpatchref(cd, PATCHER_athrow_areturn,
7297 iptr->sx.s23.s2.uc, 0);
7299 if (opt_showdisassemble) {
7300 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7303 #endif /* ENABLE_VERIFIER */
7304 goto nowperformreturn;
7306 case ICMD_FRETURN: /* ..., retvalue ==> ... */
7309 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
7310 goto nowperformreturn;
7312 case ICMD_RETURN: /* ... ==> ... */
7318 p = cd->stackframesize;
7320 #if !defined(NDEBUG)
7321 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
7322 emit_verbosecall_exit(jd);
7325 #if defined(ENABLE_THREADS)
7326 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
7327 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
7329 /* we need to save the proper return value */
7330 switch (iptr->opc) {
7333 M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
7337 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
7341 emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
7345 emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
7349 M_AST(REG_ITMP2, REG_SP, 0);
7350 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
7353 /* and now restore the proper return value */
7354 switch (iptr->opc) {
7357 M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
7361 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
7365 emit_flds_membase(cd, REG_SP, rd->memuse * 4);
7369 emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
7375 /* restore saved registers */
7377 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
7378 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
7381 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
7383 emit_fldl_membase(cd, REG_SP, p * 4);
7384 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
7386 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
7389 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
7393 /* deallocate stack */
7395 if (cd->stackframesize)
7396 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
7403 case ICMD_TABLESWITCH: /* ..., index ==> ... */
7406 branch_target_t *table;
7408 table = iptr->dst.table;
7410 l = iptr->sx.s23.s2.tablelow;
7411 i = iptr->sx.s23.s3.tablehigh;
7413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7414 M_INTMOVE(s1, REG_ITMP1);
7417 M_ISUB_IMM(l, REG_ITMP1);
7422 M_CMP_IMM(i - 1, REG_ITMP1);
7425 codegen_addreference(cd, table[0].block); /* default target */
7427 /* build jump table top down and use address of lowest entry */
7432 dseg_addtarget(cd, table->block);
7436 /* length of dataseg after last dseg_addtarget is used
7439 M_MOV_IMM(0, REG_ITMP2);
7441 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
7447 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
7450 lookup_target_t *lookup;
7452 lookup = iptr->dst.lookup;
7454 i = iptr->sx.s23.s2.lookupcount;
7456 MCODECHECK((i<<2)+8);
7457 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7460 M_CMP_IMM(lookup->value, s1);
7462 codegen_addreference(cd, lookup->target.block);
7468 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
7472 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
7474 bte = iptr->sx.s23.s3.bte;
7478 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
7480 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
7481 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
7482 case ICMD_INVOKEINTERFACE:
7484 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7486 um = iptr->sx.s23.s3.um;
7487 md = um->methodref->parseddesc.md;
7490 lm = iptr->sx.s23.s3.fmiref->p.method;
7492 md = lm->parseddesc;
7496 s3 = md->paramcount;
7498 MCODECHECK((s3 << 1) + 64);
7500 /* copy arguments to registers or stack location */
7502 for (s3 = s3 - 1; s3 >= 0; s3--) {
7503 src = iptr->sx.s23.s2.args[s3];
7505 if (src->varkind == ARGVAR)
7508 if (IS_INT_LNG_TYPE(src->type)) {
7509 if (!md->params[s3].inmemory) {
7510 log_text("No integer argument registers available!");
7514 if (IS_2_WORD_TYPE(src->type)) {
7515 d = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
7516 M_LST(d, REG_SP, md->params[s3].regoff * 4);
7519 d = emit_load(jd, iptr, src, REG_ITMP1);
7520 M_IST(d, REG_SP, md->params[s3].regoff * 4);
7525 if (!md->params[s3].inmemory) {
7526 s1 = rd->argfltregs[md->params[s3].regoff];
7527 d = emit_load(jd, iptr, src, s1);
7531 d = emit_load(jd, iptr, src, REG_FTMP1);
7532 if (IS_2_WORD_TYPE(src->type))
7533 M_DST(d, REG_SP, md->params[s3].regoff * 4);
7535 M_FST(d, REG_SP, md->params[s3].regoff * 4);
7540 switch (iptr->opc) {
7542 M_MOV_IMM(bte->fp, REG_ITMP1);
7545 if (INSTRUCTION_MUST_CHECK(iptr)) {
7548 codegen_add_fillinstacktrace_ref(cd);
7552 case ICMD_INVOKESPECIAL:
7553 M_ALD(REG_ITMP1, REG_SP, 0);
7556 codegen_add_nullpointerexception_ref(cd);
7560 case ICMD_INVOKESTATIC:
7562 codegen_addpatchref(cd, PATCHER_invokestatic_special,
7565 if (opt_showdisassemble) {
7566 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7572 disp = (ptrint) lm->stubroutine;
7574 M_MOV_IMM(disp, REG_ITMP2);
7578 case ICMD_INVOKEVIRTUAL:
7579 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
7580 gen_nullptr_check(REG_ITMP1);
7583 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
7585 if (opt_showdisassemble) {
7586 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7592 s1 = OFFSET(vftbl_t, table[0]) +
7593 sizeof(methodptr) * lm->vftblindex;
7595 M_ALD(REG_METHODPTR, REG_ITMP1,
7596 OFFSET(java_objectheader, vftbl));
7597 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
7601 case ICMD_INVOKEINTERFACE:
7602 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
7603 gen_nullptr_check(REG_ITMP1);
7606 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
7608 if (opt_showdisassemble) {
7609 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7616 s1 = OFFSET(vftbl_t, interfacetable[0]) -
7617 sizeof(methodptr) * lm->class->index;
7619 s2 = sizeof(methodptr) * (lm - lm->class->methods);
7622 M_ALD(REG_METHODPTR, REG_ITMP1,
7623 OFFSET(java_objectheader, vftbl));
7624 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
7625 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
7630 /* store return value */
7632 d = md->returntype.type;
7634 if (d != TYPE_VOID) {
7635 #if defined(ENABLE_SSA)
7636 if ((ls == NULL) || (iptr->dst->varkind != TEMPVAR) ||
7637 (ls->lifetime[-iptr->dst->varnum-1].type != -1))
7638 /* a "living" stackslot */
7641 if (IS_INT_LNG_TYPE(d)) {
7642 if (IS_2_WORD_TYPE(d)) {
7643 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
7644 M_LNGMOVE(REG_RESULT_PACKED, s1);
7647 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
7648 M_INTMOVE(REG_RESULT, s1);
7652 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
7654 emit_store_dst(jd, iptr, s1);
7660 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
7661 /* val.a: (classinfo*) superclass */
7663 /* superclass is an interface:
7665 * OK if ((sub == NULL) ||
7666 * (sub->vftbl->interfacetablelength > super->index) &&
7667 * (sub->vftbl->interfacetable[-super->index] != NULL));
7669 * superclass is a class:
7671 * OK if ((sub == NULL) || (0
7672 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
7673 * super->vftbl->diffval));
7676 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
7677 /* object type cast-check */
7680 vftbl_t *supervftbl;
7683 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7689 super = iptr->sx.s23.s3.c.cls;
7690 superindex = super->index;
7691 supervftbl = super->vftbl;
7694 #if defined(ENABLE_THREADS)
7695 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
7697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7699 /* calculate interface checkcast code size */
7701 s2 = 2; /* mov_membase_reg */
7702 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
7704 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* sub imm32 */ +
7705 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
7706 2 /* test */ + 6 /* jcc */);
7709 s2 += (opt_showdisassemble ? 5 : 0);
7711 /* calculate class checkcast code size */
7713 s3 = 2; /* mov_membase_reg */
7714 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
7716 s3 += 5 /* mov_imm_reg */ + 2 + 4 /* mov_membase32_reg */;
7719 if (s1 != REG_ITMP1) {
7721 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
7724 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
7731 s3 += (2 + 4 /* mov_membase32_reg */ + 2 /* sub */ +
7732 5 /* mov_imm_reg */ + 2 /* mov_membase_reg */);
7733 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
7736 s3 += 2 /* cmp */ + 6 /* jcc */;
7739 s3 += (opt_showdisassemble ? 5 : 0);
7741 /* if class is not resolved, check which code to call */
7743 if (super == NULL) {
7745 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
7747 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
7748 iptr->sx.s23.s3.c.ref, 0);
7750 if (opt_showdisassemble) {
7751 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7754 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
7755 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
7759 /* interface checkcast code */
7761 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
7762 if (super != NULL) {
7767 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
7769 if (super == NULL) {
7770 codegen_addpatchref(cd,
7771 PATCHER_checkcast_instanceof_interface,
7772 iptr->sx.s23.s3.c.ref,
7775 if (opt_showdisassemble) {
7776 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7781 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
7782 M_ISUB_IMM32(superindex, REG_ITMP3);
7785 codegen_add_classcastexception_ref(cd, s1);
7786 M_ALD32(REG_ITMP3, REG_ITMP2,
7787 OFFSET(vftbl_t, interfacetable[0]) -
7788 superindex * sizeof(methodptr*));
7791 codegen_add_classcastexception_ref(cd, s1);
7797 /* class checkcast code */
7799 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
7800 if (super != NULL) {
7805 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
7807 if (super == NULL) {
7808 codegen_addpatchref(cd, PATCHER_checkcast_class,
7809 iptr->sx.s23.s3.c.ref,
7812 if (opt_showdisassemble) {
7813 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7817 M_MOV_IMM(supervftbl, REG_ITMP3);
7818 #if defined(ENABLE_THREADS)
7819 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
7821 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
7823 /* if (s1 != REG_ITMP1) { */
7824 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
7825 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
7826 /* #if defined(ENABLE_THREADS) */
7827 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
7829 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
7832 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
7833 M_ISUB(REG_ITMP3, REG_ITMP2);
7834 M_MOV_IMM(supervftbl, REG_ITMP3);
7835 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
7836 #if defined(ENABLE_THREADS)
7837 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
7841 M_CMP(REG_ITMP3, REG_ITMP2);
7842 M_BA(0); /* (u) REG_ITMP2 > (u) REG_ITMP3 -> jump */
7843 codegen_add_classcastexception_ref(cd, s1);
7846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
7849 /* array type cast-check */
7851 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
7852 M_AST(s1, REG_SP, 0 * 4);
7854 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7855 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
7856 iptr->sx.s23.s3.c.ref, 0);
7858 if (opt_showdisassemble) {
7859 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7863 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
7864 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
7867 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
7870 codegen_add_classcastexception_ref(cd, s1);
7872 d = codegen_reg_of_dst(jd, iptr, s1);
7876 emit_store_dst(jd, iptr, d);
7879 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
7880 /* val.a: (classinfo*) superclass */
7882 /* superclass is an interface:
7884 * return (sub != NULL) &&
7885 * (sub->vftbl->interfacetablelength > super->index) &&
7886 * (sub->vftbl->interfacetable[-super->index] != NULL);
7888 * superclass is a class:
7890 * return ((sub != NULL) && (0
7891 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
7892 * super->vftbl->diffvall));
7897 vftbl_t *supervftbl;
7900 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
7906 super = iptr->sx.s23.s3.c.cls;
7907 superindex = super->index;
7908 supervftbl = super->vftbl;
7911 #if defined(ENABLE_THREADS)
7912 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
7915 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
7916 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
7918 M_INTMOVE(s1, REG_ITMP1);
7922 /* calculate interface instanceof code size */
7924 s2 = 2; /* mov_membase_reg */
7925 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
7927 s2 += (2 + 4 /* mov_membase32_reg */ + 2 + 4 /* alu_imm32_reg */ +
7928 2 /* test */ + 6 /* jcc */ + 2 + 4 /* mov_membase32_reg */ +
7929 2 /* test */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
7932 s2 += (opt_showdisassemble ? 5 : 0);
7934 /* calculate class instanceof code size */
7936 s3 = 2; /* mov_membase_reg */
7937 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
7938 s3 += 5; /* mov_imm_reg */
7940 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
7942 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
7944 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
7946 s3 += (2 /* alu_reg_reg */ + 2 /* alu_reg_reg */ +
7947 2 /* alu_reg_reg */ + 6 /* jcc */ + 5 /* mov_imm_reg */);
7950 s3 += (opt_showdisassemble ? 5 : 0);
7954 /* if class is not resolved, check which code to call */
7958 M_BEQ(5 + (opt_showdisassemble ? 5 : 0) + 6 + 6 + s2 + 5 + s3);
7960 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
7961 iptr->sx.s23.s3.c.ref, 0);
7963 if (opt_showdisassemble) {
7964 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7967 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
7968 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
7972 /* interface instanceof code */
7974 if (!super || (super->flags & ACC_INTERFACE)) {
7980 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
7983 codegen_addpatchref(cd,
7984 PATCHER_checkcast_instanceof_interface,
7985 iptr->sx.s23.s3.c.ref, 0);
7987 if (opt_showdisassemble) {
7988 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
7993 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
7994 M_ISUB_IMM32(superindex, REG_ITMP3);
7997 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
7998 6 /* jcc */ + 5 /* mov_imm_reg */);
8001 M_ALD32(REG_ITMP1, REG_ITMP1,
8002 OFFSET(vftbl_t, interfacetable[0]) -
8003 superindex * sizeof(methodptr*));
8005 /* emit_setcc_reg(cd, CC_A, d); */
8006 /* emit_jcc(cd, CC_BE, 5); */
8014 /* class instanceof code */
8016 if (!super || !(super->flags & ACC_INTERFACE)) {
8022 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
8025 codegen_addpatchref(cd, PATCHER_instanceof_class,
8026 iptr->sx.s23.s3.c.ref, 0);
8028 if (opt_showdisassemble) {
8029 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
8033 M_MOV_IMM(supervftbl, REG_ITMP2);
8034 #if defined(ENABLE_THREADS)
8035 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
8037 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
8038 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
8039 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
8040 #if defined(ENABLE_THREADS)
8041 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
8043 M_ISUB(REG_ITMP2, REG_ITMP1);
8044 M_CLR(d); /* may be REG_ITMP2 */
8045 M_CMP(REG_ITMP3, REG_ITMP1);
8049 emit_store_dst(jd, iptr, d);
8055 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
8057 /* check for negative sizes and copy sizes to stack if necessary */
8059 MCODECHECK((iptr->s1.argcount << 1) + 64);
8061 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
8062 /* copy SAVEDVAR sizes to stack */
8063 src = iptr->sx.s23.s2.args[s1];
8065 if (src->varkind != ARGVAR) {
8066 if (IS_INMEMORY(src->flags)) {
8067 M_ILD(REG_ITMP1, REG_SP, src->regoff * 4);
8068 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
8071 M_IST(src->regoff, REG_SP, (s1 + 3) * 4);
8075 /* is a patcher function set? */
8077 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
8078 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
8079 iptr->sx.s23.s3.c.ref, 0);
8081 if (opt_showdisassemble) {
8082 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
8089 disp = (ptrint) iptr->sx.s23.s3.c.cls;
8091 /* a0 = dimension count */
8093 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
8095 /* a1 = arraydescriptor */
8097 M_IST_IMM(disp, REG_SP, 1 * 4);
8099 /* a2 = pointer to dimensions = stack pointer */
8101 M_MOV(REG_SP, REG_ITMP1);
8102 M_AADD_IMM(3 * 4, REG_ITMP1);
8103 M_AST(REG_ITMP1, REG_SP, 2 * 4);
8105 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
8108 /* check for exception before result assignment */
8112 codegen_add_fillinstacktrace_ref(cd);
8114 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
8115 M_INTMOVE(REG_RESULT, s1);
8116 emit_store_dst(jd, iptr, s1);
8121 new_internalerror("Unknown ICMD %d", iptr->opc);
8125 } /* for instruction */
8127 /* copy values to interface registers */
8129 len = bptr->outdepth;
8131 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
8134 #if defined(ENABLE_SSA)
8136 /* by edge splitting, in Blocks with phi moves there can only */
8137 /* be a goto as last command, no other Jump/Branch Command */
8138 if (!last_cmd_was_goto)
8139 codegen_insert_phi_moves(cd, rd, ls, bptr);
8141 #if !defined(NEW_VAR)
8145 #if !defined(NEW_VAR)
8148 src = bptr->outvars[len];
8149 if ((src->varkind != STACKVAR)) {
8151 if (IS_FLT_DBL_TYPE(s2)) {
8152 s1 = emit_load(jd, iptr, src, REG_FTMP1);
8153 if (!IS_INMEMORY(rd->interfaces[len][s2].flags))
8154 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
8156 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
8159 if (IS_2_WORD_TYPE(s2))
8161 /* s1 = emit_load(jd, iptr, src,
8162 PACK_REGS(REG_ITMP1, REG_ITMP2)); */
8164 s1 = emit_load(jd, iptr, src, REG_ITMP1);
8166 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
8167 if (IS_2_WORD_TYPE(s2))
8168 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
8170 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
8173 if (IS_2_WORD_TYPE(s2))
8174 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
8176 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
8184 /* At the end of a basic block we may have to append some nops,
8185 because the patcher stub calling code might be longer than the
8186 actual instruction. So codepatching does not change the
8187 following block unintentionally. */
8189 if (cd->mcodeptr < cd->lastmcodeptr) {
8190 while (cd->mcodeptr < cd->lastmcodeptr) {
8195 } /* if (bptr -> flags >= BBREACHED) */
8196 } /* for basic block */
8198 dseg_createlinenumbertable(cd);
8201 /* generate exception and patcher stubs */
8203 emit_exception_stubs(jd);
8204 emit_patcher_stubs(jd);
8206 emit_replacement_stubs(jd);
8211 /* everything's ok */
8215 #endif /* defined(NEW_VAR) */
8217 #if defined(ENABLE_SSA)
8218 void codegen_insert_phi_moves(codegendata *cd, registerdata *rd, lsradata *ls, basicblock *bptr) {
8219 /* look for phi moves */
8220 int t_a,s_a,i, type;
8221 int t_lt, s_lt; /* lifetime indices of phi_moves */
8222 bool t_inmemory, s_inmemory;
8223 s4 t_regoff, s_regoff, s_flags, t_flags;
8226 /* Moves from phi functions with highest indices have to be */
8227 /* inserted first, since this is the order as is used for */
8228 /* conflict resolution */
8229 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
8230 t_a = ls->phi_moves[bptr->nr][i][0];
8231 s_a = ls->phi_moves[bptr->nr][i][1];
8232 #if defined(SSA_DEBUG_VERBOSE)
8234 printf("BB %3i Move %3i <- %3i ",bptr->nr,t_a,s_a);
8237 /* local var lifetimes */
8238 t_lt = ls->maxlifetimes + t_a;
8239 type = ls->lifetime[t_lt].type;
8242 type = ls->lifetime[t_lt].local_ss->s->type;
8243 /* stackslot lifetime */
8246 #if defined(SSA_DEBUG_VERBOSE)
8248 printf("...returning - phi lifetimes where joined\n");
8253 /* local var lifetimes */
8254 s_lt = ls->maxlifetimes + s_a;
8255 type = ls->lifetime[s_lt].type;
8258 type = ls->lifetime[s_lt].type;
8259 /* stackslot lifetime */
8262 #if defined(SSA_DEBUG_VERBOSE)
8264 printf("...returning - phi lifetimes where joined\n");
8270 t_inmemory = rd->locals[t_a][type].flags & INMEMORY;
8271 t_flags = rd->locals[t_a][type].flags;
8272 t_regoff = rd->locals[t_a][type].regoff;
8275 t_inmemory = ls->lifetime[t_lt].local_ss->s->flags & INMEMORY;
8276 t_flags = ls->lifetime[t_lt].local_ss->s->flags;
8277 t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
8281 /* local var move */
8283 s_inmemory = rd->locals[s_a][type].flags & INMEMORY;
8284 s_flags = rd->locals[s_a][type].flags;
8285 s_regoff = rd->locals[s_a][type].regoff;
8287 /* stackslot lifetime */
8288 s_inmemory = ls->lifetime[s_lt].local_ss->s->flags & INMEMORY;
8289 s_flags = ls->lifetime[s_lt].local_ss->s->flags;
8290 s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
8293 #if defined(SSA_DEBUG_VERBOSE)
8295 printf("...returning - phi lifetimes where joined\n");
8300 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
8302 #if defined(SSA_DEBUG_VERBOSE)
8303 if (compileverbose) {
8304 if ((t_inmemory) && (s_inmemory)) {
8306 printf("M%3i <- M%3i",t_regoff,s_regoff);
8307 } else if (s_inmemory) {
8309 printf("R%3i <- M%3i",t_regoff,s_regoff);
8310 } else if (t_inmemory) {
8312 printf("M%3i <- R%3i",t_regoff,s_regoff);
8315 printf("R%3i <- R%3i",t_regoff,s_regoff);
8319 #endif /* defined(SSA_DEBUG_VERBOSE) */
8323 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
8324 s4 dst_regoff, s4 dst_flags) {
8325 if ((IS_INMEMORY(dst_flags)) && (IS_INMEMORY(src_flags))) {
8327 if (dst_regoff != src_regoff) {
8328 if (!IS_2_WORD_TYPE(type)) {
8329 if (IS_FLT_DBL_TYPE(type)) {
8330 emit_flds_membase(cd, REG_SP, src_regoff * 4);
8331 emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
8333 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
8335 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
8337 } else { /* LONG OR DOUBLE */
8338 if (IS_FLT_DBL_TYPE(type)) {
8339 emit_fldl_membase( cd, REG_SP, src_regoff * 4);
8340 emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
8342 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
8344 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
8345 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
8347 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP,
8348 dst_regoff * 4 + 4);
8353 if (IS_FLT_DBL_TYPE(type)) {
8354 log_text("cg_move: flt/dbl type have to be in memory\n");
8357 if (IS_2_WORD_TYPE(type)) {
8358 log_text("cg_move: longs have to be in memory\n");
8361 if (IS_INMEMORY(src_flags)) {
8363 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
8364 } else if (IS_INMEMORY(dst_flags)) {
8366 emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
8369 /* only ints can be in regs on i386 */
8370 M_INTMOVE(src_regoff,dst_regoff);
8374 #endif /* defined(ENABLE_SSA) */
8376 /* createcompilerstub **********************************************************
8378 Creates a stub routine which calls the compiler.
8380 *******************************************************************************/
8382 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
8383 #define COMPILERSTUB_CODESIZE 12
8385 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
8388 u1 *createcompilerstub(methodinfo *m)
8390 u1 *s; /* memory to hold the stub */
8396 s = CNEW(u1, COMPILERSTUB_SIZE);
8398 /* set data pointer and code pointer */
8401 s = s + COMPILERSTUB_DATASIZE;
8403 /* mark start of dump memory area */
8405 dumpsize = dump_size();
8407 cd = DNEW(codegendata);
8410 /* Store the codeinfo pointer in the same place as in the
8411 methodheader for compiled methods. */
8413 code = code_codeinfo_new(m);
8415 d[0] = (ptrint) asm_call_jit_compiler;
8417 d[2] = (ptrint) code;
8419 /* code for the stub */
8421 M_MOV_IMM(m, REG_ITMP1); /* method info */
8422 M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
8425 #if defined(ENABLE_STATISTICS)
8427 count_cstub_len += COMPILERSTUB_SIZE;
8430 /* release dump area */
8432 dump_release(dumpsize);
8438 /* createnativestub ************************************************************
8440 Creates a stub routine which calls a native method.
8442 *******************************************************************************/
8444 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
8452 s4 i, j; /* count variables */
8456 /* get required compiler data */
8463 /* set some variables */
8466 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
8468 /* calculate stackframe size */
8470 cd->stackframesize =
8471 sizeof(stackframeinfo) / SIZEOF_VOID_P +
8472 sizeof(localref_table) / SIZEOF_VOID_P +
8473 1 + /* function pointer */
8474 4 * 4 + /* 4 arguments (start_native_call) */
8477 /* keep stack 16-byte aligned */
8479 cd->stackframesize |= 0x3;
8481 /* create method header */
8483 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
8484 (void) dseg_adds4(cd, cd->stackframesize * 4); /* FrameSize */
8485 (void) dseg_adds4(cd, 0); /* IsSync */
8486 (void) dseg_adds4(cd, 0); /* IsLeaf */
8487 (void) dseg_adds4(cd, 0); /* IntSave */
8488 (void) dseg_adds4(cd, 0); /* FltSave */
8489 (void) dseg_addlinenumbertablesize(cd);
8490 (void) dseg_adds4(cd, 0); /* ExTableSize */
8492 /* generate native method profiling code */
8494 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
8495 /* count frequency */
8497 M_MOV_IMM(code, REG_ITMP1);
8498 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
8501 /* calculate stackframe size for native function */
8503 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
8505 #if !defined(NDEBUG)
8506 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
8507 emit_verbosecall_enter(jd);
8510 /* get function address (this must happen before the stackframeinfo) */
8512 #if !defined(WITH_STATIC_CLASSPATH)
8514 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
8516 if (opt_showdisassemble) {
8517 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
8522 M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
8524 /* Mark the whole fpu stack as free for native functions (only for saved */
8525 /* register count == 0). */
8527 emit_ffree_reg(cd, 0);
8528 emit_ffree_reg(cd, 1);
8529 emit_ffree_reg(cd, 2);
8530 emit_ffree_reg(cd, 3);
8531 emit_ffree_reg(cd, 4);
8532 emit_ffree_reg(cd, 5);
8533 emit_ffree_reg(cd, 6);
8534 emit_ffree_reg(cd, 7);
8536 /* prepare data structures for native function call */
8538 M_MOV(REG_SP, REG_ITMP1);
8539 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
8541 M_AST(REG_ITMP1, REG_SP, 0 * 4);
8542 M_IST_IMM(0, REG_SP, 1 * 4);
8545 M_MOV(REG_SP, REG_ITMP2);
8546 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
8548 M_AST(REG_ITMP2, REG_SP, 2 * 4);
8549 M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
8550 M_AST(REG_ITMP3, REG_SP, 3 * 4);
8551 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
8554 M_ALD(REG_ITMP3, REG_SP, 4 * 4);
8556 /* copy arguments into new stackframe */
8558 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
8559 t = md->paramtypes[i].type;
8561 if (!md->params[i].inmemory) {
8562 /* no integer argument registers */
8563 } else { /* float/double in memory can be copied like int/longs */
8564 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
8565 s2 = nmd->params[j].regoff * 4;
8567 M_ILD(REG_ITMP1, REG_SP, s1);
8568 M_IST(REG_ITMP1, REG_SP, s2);
8569 if (IS_2_WORD_TYPE(t)) {
8570 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
8571 M_IST(REG_ITMP1, REG_SP, s2 + 4);
8576 /* if function is static, put class into second argument */
8578 if (m->flags & ACC_STATIC)
8579 M_AST_IMM(m->class, REG_SP, 1 * 4);
8581 /* put env into first argument */
8583 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
8585 /* call the native function */
8589 /* save return value */
8591 if (md->returntype.type != TYPE_VOID) {
8592 if (IS_INT_LNG_TYPE(md->returntype.type)) {
8593 if (IS_2_WORD_TYPE(md->returntype.type))
8594 M_IST(REG_RESULT2, REG_SP, 2 * 4);
8595 M_IST(REG_RESULT, REG_SP, 1 * 4);
8598 if (IS_2_WORD_TYPE(md->returntype.type))
8599 emit_fstl_membase(cd, REG_SP, 1 * 4);
8601 emit_fsts_membase(cd, REG_SP, 1 * 4);
8605 #if !defined(NDEBUG)
8606 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
8607 emit_verbosecall_exit(jd);
8610 /* remove native stackframe info */
8612 M_MOV(REG_SP, REG_ITMP1);
8613 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
8615 M_AST(REG_ITMP1, REG_SP, 0 * 4);
8616 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
8618 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
8620 /* restore return value */
8622 if (md->returntype.type != TYPE_VOID) {
8623 if (IS_INT_LNG_TYPE(md->returntype.type)) {
8624 if (IS_2_WORD_TYPE(md->returntype.type))
8625 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
8626 M_ILD(REG_RESULT, REG_SP, 1 * 4);
8629 if (IS_2_WORD_TYPE(md->returntype.type))
8630 emit_fldl_membase(cd, REG_SP, 1 * 4);
8632 emit_flds_membase(cd, REG_SP, 1 * 4);
8636 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
8638 /* check for exception */
8645 /* handle exception */
8647 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
8648 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
8649 M_ASUB_IMM(2, REG_ITMP2_XPC);
8651 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
8655 /* generate patcher stubs */
8657 emit_patcher_stubs(jd);
8661 return code->entrypoint;
8666 * These are local overrides for various environment variables in Emacs.
8667 * Please do not remove this and leave it at the end of the file, where
8668 * Emacs will automagically detect them.
8669 * ---------------------------------------------------------------------
8672 * indent-tabs-mode: t
8676 * vim:noexpandtab:sw=4:ts=4: