1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "vm/jit/x86_64/arch.h"
37 #include "vm/jit/x86_64/codegen.h"
38 #include "vm/jit/x86_64/emit.h"
40 #include "mm/memory.h"
42 #include "native/localref.hpp"
43 #include "native/native.hpp"
45 #include "threads/lock.hpp"
47 #include "vm/jit/builtin.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/global.h"
50 #include "vm/loader.hpp"
51 #include "vm/options.h"
52 #include "vm/primitive.hpp"
53 #include "vm/statistics.h"
54 #include "vm/string.hpp"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/code.hpp"
60 #include "vm/jit/codegen-common.hpp"
61 #include "vm/jit/dseg.h"
62 #include "vm/jit/emit-common.hpp"
63 #include "vm/jit/jit.hpp"
64 #include "vm/jit/linenumbertable.hpp"
65 #include "vm/jit/methodheader.h"
66 #include "vm/jit/parse.hpp"
67 #include "vm/jit/patcher-common.hpp"
68 #include "vm/jit/reg.h"
69 #include "vm/jit/replace.hpp"
70 #include "vm/jit/stacktrace.hpp"
71 #include "vm/jit/trap.h"
73 #if defined(ENABLE_LSRA)
74 # include "vm/jit/allocator/lsra.h"
78 /* codegen_emit ****************************************************************
80 Generates machine code.
82 *******************************************************************************/
84 bool codegen_emit(jitdata *jd)
90 s4 len, s1, s2, s3, d, disp;
96 constant_classref *cr;
98 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
99 unresolved_method *um;
100 builtintable_entry *bte;
103 unresolved_field *uf;
107 /* get required compiler data */
114 /* prevent compiler warnings */
127 /* space to save used callee saved registers */
129 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
130 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
132 cd->stackframesize = rd->memuse + savedregs_num;
134 #if defined(ENABLE_THREADS)
135 /* space to save argument of monitor_enter */
137 if (checksync && code_is_synchronized(code))
138 cd->stackframesize++;
141 /* Keep stack of non-leaf functions 16-byte aligned for calls into
142 native code e.g. libc or jni (alignment problems with
145 if (!code_is_leafmethod(code) || opt_verbosecall)
146 cd->stackframesize |= 0x1;
148 /* create method header */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 code->synchronizedoffset = rd->memuse * 8;
155 if (code_is_leafmethod(code))
156 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
158 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
160 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
161 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
163 #if defined(ENABLE_PROFILING)
164 /* generate method profiling code */
166 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
167 /* count frequency */
169 M_MOV_IMM(code, REG_ITMP3);
170 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
176 /* create stack frame (if necessary) */
178 if (cd->stackframesize)
179 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
181 /* save used callee saved registers */
183 p = cd->stackframesize;
184 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
185 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
187 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
188 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
191 /* take arguments out of register or stack frame */
195 for (p = 0, l = 0; p < md->paramcount; p++) {
196 t = md->paramtypes[p].type;
198 varindex = jd->local_map[l * 5 + t];
201 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
204 if (varindex == UNUSED)
209 s1 = md->params[p].regoff;
211 if (IS_INT_LNG_TYPE(t)) { /* integer args */
212 if (!md->params[p].inmemory) { /* register arguments */
213 if (!IS_INMEMORY(var->flags))
214 M_INTMOVE(s1, var->vv.regoff);
216 M_LST(s1, REG_SP, var->vv.regoff);
218 else { /* stack arguments */
219 if (!IS_INMEMORY(var->flags))
220 /* + 8 for return address */
221 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
223 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
226 else { /* floating args */
227 if (!md->params[p].inmemory) { /* register arguments */
228 if (!IS_INMEMORY(var->flags))
229 M_FLTMOVE(s1, var->vv.regoff);
231 M_DST(s1, REG_SP, var->vv.regoff);
233 else { /* stack arguments */
234 if (!IS_INMEMORY(var->flags))
235 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
237 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
242 /* save monitorenter argument */
244 #if defined(ENABLE_THREADS)
245 if (checksync && code_is_synchronized(code)) {
246 /* stack offset for monitor argument */
250 if (opt_verbosecall) {
251 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
253 for (p = 0; p < INT_ARG_CNT; p++)
254 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
256 for (p = 0; p < FLT_ARG_CNT; p++)
257 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
259 s1 += INT_ARG_CNT + FLT_ARG_CNT;
262 /* decide which monitor enter function to call */
264 if (m->flags & ACC_STATIC) {
265 M_MOV_IMM(&m->clazz->object.header, REG_A0);
270 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
273 M_AST(REG_A0, REG_SP, s1 * 8);
274 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
277 if (opt_verbosecall) {
278 for (p = 0; p < INT_ARG_CNT; p++)
279 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
281 for (p = 0; p < FLT_ARG_CNT; p++)
282 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
284 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
290 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
291 emit_verbosecall_enter(jd);
292 #endif /* !defined(NDEBUG) */
296 /* end of header generation */
298 /* create replacement points */
300 REPLACEMENT_POINTS_INIT(cd, jd);
302 /* walk through all basic blocks */
304 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
306 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
308 if (bptr->flags >= BBREACHED) {
310 /* branch resolving */
312 codegen_resolve_branchrefs(cd, bptr);
314 /* handle replacement points */
316 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
318 /* copy interface registers to their destination */
323 #if defined(ENABLE_PROFILING)
324 /* generate basicblock profiling code */
326 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
327 /* count frequency */
329 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
330 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
332 /* if this is an exception handler, start profiling again */
334 if (bptr->type == BBTYPE_EXH)
339 #if defined(ENABLE_LSRA)
343 src = bptr->invars[len];
344 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
345 if (bptr->type == BBTYPE_EXH) {
346 /* d = reg_of_var(rd, src, REG_ITMP1); */
347 if (!IS_INMEMORY(src->flags))
351 M_INTMOVE(REG_ITMP1, d);
352 emit_store(jd, NULL, src, d);
362 var = VAR(bptr->invars[len]);
363 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
364 if (bptr->type == BBTYPE_EXH) {
365 d = codegen_reg_of_var(0, var, REG_ITMP1);
366 M_INTMOVE(REG_ITMP1, d);
367 emit_store(jd, NULL, var, d);
371 assert((var->flags & INOUT));
374 #if defined(ENABLE_LSRA)
377 /* walk through all instructions */
382 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
383 if (iptr->line != currentline) {
384 linenumbertable_list_entry_add(cd, iptr->line);
385 currentline = iptr->line;
388 MCODECHECK(1024); /* 1KB should be enough */
391 case ICMD_NOP: /* ... ==> ... */
392 case ICMD_POP: /* ..., value ==> ... */
393 case ICMD_POP2: /* ..., value, value ==> ... */
396 case ICMD_INLINE_START:
398 REPLACEMENT_POINT_INLINE_START(cd, iptr);
401 case ICMD_INLINE_BODY:
403 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
404 linenumbertable_list_entry_add_inline_start(cd, iptr);
405 linenumbertable_list_entry_add(cd, iptr->line);
408 case ICMD_INLINE_END:
410 linenumbertable_list_entry_add_inline_end(cd, iptr);
411 linenumbertable_list_entry_add(cd, iptr->line);
414 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
417 emit_nullpointer_check(cd, iptr, s1);
420 /* constant operations ************************************************/
422 case ICMD_ICONST: /* ... ==> ..., constant */
424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
425 ICONST(d, iptr->sx.val.i);
426 emit_store_dst(jd, iptr, d);
429 case ICMD_LCONST: /* ... ==> ..., constant */
431 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
432 LCONST(d, iptr->sx.val.l);
433 emit_store_dst(jd, iptr, d);
436 case ICMD_FCONST: /* ... ==> ..., constant */
438 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
439 disp = dseg_add_float(cd, iptr->sx.val.f);
440 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
441 emit_store_dst(jd, iptr, d);
444 case ICMD_DCONST: /* ... ==> ..., constant */
446 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
447 disp = dseg_add_double(cd, iptr->sx.val.d);
448 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
449 emit_store_dst(jd, iptr, d);
452 case ICMD_ACONST: /* ... ==> ..., constant */
454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
456 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
457 cr = iptr->sx.val.c.ref;
458 disp = dseg_add_unique_address(cd, cr);
460 /* PROFILE_CYCLE_STOP; */
462 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
465 /* PROFILE_CYCLE_START; */
470 if (iptr->sx.val.anyptr == 0) {
474 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
478 emit_store_dst(jd, iptr, d);
482 /* load/store/copy/move operations ************************************/
484 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
485 case ICMD_ALOAD: /* s1 = local variable */
489 case ICMD_ISTORE: /* ..., value ==> ... */
500 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
504 /* integer operations *************************************************/
506 case ICMD_INEG: /* ..., value ==> ..., - value */
508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
512 emit_store_dst(jd, iptr, d);
515 case ICMD_LNEG: /* ..., value ==> ..., - value */
517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_I2L: /* ..., value ==> ..., value */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_L2I: /* ..., value ==> ..., value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
537 emit_store_dst(jd, iptr, d);
540 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
545 emit_store_dst(jd, iptr, d);
548 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
553 emit_store_dst(jd, iptr, d);
556 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
561 emit_store_dst(jd, iptr, d);
565 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
569 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
576 emit_store_dst(jd, iptr, d);
580 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
581 /* sx.val.i = constant */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
586 /* Using inc and dec is not faster than add (tested with
590 M_IADD_IMM(iptr->sx.val.i, d);
591 emit_store_dst(jd, iptr, d);
594 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 emit_store_dst(jd, iptr, d);
608 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
609 /* sx.val.l = constant */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
614 if (IS_IMM32(iptr->sx.val.l))
615 M_LADD_IMM(iptr->sx.val.l, d);
617 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
618 M_LADD(REG_ITMP2, d);
620 emit_store_dst(jd, iptr, d);
623 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
626 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
629 M_INTMOVE(s1, REG_ITMP1);
630 M_ISUB(s2, REG_ITMP1);
631 M_INTMOVE(REG_ITMP1, d);
636 emit_store_dst(jd, iptr, d);
639 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
640 /* sx.val.i = constant */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
645 M_ISUB_IMM(iptr->sx.val.i, d);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
655 M_INTMOVE(s1, REG_ITMP1);
656 M_LSUB(s2, REG_ITMP1);
657 M_INTMOVE(REG_ITMP1, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
666 /* sx.val.l = constant */
668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
671 if (IS_IMM32(iptr->sx.val.l))
672 M_LSUB_IMM(iptr->sx.val.l, d);
674 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
675 M_LSUB(REG_ITMP2, d);
677 emit_store_dst(jd, iptr, d);
680 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
691 emit_store_dst(jd, iptr, d);
694 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
695 /* sx.val.i = constant */
697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
699 if (iptr->sx.val.i == 2) {
703 M_IMUL_IMM(s1, iptr->sx.val.i, d);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 emit_store_dst(jd, iptr, d);
721 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
722 /* sx.val.l = constant */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
726 if (IS_IMM32(iptr->sx.val.l))
727 M_LMUL_IMM(s1, iptr->sx.val.l, d);
729 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
731 M_LMUL(REG_ITMP2, d);
733 emit_store_dst(jd, iptr, d);
736 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
738 s1 = emit_load_s1(jd, iptr, RAX);
739 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
740 d = codegen_reg_of_dst(jd, iptr, RAX);
743 M_INTMOVE(s2, REG_ITMP3);
744 emit_arithmetic_check(cd, iptr, REG_ITMP3);
746 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
748 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
750 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
751 M_BEQ(1 + 3); /* 6 bytes */
753 emit_cltd(cd); /* 1 byte */
754 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
757 emit_store_dst(jd, iptr, d);
758 dst = VAROP(iptr->dst);
759 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
760 M_MOV(REG_ITMP2, RDX); /* restore RDX */
763 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
765 s1 = emit_load_s1(jd, iptr, RAX);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
767 d = codegen_reg_of_dst(jd, iptr, RDX);
770 M_INTMOVE(s2, REG_ITMP3);
771 emit_arithmetic_check(cd, iptr, REG_ITMP3);
773 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
775 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
777 M_CLR(RDX); /* 3 bytes */
778 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
779 M_BEQ(1 + 3); /* 6 bytes */
781 emit_cltd(cd); /* 1 byte */
782 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
785 emit_store_dst(jd, iptr, d);
786 dst = VAROP(iptr->dst);
787 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
788 M_MOV(REG_ITMP2, RDX); /* restore RDX */
791 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
792 /* sx.val.i = constant */
794 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
796 M_INTMOVE(s1, REG_ITMP1);
797 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
798 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
799 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
800 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
801 emit_mov_reg_reg(cd, REG_ITMP1, d);
802 emit_store_dst(jd, iptr, d);
805 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
806 /* sx.val.i = constant */
808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
809 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
810 M_INTMOVE(s1, REG_ITMP1);
811 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
812 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
813 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
814 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
815 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
816 emit_mov_reg_reg(cd, REG_ITMP1, d);
817 emit_store_dst(jd, iptr, d);
821 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
823 s1 = emit_load_s1(jd, iptr, RAX);
824 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
825 d = codegen_reg_of_dst(jd, iptr, RAX);
828 M_INTMOVE(s2, REG_ITMP3);
829 emit_arithmetic_check(cd, iptr, REG_ITMP3);
831 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
833 /* check as described in jvm spec */
834 disp = dseg_add_s8(cd, 0x8000000000000000LL);
835 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
837 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
838 M_BEQ(2 + 3); /* 6 bytes */
840 emit_cqto(cd); /* 2 bytes */
841 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
844 emit_store_dst(jd, iptr, d);
845 dst = VAROP(iptr->dst);
846 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
847 M_MOV(REG_ITMP2, RDX); /* restore RDX */
850 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
852 s1 = emit_load_s1(jd, iptr, RAX);
853 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
854 d = codegen_reg_of_dst(jd, iptr, RDX);
857 M_INTMOVE(s2, REG_ITMP3);
858 emit_arithmetic_check(cd, iptr, REG_ITMP3);
860 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
862 /* check as described in jvm spec */
863 disp = dseg_add_s8(cd, 0x8000000000000000LL);
864 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
866 M_LXOR(RDX, RDX); /* 3 bytes */
867 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
868 M_BEQ(2 + 3); /* 6 bytes */
870 emit_cqto(cd); /* 2 bytes */
871 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
874 emit_store_dst(jd, iptr, d);
875 dst = VAROP(iptr->dst);
876 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
877 M_MOV(REG_ITMP2, RDX); /* restore RDX */
880 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
881 /* sx.val.i = constant */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
885 M_INTMOVE(s1, REG_ITMP1);
886 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
887 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
888 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
889 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
890 emit_mov_reg_reg(cd, REG_ITMP1, d);
891 emit_store_dst(jd, iptr, d);
894 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
895 /* sx.val.l = constant */
897 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
898 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
899 M_INTMOVE(s1, REG_ITMP1);
900 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
901 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
902 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
903 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
904 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
905 emit_mov_reg_reg(cd, REG_ITMP1, d);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
911 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
912 emit_ishift(jd, SHIFT_SHL, iptr);
915 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
916 /* sx.val.i = constant */
918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
921 M_ISLL_IMM(iptr->sx.val.i, d);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
927 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
928 emit_ishift(jd, SHIFT_SAR, iptr);
931 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
932 /* sx.val.i = constant */
934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
935 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
937 M_ISRA_IMM(iptr->sx.val.i, d);
938 emit_store_dst(jd, iptr, d);
941 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
943 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
944 emit_ishift(jd, SHIFT_SHR, iptr);
947 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
948 /* sx.val.i = constant */
950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953 M_ISRL_IMM(iptr->sx.val.i, d);
954 emit_store_dst(jd, iptr, d);
957 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
959 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
960 emit_lshift(jd, SHIFT_SHL, iptr);
963 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
964 /* sx.val.i = constant */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
969 M_LSLL_IMM(iptr->sx.val.i, d);
970 emit_store_dst(jd, iptr, d);
973 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
975 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
976 emit_lshift(jd, SHIFT_SAR, iptr);
979 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
980 /* sx.val.i = constant */
982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
983 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
985 M_LSRA_IMM(iptr->sx.val.i, d);
986 emit_store_dst(jd, iptr, d);
989 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
991 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
992 emit_lshift(jd, SHIFT_SHR, iptr);
995 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
996 /* sx.val.l = constant */
998 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
999 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1001 M_LSRL_IMM(iptr->sx.val.i, d);
1002 emit_store_dst(jd, iptr, d);
1005 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1008 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1009 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 emit_store_dst(jd, iptr, d);
1019 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1020 /* sx.val.i = constant */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1025 M_IAND_IMM(iptr->sx.val.i, d);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1032 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1033 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1044 /* sx.val.l = constant */
1046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1049 if (IS_IMM32(iptr->sx.val.l))
1050 M_LAND_IMM(iptr->sx.val.l, d);
1052 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1053 M_LAND(REG_ITMP2, d);
1055 emit_store_dst(jd, iptr, d);
1058 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1073 /* sx.val.i = constant */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1078 M_IOR_IMM(iptr->sx.val.i, d);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1085 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1086 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1093 emit_store_dst(jd, iptr, d);
1096 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1097 /* sx.val.l = constant */
1099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1100 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1102 if (IS_IMM32(iptr->sx.val.l))
1103 M_LOR_IMM(iptr->sx.val.l, d);
1105 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1106 M_LOR(REG_ITMP2, d);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1113 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1114 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1115 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1126 /* sx.val.i = constant */
1128 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1129 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1131 M_IXOR_IMM(iptr->sx.val.i, d);
1132 emit_store_dst(jd, iptr, d);
1135 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1138 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1139 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1146 emit_store_dst(jd, iptr, d);
1149 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1150 /* sx.val.l = constant */
1152 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1155 if (IS_IMM32(iptr->sx.val.l))
1156 M_LXOR_IMM(iptr->sx.val.l, d);
1158 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1159 M_LXOR(REG_ITMP2, d);
1161 emit_store_dst(jd, iptr, d);
1165 /* floating operations ************************************************/
1167 case ICMD_FNEG: /* ..., value ==> ..., - value */
1169 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1170 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1171 disp = dseg_add_s4(cd, 0x80000000);
1173 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1174 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1175 emit_store_dst(jd, iptr, d);
1178 case ICMD_DNEG: /* ..., value ==> ..., - value */
1180 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1181 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1182 disp = dseg_add_s8(cd, 0x8000000000000000);
1184 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1185 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1186 emit_store_dst(jd, iptr, d);
1189 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1191 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1192 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1193 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1205 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1206 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1207 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1214 emit_store_dst(jd, iptr, d);
1217 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1219 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1220 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1221 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1223 M_FLTMOVE(s2, REG_FTMP2);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1233 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1237 M_FLTMOVE(s2, REG_FTMP2);
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1247 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1261 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1262 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1263 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1275 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1276 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1277 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 M_FLTMOVE(s2, REG_FTMP2);
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1289 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1290 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1291 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1293 M_FLTMOVE(s2, REG_FTMP2);
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1303 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1304 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1306 emit_store_dst(jd, iptr, d);
1309 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1312 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1328 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1330 emit_store_dst(jd, iptr, d);
1333 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1335 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1338 M_ICMP_IMM(0x80000000, d); /* corner cases */
1339 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1340 ((REG_RESULT == d) ? 0 : 3);
1342 M_FLTMOVE(s1, REG_FTMP1);
1343 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1345 M_INTMOVE(REG_RESULT, d);
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1351 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1352 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1354 M_ICMP_IMM(0x80000000, d); /* corner cases */
1355 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1356 ((REG_RESULT == d) ? 0 : 3);
1358 M_FLTMOVE(s1, REG_FTMP1);
1359 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1361 M_INTMOVE(REG_RESULT, d);
1362 emit_store_dst(jd, iptr, d);
1365 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1367 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1368 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1370 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1371 M_LCMP(REG_ITMP2, d); /* corner cases */
1372 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1373 ((REG_RESULT == d) ? 0 : 3);
1375 M_FLTMOVE(s1, REG_FTMP1);
1376 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1378 M_INTMOVE(REG_RESULT, d);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1384 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1387 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1388 M_LCMP(REG_ITMP2, d); /* corner cases */
1389 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1390 ((REG_RESULT == d) ? 0 : 3);
1392 M_FLTMOVE(s1, REG_FTMP1);
1393 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1395 M_INTMOVE(REG_RESULT, d);
1396 emit_store_dst(jd, iptr, d);
1399 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1401 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1402 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1404 emit_store_dst(jd, iptr, d);
1407 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1409 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1410 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1416 /* == => 0, < => 1, > => -1 */
1418 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1419 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1422 M_MOV_IMM(1, REG_ITMP1);
1423 M_MOV_IMM(-1, REG_ITMP2);
1424 emit_ucomiss_reg_reg(cd, s1, s2);
1425 M_CMOVULT(REG_ITMP1, d);
1426 M_CMOVUGT(REG_ITMP2, d);
1427 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1432 /* == => 0, < => 1, > => -1 */
1434 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1435 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1436 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1438 M_MOV_IMM(1, REG_ITMP1);
1439 M_MOV_IMM(-1, REG_ITMP2);
1440 emit_ucomiss_reg_reg(cd, s1, s2);
1441 M_CMOVULT(REG_ITMP1, d);
1442 M_CMOVUGT(REG_ITMP2, d);
1443 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1444 emit_store_dst(jd, iptr, d);
1447 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1448 /* == => 0, < => 1, > => -1 */
1450 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1454 M_MOV_IMM(1, REG_ITMP1);
1455 M_MOV_IMM(-1, REG_ITMP2);
1456 emit_ucomisd_reg_reg(cd, s1, s2);
1457 M_CMOVULT(REG_ITMP1, d);
1458 M_CMOVUGT(REG_ITMP2, d);
1459 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1460 emit_store_dst(jd, iptr, d);
1463 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1464 /* == => 0, < => 1, > => -1 */
1466 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1467 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1470 M_MOV_IMM(1, REG_ITMP1);
1471 M_MOV_IMM(-1, REG_ITMP2);
1472 emit_ucomisd_reg_reg(cd, s1, s2);
1473 M_CMOVULT(REG_ITMP1, d);
1474 M_CMOVUGT(REG_ITMP2, d);
1475 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1476 emit_store_dst(jd, iptr, d);
1480 /* memory operations **************************************************/
1482 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1486 /* implicit null-pointer check */
1487 M_ILD(d, s1, OFFSET(java_array_t, size));
1488 emit_store_dst(jd, iptr, d);
1491 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1494 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1495 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1496 /* implicit null-pointer check */
1497 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1498 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1499 emit_store_dst(jd, iptr, d);
1502 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1505 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1506 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1507 /* implicit null-pointer check */
1508 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1509 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1510 emit_store_dst(jd, iptr, d);
1513 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1518 /* implicit null-pointer check */
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1521 emit_store_dst(jd, iptr, d);
1524 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1527 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1528 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1529 /* implicit null-pointer check */
1530 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1531 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1532 emit_store_dst(jd, iptr, d);
1535 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1538 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1540 /* implicit null-pointer check */
1541 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1542 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1543 emit_store_dst(jd, iptr, d);
1546 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1551 /* implicit null-pointer check */
1552 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1553 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1554 emit_store_dst(jd, iptr, d);
1557 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1562 /* implicit null-pointer check */
1563 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1564 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1565 emit_store_dst(jd, iptr, d);
1568 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1571 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1573 /* implicit null-pointer check */
1574 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1575 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1576 emit_store_dst(jd, iptr, d);
1580 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1583 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1584 /* implicit null-pointer check */
1585 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1586 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1587 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1590 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1594 /* implicit null-pointer check */
1595 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1596 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1597 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1600 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1603 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1604 /* implicit null-pointer check */
1605 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1606 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1607 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1610 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1614 /* implicit null-pointer check */
1615 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1616 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1617 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1620 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1624 /* implicit null-pointer check */
1625 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1626 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1627 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1630 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1634 /* implicit null-pointer check */
1635 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1636 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1637 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1640 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1643 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1644 /* implicit null-pointer check */
1645 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1646 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1647 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1650 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1654 /* implicit null-pointer check */
1655 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1656 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1660 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1662 emit_arraystore_check(cd, iptr);
1664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1667 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1671 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1675 /* implicit null-pointer check */
1676 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1677 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1680 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1683 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1684 /* implicit null-pointer check */
1685 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1686 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1689 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1692 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1693 /* implicit null-pointer check */
1694 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1695 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1698 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1702 /* implicit null-pointer check */
1703 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1704 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1707 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711 /* implicit null-pointer check */
1712 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1714 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1715 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1718 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1719 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1723 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1727 /* implicit null-pointer check */
1728 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1729 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1733 case ICMD_GETSTATIC: /* ... ==> ..., value */
1735 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1736 uf = iptr->sx.s23.s3.uf;
1737 fieldtype = uf->fieldref->parseddesc.fd->type;
1738 disp = dseg_add_unique_address(cd, uf);
1740 /* PROFILE_CYCLE_STOP; */
1742 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1744 /* PROFILE_CYCLE_START; */
1747 fi = iptr->sx.s23.s3.fmiref->p.field;
1748 fieldtype = fi->type;
1749 disp = dseg_add_address(cd, fi->value);
1751 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1754 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1757 PROFILE_CYCLE_START;
1761 /* This approach is much faster than moving the field
1762 address inline into a register. */
1764 M_ALD(REG_ITMP1, RIP, disp);
1766 switch (fieldtype) {
1768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1769 M_ILD(d, REG_ITMP1, 0);
1773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1774 M_LLD(d, REG_ITMP1, 0);
1777 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1778 M_FLD(d, REG_ITMP1, 0);
1781 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1782 M_DLD(d, REG_ITMP1, 0);
1785 emit_store_dst(jd, iptr, d);
1788 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1790 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1791 uf = iptr->sx.s23.s3.uf;
1792 fieldtype = uf->fieldref->parseddesc.fd->type;
1793 disp = dseg_add_unique_address(cd, uf);
1795 /* PROFILE_CYCLE_STOP; */
1797 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1799 /* PROFILE_CYCLE_START; */
1802 fi = iptr->sx.s23.s3.fmiref->p.field;
1803 fieldtype = fi->type;
1804 disp = dseg_add_address(cd, fi->value);
1806 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1809 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1812 PROFILE_CYCLE_START;
1816 /* This approach is much faster than moving the field
1817 address inline into a register. */
1819 M_ALD(REG_ITMP1, RIP, disp);
1821 switch (fieldtype) {
1823 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1824 M_IST(s1, REG_ITMP1, 0);
1828 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1829 M_LST(s1, REG_ITMP1, 0);
1832 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1833 M_FST(s1, REG_ITMP1, 0);
1836 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1837 M_DST(s1, REG_ITMP1, 0);
1842 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1843 /* val = value (in current instruction) */
1844 /* following NOP) */
1846 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1847 uf = iptr->sx.s23.s3.uf;
1848 fieldtype = uf->fieldref->parseddesc.fd->type;
1849 disp = dseg_add_unique_address(cd, uf);
1851 /* PROFILE_CYCLE_STOP; */
1853 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1855 /* PROFILE_CYCLE_START; */
1858 fi = iptr->sx.s23.s3.fmiref->p.field;
1859 fieldtype = fi->type;
1860 disp = dseg_add_address(cd, fi->value);
1862 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1865 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1868 PROFILE_CYCLE_START;
1872 /* This approach is much faster than moving the field
1873 address inline into a register. */
1875 M_ALD(REG_ITMP1, RIP, disp);
1877 switch (fieldtype) {
1880 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1885 if (IS_IMM32(iptr->sx.s23.s2.constval))
1886 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1888 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1889 M_LST(REG_ITMP2, REG_ITMP1, 0);
1895 case ICMD_GETFIELD: /* ... ==> ..., value */
1897 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1900 uf = iptr->sx.s23.s3.uf;
1901 fieldtype = uf->fieldref->parseddesc.fd->type;
1904 /* PROFILE_CYCLE_STOP; */
1906 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1908 /* PROFILE_CYCLE_START; */
1911 fi = iptr->sx.s23.s3.fmiref->p.field;
1912 fieldtype = fi->type;
1916 /* implicit null-pointer check */
1917 switch (fieldtype) {
1919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1920 M_ILD32(d, s1, disp);
1924 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1925 M_LLD32(d, s1, disp);
1928 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1929 M_FLD32(d, s1, disp);
1932 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1933 M_DLD32(d, s1, disp);
1936 emit_store_dst(jd, iptr, d);
1939 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1942 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1944 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1945 uf = iptr->sx.s23.s3.uf;
1946 fieldtype = uf->fieldref->parseddesc.fd->type;
1949 /* PROFILE_CYCLE_STOP; */
1951 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1953 /* PROFILE_CYCLE_START; */
1956 fi = iptr->sx.s23.s3.fmiref->p.field;
1957 fieldtype = fi->type;
1961 /* implicit null-pointer check */
1962 switch (fieldtype) {
1964 M_IST32(s2, s1, disp);
1968 M_LST32(s2, s1, disp);
1971 M_FST32(s2, s1, disp);
1974 M_DST32(s2, s1, disp);
1979 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1980 /* val = value (in current instruction) */
1981 /* following NOP) */
1983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1985 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1986 uf = iptr->sx.s23.s3.uf;
1987 fieldtype = uf->fieldref->parseddesc.fd->type;
1990 /* PROFILE_CYCLE_STOP; */
1992 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1994 /* PROFILE_CYCLE_START; */
1997 fi = iptr->sx.s23.s3.fmiref->p.field;
1998 fieldtype = fi->type;
2002 /* implicit null-pointer check */
2003 switch (fieldtype) {
2006 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2011 /* XXX why no check for IS_IMM32? -- probably because of the patcher */
2012 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
2013 if (disp) /* resolved, disp can never be 0 */
2014 M_LST(REG_ITMP2, s1, disp);
2015 else /* unresolved */
2016 M_LST32(REG_ITMP2, s1, disp);
2022 /* branch operations **************************************************/
2024 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027 M_INTMOVE(s1, REG_ITMP1_XPTR);
2031 #ifdef ENABLE_VERIFIER
2032 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2033 uc = iptr->sx.s23.s2.uc;
2035 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2037 #endif /* ENABLE_VERIFIER */
2039 M_CALL_IMM(0); /* passing exception pc */
2040 M_POP(REG_ITMP2_XPC);
2042 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2046 case ICMD_GOTO: /* ... ==> ... */
2049 emit_br(cd, iptr->dst.block);
2053 case ICMD_JSR: /* ... ==> ... */
2055 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2059 case ICMD_IFNULL: /* ..., value ==> ... */
2060 case ICMD_IFNONNULL:
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2064 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2067 case ICMD_IFEQ: /* ..., value ==> ... */
2074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2075 M_ICMP_IMM(iptr->sx.val.i, s1);
2076 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2079 case ICMD_IF_LEQ: /* ..., value ==> ... */
2086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2087 if (IS_IMM32(iptr->sx.val.l))
2088 M_LCMP_IMM(iptr->sx.val.l, s1);
2090 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2091 M_LCMP(REG_ITMP2, s1);
2093 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2096 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2097 case ICMD_IF_ICMPNE:
2098 case ICMD_IF_ICMPLT:
2099 case ICMD_IF_ICMPGE:
2100 case ICMD_IF_ICMPGT:
2101 case ICMD_IF_ICMPLE:
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2106 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2109 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2110 case ICMD_IF_ACMPNE:
2112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2115 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2118 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2119 case ICMD_IF_LCMPNE:
2120 case ICMD_IF_LCMPLT:
2121 case ICMD_IF_LCMPGE:
2122 case ICMD_IF_LCMPGT:
2123 case ICMD_IF_LCMPLE:
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2128 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2131 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2134 REPLACEMENT_POINT_RETURN(cd, iptr);
2135 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2136 M_INTMOVE(s1, REG_RESULT);
2137 goto nowperformreturn;
2139 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2141 REPLACEMENT_POINT_RETURN(cd, iptr);
2142 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2143 M_INTMOVE(s1, REG_RESULT);
2145 #ifdef ENABLE_VERIFIER
2146 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2147 uc = iptr->sx.s23.s2.uc;
2151 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2153 PROFILE_CYCLE_START;
2155 #endif /* ENABLE_VERIFIER */
2156 goto nowperformreturn;
2158 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2161 REPLACEMENT_POINT_RETURN(cd, iptr);
2162 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2163 M_FLTMOVE(s1, REG_FRESULT);
2164 goto nowperformreturn;
2166 case ICMD_RETURN: /* ... ==> ... */
2168 REPLACEMENT_POINT_RETURN(cd, iptr);
2174 p = cd->stackframesize;
2176 #if !defined(NDEBUG)
2177 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2178 emit_verbosecall_exit(jd);
2179 #endif /* !defined(NDEBUG) */
2181 #if defined(ENABLE_THREADS)
2182 if (checksync && code_is_synchronized(code)) {
2183 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2185 /* we need to save the proper return value */
2186 switch (iptr->opc) {
2190 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2194 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2198 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2201 /* and now restore the proper return value */
2202 switch (iptr->opc) {
2206 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2210 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2216 /* restore saved registers */
2218 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2219 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2221 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2222 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2225 /* deallocate stack */
2227 if (cd->stackframesize)
2228 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2230 /* generate method profiling code */
2239 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2242 branch_target_t *table;
2244 table = iptr->dst.table;
2246 l = iptr->sx.s23.s2.tablelow;
2247 i = iptr->sx.s23.s3.tablehigh;
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 M_INTMOVE(s1, REG_ITMP1);
2253 M_ISUB_IMM(l, REG_ITMP1);
2255 /* number of targets */
2260 M_ICMP_IMM(i - 1, REG_ITMP1);
2261 emit_bugt(cd, table[0].block);
2263 /* build jump table top down and use address of lowest entry */
2268 dseg_add_target(cd, table->block);
2272 /* length of dataseg after last dseg_add_target is used
2275 M_MOV_IMM(0, REG_ITMP2);
2277 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2283 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2286 lookup_target_t *lookup;
2288 lookup = iptr->dst.lookup;
2290 i = iptr->sx.s23.s2.lookupcount;
2292 MCODECHECK(8 + ((7 + 6) * i) + 5);
2293 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2296 M_ICMP_IMM(lookup->value, s1);
2297 emit_beq(cd, lookup->target.block);
2301 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2307 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2309 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2311 bte = iptr->sx.s23.s3.bte;
2315 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2317 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2318 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2319 case ICMD_INVOKEINTERFACE:
2321 REPLACEMENT_POINT_INVOKE(cd, iptr);
2323 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2325 um = iptr->sx.s23.s3.um;
2326 md = um->methodref->parseddesc.md;
2329 lm = iptr->sx.s23.s3.fmiref->p.method;
2331 md = lm->parseddesc;
2335 s3 = md->paramcount;
2337 MCODECHECK((20 * s3) + 128);
2339 /* copy arguments to registers or stack location */
2341 for (s3 = s3 - 1; s3 >= 0; s3--) {
2342 var = VAR(iptr->sx.s23.s2.args[s3]);
2343 d = md->params[s3].regoff;
2345 /* already preallocated (ARGVAR)? */
2347 if (var->flags & PREALLOC)
2350 if (IS_INT_LNG_TYPE(var->type)) {
2351 if (!md->params[s3].inmemory) {
2352 s1 = emit_load(jd, iptr, var, d);
2356 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2357 M_LST(s1, REG_SP, d);
2361 if (!md->params[s3].inmemory) {
2362 s1 = emit_load(jd, iptr, var, d);
2366 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2368 if (IS_2_WORD_TYPE(var->type))
2369 M_DST(s1, REG_SP, d);
2371 M_FST(s1, REG_SP, d);
2376 /* generate method profiling code */
2380 switch (iptr->opc) {
2382 if (bte->stub == NULL) {
2383 M_MOV_IMM(bte->fp, REG_ITMP1);
2386 M_MOV_IMM(bte->stub, REG_ITMP1);
2391 case ICMD_INVOKESPECIAL:
2392 emit_nullpointer_check(cd, iptr, REG_A0);
2395 case ICMD_INVOKESTATIC:
2397 disp = dseg_add_unique_address(cd, um);
2399 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2403 disp = dseg_add_functionptr(cd, lm->stubroutine);
2406 M_ALD(REG_ITMP2, RIP, disp);
2410 case ICMD_INVOKEVIRTUAL:
2412 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2417 s1 = OFFSET(vftbl_t, table[0]) +
2418 sizeof(methodptr) * lm->vftblindex;
2421 /* implicit null-pointer check */
2422 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2423 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2427 case ICMD_INVOKEINTERFACE:
2429 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2435 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2436 sizeof(methodptr) * lm->clazz->index;
2438 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2441 /* implicit null-pointer check */
2442 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2443 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2444 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2449 /* generate method profiling code */
2451 PROFILE_CYCLE_START;
2453 /* store size of call code in replacement point */
2455 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2456 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2458 /* store return value */
2460 switch (md->returntype.type) {
2464 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2465 M_INTMOVE(REG_RESULT, s1);
2466 emit_store_dst(jd, iptr, s1);
2470 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2471 M_FLTMOVE(REG_FRESULT, s1);
2472 emit_store_dst(jd, iptr, s1);
2481 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2483 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2484 /* object type cast-check */
2489 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2494 super = iptr->sx.s23.s3.c.cls;
2495 superindex = super->index;
2498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2500 /* if class is not resolved, check which code to call */
2502 if (super == NULL) {
2504 emit_label_beq(cd, BRANCH_LABEL_1);
2506 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2507 iptr->sx.s23.s3.c.ref, 0);
2509 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2510 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2511 emit_label_beq(cd, BRANCH_LABEL_2);
2514 /* interface checkcast code */
2516 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2517 if (super != NULL) {
2519 emit_label_beq(cd, BRANCH_LABEL_3);
2522 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2524 if (super == NULL) {
2525 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2526 iptr->sx.s23.s3.c.ref,
2531 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2532 M_ICMP_IMM32(superindex, REG_ITMP3);
2533 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2535 M_ALD32(REG_ITMP3, REG_ITMP2,
2536 OFFSET(vftbl_t, interfacetable[0]) -
2537 superindex * sizeof(methodptr*));
2539 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2542 emit_label_br(cd, BRANCH_LABEL_4);
2544 emit_label(cd, BRANCH_LABEL_3);
2547 /* class checkcast code */
2549 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2550 if (super == NULL) {
2551 emit_label(cd, BRANCH_LABEL_2);
2553 cr = iptr->sx.s23.s3.c.ref;
2554 disp = dseg_add_unique_address(cd, cr);
2556 patcher_add_patch_ref(jd,
2557 PATCHER_resolve_classref_to_vftbl,
2562 emit_label_beq(cd, BRANCH_LABEL_5);
2564 disp = dseg_add_address(cd, super->vftbl);
2567 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2568 M_ALD(REG_ITMP3, RIP, disp);
2570 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2571 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2572 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2573 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
2575 if (super == NULL) {
2576 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2577 emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
2580 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2581 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2582 emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
2584 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2585 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
2586 emit_label_beq(cd, BRANCH_LABEL_7); /* good */
2588 emit_label(cd, BRANCH_LABEL_9);
2590 emit_label(cd, BRANCH_LABEL_10);
2592 /* reload s1, might have been destroyed */
2593 emit_load_s1(jd, iptr, REG_ITMP1);
2594 M_ALD_MEM(s1, TRAP_ClassCastException);
2596 emit_label(cd, BRANCH_LABEL_7);
2597 emit_label(cd, BRANCH_LABEL_6);
2598 /* reload s1, might have been destroyed */
2599 emit_load_s1(jd, iptr, REG_ITMP1);
2602 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2603 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2607 emit_label(cd, BRANCH_LABEL_5);
2610 if (super == NULL) {
2611 emit_label(cd, BRANCH_LABEL_1);
2612 emit_label(cd, BRANCH_LABEL_4);
2615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2618 /* array type cast-check */
2620 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2621 M_INTMOVE(s1, REG_A0);
2623 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2624 cr = iptr->sx.s23.s3.c.ref;
2625 disp = dseg_add_unique_address(cd, cr);
2627 patcher_add_patch_ref(jd,
2628 PATCHER_resolve_classref_to_classinfo,
2632 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2635 M_ALD(REG_A1, RIP, disp);
2636 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2639 /* s1 may have been destroyed over the function call */
2640 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2642 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2648 emit_store_dst(jd, iptr, d);
2651 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2657 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2662 super = iptr->sx.s23.s3.c.cls;
2663 superindex = super->index;
2666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2670 M_INTMOVE(s1, REG_ITMP1);
2676 /* if class is not resolved, check which code to call */
2678 if (super == NULL) {
2680 emit_label_beq(cd, BRANCH_LABEL_1);
2682 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2683 iptr->sx.s23.s3.c.ref, 0);
2685 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2686 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2687 emit_label_beq(cd, BRANCH_LABEL_2);
2690 /* interface instanceof code */
2692 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2693 if (super != NULL) {
2695 emit_label_beq(cd, BRANCH_LABEL_3);
2698 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2700 if (super == NULL) {
2701 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2702 iptr->sx.s23.s3.c.ref, 0);
2706 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2707 M_ICMP_IMM32(superindex, REG_ITMP3);
2709 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2712 M_ALD32(REG_ITMP1, REG_ITMP1,
2713 OFFSET(vftbl_t, interfacetable[0]) -
2714 superindex * sizeof(methodptr*));
2719 emit_label_br(cd, BRANCH_LABEL_4);
2721 emit_label(cd, BRANCH_LABEL_3);
2724 /* class instanceof code */
2726 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2727 if (super == NULL) {
2728 emit_label(cd, BRANCH_LABEL_2);
2730 cr = iptr->sx.s23.s3.c.ref;
2731 disp = dseg_add_unique_address(cd, cr);
2733 patcher_add_patch_ref(jd,
2734 PATCHER_resolve_classref_to_vftbl,
2739 emit_label_beq(cd, BRANCH_LABEL_5);
2741 disp = dseg_add_address(cd, super->vftbl);
2744 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2745 M_ALD(REG_ITMP3, RIP, disp);
2747 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2748 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2749 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2750 emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2751 if (d == REG_ITMP2) {
2756 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2757 emit_label(cd, BRANCH_LABEL_8);
2759 if (super == NULL) {
2760 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2761 emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2764 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2765 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2766 emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2768 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2769 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
2771 if (d == REG_ITMP2) {
2774 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2777 emit_label(cd, BRANCH_LABEL_9);
2779 emit_label(cd, BRANCH_LABEL_10);
2780 if (d == REG_ITMP2) {
2783 emit_label(cd, BRANCH_LABEL_7);
2785 emit_label(cd, BRANCH_LABEL_6);
2788 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2795 emit_label(cd, BRANCH_LABEL_5);
2798 if (super == NULL) {
2799 emit_label(cd, BRANCH_LABEL_1);
2800 emit_label(cd, BRANCH_LABEL_4);
2803 emit_store_dst(jd, iptr, d);
2807 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2809 /* check for negative sizes and copy sizes to stack if necessary */
2811 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2813 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2815 /* copy SAVEDVAR sizes to stack */
2816 var = VAR(iptr->sx.s23.s2.args[s1]);
2818 /* Already Preallocated? */
2819 if (!(var->flags & PREALLOC)) {
2820 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2821 M_LST(s2, REG_SP, s1 * 8);
2825 /* a0 = dimension count */
2827 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2829 /* is a patcher function set? */
2831 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2832 cr = iptr->sx.s23.s3.c.ref;
2833 disp = dseg_add_unique_address(cd, cr);
2835 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2839 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2842 /* a1 = classinfo */
2844 M_ALD(REG_A1, RIP, disp);
2846 /* a2 = pointer to dimensions = stack pointer */
2848 M_MOV(REG_SP, REG_A2);
2850 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2853 /* check for exception before result assignment */
2855 emit_exception_check(cd, iptr);
2857 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2858 M_INTMOVE(REG_RESULT, s1);
2859 emit_store_dst(jd, iptr, s1);
2863 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2868 } /* for instruction */
2870 MCODECHECK(512); /* XXX require a lower number? */
2872 /* At the end of a basic block we may have to append some nops,
2873 because the patcher stub calling code might be longer than the
2874 actual instruction. So codepatching does not change the
2875 following block unintentionally. */
2877 if (cd->mcodeptr < cd->lastmcodeptr) {
2878 while (cd->mcodeptr < cd->lastmcodeptr) {
2883 } /* if (bptr -> flags >= BBREACHED) */
2884 } /* for basic block */
2886 /* Generate patcher traps. */
2888 emit_patcher_traps(jd);
2890 /* everything's ok */
2896 /* codegen_emit_stub_native ****************************************************
2898 Emits a stub routine which calls a native method.
2900 *******************************************************************************/
2902 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2916 /* Get required compiler data. */
2922 /* initialize variables */
2926 /* calculate stack frame size */
2928 cd->stackframesize =
2929 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2930 sizeof(localref_table) / SIZEOF_VOID_P +
2932 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2935 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2937 /* create method header */
2939 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2940 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2941 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2942 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2943 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2945 #if defined(ENABLE_PROFILING)
2946 /* generate native method profiling code */
2948 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2949 /* count frequency */
2951 M_MOV_IMM(code, REG_ITMP3);
2952 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2956 /* generate stub code */
2958 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2960 #if defined(ENABLE_GC_CACAO)
2961 /* Save callee saved integer registers in stackframeinfo (GC may
2962 need to recover them during a collection). */
2964 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2965 OFFSET(stackframeinfo_t, intregs);
2967 for (i = 0; i < INT_SAV_CNT; i++)
2968 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2971 /* save integer and float argument registers */
2973 for (i = 0; i < md->paramcount; i++) {
2974 if (!md->params[i].inmemory) {
2975 s1 = md->params[i].regoff;
2977 switch (md->paramtypes[i].type) {
2981 M_LST(s1, REG_SP, i * 8);
2985 M_DST(s1, REG_SP, i * 8);
2991 /* create dynamic stack info */
2993 M_MOV(REG_SP, REG_A0);
2994 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2995 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2998 /* remember class argument */
3000 if (m->flags & ACC_STATIC)
3001 M_MOV(REG_RESULT, REG_ITMP2);
3003 /* restore integer and float argument registers */
3005 for (i = 0; i < md->paramcount; i++) {
3006 if (!md->params[i].inmemory) {
3007 s1 = md->params[i].regoff;
3009 switch (md->paramtypes[i].type) {
3013 M_LLD(s1, REG_SP, i * 8);
3017 M_DLD(s1, REG_SP, i * 8);
3023 /* Copy or spill arguments to new locations. */
3025 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3026 s2 = nmd->params[j].regoff;
3028 switch (md->paramtypes[i].type) {
3032 if (!md->params[i].inmemory) {
3033 s1 = md->params[i].regoff;
3035 if (!nmd->params[j].inmemory)
3038 M_LST(s1, REG_SP, s2);
3041 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3042 M_LLD(REG_ITMP1, REG_SP, s1);
3043 M_LST(REG_ITMP1, REG_SP, s2);
3047 /* We only copy spilled float arguments, as the float
3048 argument registers keep unchanged. */
3050 if (md->params[i].inmemory) {
3051 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3053 M_FLD(REG_FTMP1, REG_SP, s1);
3054 M_FST(REG_FTMP1, REG_SP, s2);
3058 if (md->params[i].inmemory) {
3059 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3060 M_DLD(REG_FTMP1, REG_SP, s1);
3061 M_DST(REG_FTMP1, REG_SP, s2);
3067 /* Handle native Java methods. */
3069 if (m->flags & ACC_NATIVE) {
3070 /* put class into second argument register */
3072 if (m->flags & ACC_STATIC)
3073 M_MOV(REG_ITMP2, REG_A1);
3075 /* put env into first argument register */
3077 M_MOV_IMM(VM_get_jnienv(), REG_A0);
3080 /* Call the native function. */
3082 disp = dseg_add_functionptr(cd, f);
3083 M_ALD(REG_ITMP1, RIP, disp);
3086 /* save return value */
3088 switch (md->returntype.type) {
3092 switch (md->returntype.primitivetype) {
3093 case PRIMITIVETYPE_BOOLEAN:
3094 M_BZEXT(REG_RESULT, REG_RESULT);
3096 case PRIMITIVETYPE_BYTE:
3097 M_BSEXT(REG_RESULT, REG_RESULT);
3099 case PRIMITIVETYPE_CHAR:
3100 M_CZEXT(REG_RESULT, REG_RESULT);
3102 case PRIMITIVETYPE_SHORT:
3103 M_SSEXT(REG_RESULT, REG_RESULT);
3106 M_LST(REG_RESULT, REG_SP, 0 * 8);
3110 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3116 /* remove native stackframe info */
3118 M_MOV(REG_SP, REG_A0);
3119 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3120 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3122 M_MOV(REG_RESULT, REG_ITMP3);
3124 /* restore return value */
3126 switch (md->returntype.type) {
3130 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3134 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3140 #if defined(ENABLE_GC_CACAO)
3141 /* Restore callee saved integer registers from stackframeinfo (GC
3142 might have modified them during a collection). */
3144 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3145 OFFSET(stackframeinfo_t, intregs);
3147 for (i = 0; i < INT_SAV_CNT; i++)
3148 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3151 /* remove stackframe */
3153 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3155 /* test for exception */
3161 /* handle exception */
3163 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3164 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3165 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3167 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3173 * These are local overrides for various environment variables in Emacs.
3174 * Please do not remove this and leave it at the end of the file, where
3175 * Emacs will automagically detect them.
3176 * ---------------------------------------------------------------------
3179 * indent-tabs-mode: t
3183 * vim:noexpandtab:sw=4:ts=4: