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/jni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
46 #include "threads/lock-common.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.hpp"
50 #include "vm/global.h"
51 #include "vm/primitive.hpp"
52 #include "vm/string.hpp"
55 #include "vm/jit/abi.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/code.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/linenumbertable.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/parse.h"
65 #include "vm/jit/patcher-common.h"
66 #include "vm/jit/reg.h"
67 #include "vm/jit/replace.h"
68 #include "vm/jit/stacktrace.hpp"
69 #include "vm/jit/trap.h"
71 #if defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
75 #include "vmcore/loader.h"
76 #include "vmcore/options.h"
77 #include "vmcore/statistics.h"
80 /* codegen_emit ****************************************************************
82 Generates machine code.
84 *******************************************************************************/
86 bool codegen_emit(jitdata *jd)
92 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 /* space to save used callee saved registers */
131 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
132 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
134 cd->stackframesize = rd->memuse + savedregs_num;
136 #if defined(ENABLE_THREADS)
137 /* space to save argument of monitor_enter */
139 if (checksync && code_is_synchronized(code))
140 cd->stackframesize++;
143 /* Keep stack of non-leaf functions 16-byte aligned for calls into
144 native code e.g. libc or jni (alignment problems with
147 if (!code_is_leafmethod(code) || opt_verbosecall)
148 cd->stackframesize |= 0x1;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 code->synchronizedoffset = rd->memuse * 8;
157 if (code_is_leafmethod(code))
158 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
160 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
162 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
163 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
165 #if defined(ENABLE_PROFILING)
166 /* generate method profiling code */
168 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
169 /* count frequency */
171 M_MOV_IMM(code, REG_ITMP3);
172 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
178 /* create stack frame (if necessary) */
180 if (cd->stackframesize)
181 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
183 /* save used callee saved registers */
185 p = cd->stackframesize;
186 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
187 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
189 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
193 /* take arguments out of register or stack frame */
197 for (p = 0, l = 0; p < md->paramcount; p++) {
198 t = md->paramtypes[p].type;
200 varindex = jd->local_map[l * 5 + t];
203 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
206 if (varindex == UNUSED)
211 s1 = md->params[p].regoff;
213 if (IS_INT_LNG_TYPE(t)) { /* integer args */
214 if (!md->params[p].inmemory) { /* register arguments */
215 if (!IS_INMEMORY(var->flags))
216 M_INTMOVE(s1, var->vv.regoff);
218 M_LST(s1, REG_SP, var->vv.regoff);
220 else { /* stack arguments */
221 if (!IS_INMEMORY(var->flags))
222 /* + 8 for return address */
223 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
225 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
228 else { /* floating args */
229 if (!md->params[p].inmemory) { /* register arguments */
230 if (!IS_INMEMORY(var->flags))
231 M_FLTMOVE(s1, var->vv.regoff);
233 M_DST(s1, REG_SP, var->vv.regoff);
235 else { /* stack arguments */
236 if (!IS_INMEMORY(var->flags))
237 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
239 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
244 /* save monitorenter argument */
246 #if defined(ENABLE_THREADS)
247 if (checksync && code_is_synchronized(code)) {
248 /* stack offset for monitor argument */
252 if (opt_verbosecall) {
253 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
255 for (p = 0; p < INT_ARG_CNT; p++)
256 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
258 for (p = 0; p < FLT_ARG_CNT; p++)
259 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
261 s1 += INT_ARG_CNT + FLT_ARG_CNT;
264 /* decide which monitor enter function to call */
266 if (m->flags & ACC_STATIC) {
267 M_MOV_IMM(&m->clazz->object.header, REG_A0);
272 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
275 M_AST(REG_A0, REG_SP, s1 * 8);
276 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
279 if (opt_verbosecall) {
280 for (p = 0; p < INT_ARG_CNT; p++)
281 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
283 for (p = 0; p < FLT_ARG_CNT; p++)
284 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
286 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
292 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
293 emit_verbosecall_enter(jd);
294 #endif /* !defined(NDEBUG) */
298 /* end of header generation */
300 /* create replacement points */
302 REPLACEMENT_POINTS_INIT(cd, jd);
304 /* walk through all basic blocks */
306 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
308 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
310 if (bptr->flags >= BBREACHED) {
312 /* branch resolving */
314 codegen_resolve_branchrefs(cd, bptr);
316 /* handle replacement points */
318 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
320 /* copy interface registers to their destination */
325 #if defined(ENABLE_PROFILING)
326 /* generate basicblock profiling code */
328 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
329 /* count frequency */
331 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
332 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
334 /* if this is an exception handler, start profiling again */
336 if (bptr->type == BBTYPE_EXH)
341 #if defined(ENABLE_LSRA)
345 src = bptr->invars[len];
346 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
347 if (bptr->type == BBTYPE_EXH) {
348 /* d = reg_of_var(rd, src, REG_ITMP1); */
349 if (!IS_INMEMORY(src->flags))
353 M_INTMOVE(REG_ITMP1, d);
354 emit_store(jd, NULL, src, d);
364 var = VAR(bptr->invars[len]);
365 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
366 if (bptr->type == BBTYPE_EXH) {
367 d = codegen_reg_of_var(0, var, REG_ITMP1);
368 M_INTMOVE(REG_ITMP1, d);
369 emit_store(jd, NULL, var, d);
373 assert((var->flags & INOUT));
376 #if defined(ENABLE_LSRA)
379 /* walk through all instructions */
384 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
385 if (iptr->line != currentline) {
386 linenumbertable_list_entry_add(cd, iptr->line);
387 currentline = iptr->line;
390 MCODECHECK(1024); /* 1KB should be enough */
393 case ICMD_NOP: /* ... ==> ... */
394 case ICMD_POP: /* ..., value ==> ... */
395 case ICMD_POP2: /* ..., value, value ==> ... */
398 case ICMD_INLINE_START:
400 REPLACEMENT_POINT_INLINE_START(cd, iptr);
403 case ICMD_INLINE_BODY:
405 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
406 linenumbertable_list_entry_add_inline_start(cd, iptr);
407 linenumbertable_list_entry_add(cd, iptr->line);
410 case ICMD_INLINE_END:
412 linenumbertable_list_entry_add_inline_end(cd, iptr);
413 linenumbertable_list_entry_add(cd, iptr->line);
416 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
419 emit_nullpointer_check(cd, iptr, s1);
422 /* constant operations ************************************************/
424 case ICMD_ICONST: /* ... ==> ..., constant */
426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
427 ICONST(d, iptr->sx.val.i);
428 emit_store_dst(jd, iptr, d);
431 case ICMD_LCONST: /* ... ==> ..., constant */
433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
434 LCONST(d, iptr->sx.val.l);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_FCONST: /* ... ==> ..., constant */
440 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
441 disp = dseg_add_float(cd, iptr->sx.val.f);
442 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
443 emit_store_dst(jd, iptr, d);
446 case ICMD_DCONST: /* ... ==> ..., constant */
448 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
449 disp = dseg_add_double(cd, iptr->sx.val.d);
450 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
451 emit_store_dst(jd, iptr, d);
454 case ICMD_ACONST: /* ... ==> ..., constant */
456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
458 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
459 cr = iptr->sx.val.c.ref;
460 disp = dseg_add_unique_address(cd, cr);
462 /* PROFILE_CYCLE_STOP; */
464 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
467 /* PROFILE_CYCLE_START; */
472 if (iptr->sx.val.anyptr == 0) {
476 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
480 emit_store_dst(jd, iptr, d);
484 /* load/store/copy/move operations ************************************/
486 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
487 case ICMD_ALOAD: /* s1 = local variable */
491 case ICMD_ISTORE: /* ..., value ==> ... */
502 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
506 /* integer operations *************************************************/
508 case ICMD_INEG: /* ..., value ==> ..., - value */
510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
514 emit_store_dst(jd, iptr, d);
517 case ICMD_LNEG: /* ..., value ==> ..., - value */
519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
520 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
523 emit_store_dst(jd, iptr, d);
526 case ICMD_I2L: /* ..., value ==> ..., value */
528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
529 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
531 emit_store_dst(jd, iptr, d);
534 case ICMD_L2I: /* ..., value ==> ..., value */
536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
547 emit_store_dst(jd, iptr, d);
550 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
555 emit_store_dst(jd, iptr, d);
558 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
563 emit_store_dst(jd, iptr, d);
567 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 emit_store_dst(jd, iptr, d);
582 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
583 /* sx.val.i = constant */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
588 /* Using inc and dec is not faster than add (tested with
592 M_IADD_IMM(iptr->sx.val.i, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
611 /* sx.val.l = constant */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
616 if (IS_IMM32(iptr->sx.val.l))
617 M_LADD_IMM(iptr->sx.val.l, d);
619 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
620 M_LADD(REG_ITMP2, d);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 M_INTMOVE(s1, REG_ITMP1);
632 M_ISUB(s2, REG_ITMP1);
633 M_INTMOVE(REG_ITMP1, d);
638 emit_store_dst(jd, iptr, d);
641 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
642 /* sx.val.i = constant */
644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
645 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
647 M_ISUB_IMM(iptr->sx.val.i, d);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 M_INTMOVE(s1, REG_ITMP1);
658 M_LSUB(s2, REG_ITMP1);
659 M_INTMOVE(REG_ITMP1, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
668 /* sx.val.l = constant */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
673 if (IS_IMM32(iptr->sx.val.l))
674 M_LSUB_IMM(iptr->sx.val.l, d);
676 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
677 M_LSUB(REG_ITMP2, d);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
697 /* sx.val.i = constant */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
701 if (iptr->sx.val.i == 2) {
705 M_IMUL_IMM(s1, iptr->sx.val.i, d);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
720 emit_store_dst(jd, iptr, d);
723 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
724 /* sx.val.l = constant */
726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
728 if (IS_IMM32(iptr->sx.val.l))
729 M_LMUL_IMM(s1, iptr->sx.val.l, d);
731 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
733 M_LMUL(REG_ITMP2, d);
735 emit_store_dst(jd, iptr, d);
738 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
740 s1 = emit_load_s1(jd, iptr, RAX);
741 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
742 d = codegen_reg_of_dst(jd, iptr, RAX);
745 M_INTMOVE(s2, REG_ITMP3);
746 emit_arithmetic_check(cd, iptr, REG_ITMP3);
748 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
750 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
752 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
753 M_BEQ(1 + 3); /* 6 bytes */
755 emit_cltd(cd); /* 1 byte */
756 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
759 emit_store_dst(jd, iptr, d);
760 dst = VAROP(iptr->dst);
761 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
762 M_MOV(REG_ITMP2, RDX); /* restore RDX */
765 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
767 s1 = emit_load_s1(jd, iptr, RAX);
768 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
769 d = codegen_reg_of_dst(jd, iptr, RDX);
772 M_INTMOVE(s2, REG_ITMP3);
773 emit_arithmetic_check(cd, iptr, REG_ITMP3);
775 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
777 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
779 M_CLR(RDX); /* 3 bytes */
780 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
781 M_BEQ(1 + 3); /* 6 bytes */
783 emit_cltd(cd); /* 1 byte */
784 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
787 emit_store_dst(jd, iptr, d);
788 dst = VAROP(iptr->dst);
789 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
790 M_MOV(REG_ITMP2, RDX); /* restore RDX */
793 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
794 /* sx.val.i = constant */
796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
798 M_INTMOVE(s1, REG_ITMP1);
799 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
800 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
801 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
802 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
803 emit_mov_reg_reg(cd, REG_ITMP1, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
808 /* sx.val.i = constant */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
812 M_INTMOVE(s1, REG_ITMP1);
813 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
814 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
815 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
816 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
817 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
818 emit_mov_reg_reg(cd, REG_ITMP1, d);
819 emit_store_dst(jd, iptr, d);
823 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
825 s1 = emit_load_s1(jd, iptr, RAX);
826 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
827 d = codegen_reg_of_dst(jd, iptr, RAX);
830 M_INTMOVE(s2, REG_ITMP3);
831 emit_arithmetic_check(cd, iptr, REG_ITMP3);
833 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
835 /* check as described in jvm spec */
836 disp = dseg_add_s8(cd, 0x8000000000000000LL);
837 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
839 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
840 M_BEQ(2 + 3); /* 6 bytes */
842 emit_cqto(cd); /* 2 bytes */
843 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
846 emit_store_dst(jd, iptr, d);
847 dst = VAROP(iptr->dst);
848 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
849 M_MOV(REG_ITMP2, RDX); /* restore RDX */
852 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
854 s1 = emit_load_s1(jd, iptr, RAX);
855 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
856 d = codegen_reg_of_dst(jd, iptr, RDX);
859 M_INTMOVE(s2, REG_ITMP3);
860 emit_arithmetic_check(cd, iptr, REG_ITMP3);
862 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
864 /* check as described in jvm spec */
865 disp = dseg_add_s8(cd, 0x8000000000000000LL);
866 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
868 M_LXOR(RDX, RDX); /* 3 bytes */
869 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
870 M_BEQ(2 + 3); /* 6 bytes */
872 emit_cqto(cd); /* 2 bytes */
873 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
876 emit_store_dst(jd, iptr, d);
877 dst = VAROP(iptr->dst);
878 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
879 M_MOV(REG_ITMP2, RDX); /* restore RDX */
882 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
883 /* sx.val.i = constant */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
887 M_INTMOVE(s1, REG_ITMP1);
888 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
889 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
890 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
891 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
892 emit_mov_reg_reg(cd, REG_ITMP1, d);
893 emit_store_dst(jd, iptr, d);
896 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
897 /* sx.val.l = constant */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
901 M_INTMOVE(s1, REG_ITMP1);
902 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
903 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
904 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
905 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
906 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
907 emit_mov_reg_reg(cd, REG_ITMP1, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
913 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
914 emit_ishift(jd, SHIFT_SHL, iptr);
917 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
918 /* sx.val.i = constant */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
923 M_ISLL_IMM(iptr->sx.val.i, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
929 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
930 emit_ishift(jd, SHIFT_SAR, iptr);
933 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
934 /* sx.val.i = constant */
936 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
937 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
939 M_ISRA_IMM(iptr->sx.val.i, d);
940 emit_store_dst(jd, iptr, d);
943 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
945 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
946 emit_ishift(jd, SHIFT_SHR, iptr);
949 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
950 /* sx.val.i = constant */
952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
953 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
955 M_ISRL_IMM(iptr->sx.val.i, d);
956 emit_store_dst(jd, iptr, d);
959 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
961 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
962 emit_lshift(jd, SHIFT_SHL, iptr);
965 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
966 /* sx.val.i = constant */
968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
971 M_LSLL_IMM(iptr->sx.val.i, d);
972 emit_store_dst(jd, iptr, d);
975 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
977 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
978 emit_lshift(jd, SHIFT_SAR, iptr);
981 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
982 /* sx.val.i = constant */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987 M_LSRA_IMM(iptr->sx.val.i, d);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
993 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
994 emit_lshift(jd, SHIFT_SHR, iptr);
997 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
998 /* sx.val.l = constant */
1000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1001 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 M_LSRL_IMM(iptr->sx.val.i, d);
1004 emit_store_dst(jd, iptr, d);
1007 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1022 /* sx.val.i = constant */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1027 M_IAND_IMM(iptr->sx.val.i, d);
1028 emit_store_dst(jd, iptr, d);
1031 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1035 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1046 /* sx.val.l = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1051 if (IS_IMM32(iptr->sx.val.l))
1052 M_LAND_IMM(iptr->sx.val.l, d);
1054 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1055 M_LAND(REG_ITMP2, d);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1075 /* sx.val.i = constant */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1080 M_IOR_IMM(iptr->sx.val.i, d);
1081 emit_store_dst(jd, iptr, d);
1084 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1087 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1099 /* sx.val.l = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1104 if (IS_IMM32(iptr->sx.val.l))
1105 M_LOR_IMM(iptr->sx.val.l, d);
1107 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1108 M_LOR(REG_ITMP2, d);
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1124 emit_store_dst(jd, iptr, d);
1127 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1128 /* sx.val.i = constant */
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1133 M_IXOR_IMM(iptr->sx.val.i, d);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1140 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1152 /* sx.val.l = constant */
1154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1157 if (IS_IMM32(iptr->sx.val.l))
1158 M_LXOR_IMM(iptr->sx.val.l, d);
1160 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1161 M_LXOR(REG_ITMP2, d);
1163 emit_store_dst(jd, iptr, d);
1167 /* floating operations ************************************************/
1169 case ICMD_FNEG: /* ..., value ==> ..., - value */
1171 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1172 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1173 disp = dseg_add_s4(cd, 0x80000000);
1175 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1176 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1177 emit_store_dst(jd, iptr, d);
1180 case ICMD_DNEG: /* ..., value ==> ..., - value */
1182 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1183 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1184 disp = dseg_add_s8(cd, 0x8000000000000000);
1186 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1187 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1193 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1194 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1195 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1207 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1208 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1221 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1222 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1223 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1225 M_FLTMOVE(s2, REG_FTMP2);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1237 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239 M_FLTMOVE(s2, REG_FTMP2);
1244 emit_store_dst(jd, iptr, d);
1247 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1251 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1258 emit_store_dst(jd, iptr, d);
1261 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1263 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1264 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1265 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1277 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1279 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1281 M_FLTMOVE(s2, REG_FTMP2);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1291 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1295 M_FLTMOVE(s2, REG_FTMP2);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1306 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1308 emit_store_dst(jd, iptr, d);
1311 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1314 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1316 emit_store_dst(jd, iptr, d);
1319 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1321 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1322 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1332 emit_store_dst(jd, iptr, d);
1335 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1337 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1338 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1340 M_ICMP_IMM(0x80000000, d); /* corner cases */
1341 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1342 ((REG_RESULT == d) ? 0 : 3);
1344 M_FLTMOVE(s1, REG_FTMP1);
1345 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1347 M_INTMOVE(REG_RESULT, d);
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1353 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1356 M_ICMP_IMM(0x80000000, d); /* corner cases */
1357 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1358 ((REG_RESULT == d) ? 0 : 3);
1360 M_FLTMOVE(s1, REG_FTMP1);
1361 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1363 M_INTMOVE(REG_RESULT, d);
1364 emit_store_dst(jd, iptr, d);
1367 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1369 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1372 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1373 M_LCMP(REG_ITMP2, d); /* corner cases */
1374 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1375 ((REG_RESULT == d) ? 0 : 3);
1377 M_FLTMOVE(s1, REG_FTMP1);
1378 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1380 M_INTMOVE(REG_RESULT, d);
1381 emit_store_dst(jd, iptr, d);
1384 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1386 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1389 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1390 M_LCMP(REG_ITMP2, d); /* corner cases */
1391 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1392 ((REG_RESULT == d) ? 0 : 3);
1394 M_FLTMOVE(s1, REG_FTMP1);
1395 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1397 M_INTMOVE(REG_RESULT, d);
1398 emit_store_dst(jd, iptr, d);
1401 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1403 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1404 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1411 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1412 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1414 emit_store_dst(jd, iptr, d);
1417 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1418 /* == => 0, < => 1, > => -1 */
1420 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1421 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1424 M_MOV_IMM(1, REG_ITMP1);
1425 M_MOV_IMM(-1, REG_ITMP2);
1426 emit_ucomiss_reg_reg(cd, s1, s2);
1427 M_CMOVULT(REG_ITMP1, d);
1428 M_CMOVUGT(REG_ITMP2, d);
1429 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1434 /* == => 0, < => 1, > => -1 */
1436 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1437 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1438 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1440 M_MOV_IMM(1, REG_ITMP1);
1441 M_MOV_IMM(-1, REG_ITMP2);
1442 emit_ucomiss_reg_reg(cd, s1, s2);
1443 M_CMOVULT(REG_ITMP1, d);
1444 M_CMOVUGT(REG_ITMP2, d);
1445 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1446 emit_store_dst(jd, iptr, d);
1449 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1450 /* == => 0, < => 1, > => -1 */
1452 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1456 M_MOV_IMM(1, REG_ITMP1);
1457 M_MOV_IMM(-1, REG_ITMP2);
1458 emit_ucomisd_reg_reg(cd, s1, s2);
1459 M_CMOVULT(REG_ITMP1, d);
1460 M_CMOVUGT(REG_ITMP2, d);
1461 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1466 /* == => 0, < => 1, > => -1 */
1468 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1469 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1470 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1472 M_MOV_IMM(1, REG_ITMP1);
1473 M_MOV_IMM(-1, REG_ITMP2);
1474 emit_ucomisd_reg_reg(cd, s1, s2);
1475 M_CMOVULT(REG_ITMP1, d);
1476 M_CMOVUGT(REG_ITMP2, d);
1477 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1478 emit_store_dst(jd, iptr, d);
1482 /* memory operations **************************************************/
1484 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1488 /* implicit null-pointer check */
1489 M_ILD(d, s1, OFFSET(java_array_t, size));
1490 emit_store_dst(jd, iptr, d);
1493 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1497 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1498 /* implicit null-pointer check */
1499 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1500 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1501 emit_store_dst(jd, iptr, d);
1504 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1509 /* implicit null-pointer check */
1510 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1511 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1512 emit_store_dst(jd, iptr, d);
1515 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1520 /* implicit null-pointer check */
1521 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1522 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1523 emit_store_dst(jd, iptr, d);
1526 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1529 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1531 /* implicit null-pointer check */
1532 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1533 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1534 emit_store_dst(jd, iptr, d);
1537 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1542 /* implicit null-pointer check */
1543 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1544 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1545 emit_store_dst(jd, iptr, d);
1548 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1552 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1553 /* implicit null-pointer check */
1554 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1555 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1563 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1564 /* implicit null-pointer check */
1565 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1566 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1575 /* implicit null-pointer check */
1576 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1577 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1578 emit_store_dst(jd, iptr, d);
1582 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1585 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1586 /* implicit null-pointer check */
1587 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1588 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1589 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1592 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1595 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1596 /* implicit null-pointer check */
1597 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1598 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1599 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1602 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1605 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1606 /* implicit null-pointer check */
1607 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1608 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1609 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1612 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1615 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1616 /* implicit null-pointer check */
1617 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1618 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1619 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1622 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1626 /* implicit null-pointer check */
1627 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1628 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1629 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1632 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1635 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1636 /* implicit null-pointer check */
1637 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1638 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1639 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1642 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1646 /* implicit null-pointer check */
1647 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1648 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1649 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1652 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1655 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1656 /* implicit null-pointer check */
1657 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1658 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1662 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1664 emit_arraystore_check(cd, iptr);
1666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1667 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1668 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1669 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1673 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1676 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1677 /* implicit null-pointer check */
1678 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1679 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1682 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1686 /* implicit null-pointer check */
1687 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1688 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1691 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1695 /* implicit null-pointer check */
1696 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1697 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1700 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1704 /* implicit null-pointer check */
1705 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1706 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1709 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1713 /* implicit null-pointer check */
1714 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1716 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1717 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1720 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1721 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1725 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1729 /* implicit null-pointer check */
1730 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1731 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1735 case ICMD_GETSTATIC: /* ... ==> ..., value */
1737 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1738 uf = iptr->sx.s23.s3.uf;
1739 fieldtype = uf->fieldref->parseddesc.fd->type;
1740 disp = dseg_add_unique_address(cd, uf);
1742 /* PROFILE_CYCLE_STOP; */
1744 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1746 /* PROFILE_CYCLE_START; */
1749 fi = iptr->sx.s23.s3.fmiref->p.field;
1750 fieldtype = fi->type;
1751 disp = dseg_add_address(cd, fi->value);
1753 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1756 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1759 PROFILE_CYCLE_START;
1763 /* This approach is much faster than moving the field
1764 address inline into a register. */
1766 M_ALD(REG_ITMP1, RIP, disp);
1768 switch (fieldtype) {
1770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1771 M_ILD(d, REG_ITMP1, 0);
1775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1776 M_LLD(d, REG_ITMP1, 0);
1779 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1780 M_FLD(d, REG_ITMP1, 0);
1783 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1784 M_DLD(d, REG_ITMP1, 0);
1787 emit_store_dst(jd, iptr, d);
1790 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1792 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1793 uf = iptr->sx.s23.s3.uf;
1794 fieldtype = uf->fieldref->parseddesc.fd->type;
1795 disp = dseg_add_unique_address(cd, uf);
1797 /* PROFILE_CYCLE_STOP; */
1799 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1801 /* PROFILE_CYCLE_START; */
1804 fi = iptr->sx.s23.s3.fmiref->p.field;
1805 fieldtype = fi->type;
1806 disp = dseg_add_address(cd, fi->value);
1808 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1811 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1814 PROFILE_CYCLE_START;
1818 /* This approach is much faster than moving the field
1819 address inline into a register. */
1821 M_ALD(REG_ITMP1, RIP, disp);
1823 switch (fieldtype) {
1825 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1826 M_IST(s1, REG_ITMP1, 0);
1830 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1831 M_LST(s1, REG_ITMP1, 0);
1834 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1835 M_FST(s1, REG_ITMP1, 0);
1838 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1839 M_DST(s1, REG_ITMP1, 0);
1844 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1845 /* val = value (in current instruction) */
1846 /* following NOP) */
1848 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1849 uf = iptr->sx.s23.s3.uf;
1850 fieldtype = uf->fieldref->parseddesc.fd->type;
1851 disp = dseg_add_unique_address(cd, uf);
1853 /* PROFILE_CYCLE_STOP; */
1855 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1857 /* PROFILE_CYCLE_START; */
1860 fi = iptr->sx.s23.s3.fmiref->p.field;
1861 fieldtype = fi->type;
1862 disp = dseg_add_address(cd, fi->value);
1864 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1867 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1870 PROFILE_CYCLE_START;
1874 /* This approach is much faster than moving the field
1875 address inline into a register. */
1877 M_ALD(REG_ITMP1, RIP, disp);
1879 switch (fieldtype) {
1882 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1887 if (IS_IMM32(iptr->sx.s23.s2.constval))
1888 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1890 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1891 M_LST(REG_ITMP2, REG_ITMP1, 0);
1897 case ICMD_GETFIELD: /* ... ==> ..., value */
1899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1902 uf = iptr->sx.s23.s3.uf;
1903 fieldtype = uf->fieldref->parseddesc.fd->type;
1906 /* PROFILE_CYCLE_STOP; */
1908 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1910 /* PROFILE_CYCLE_START; */
1913 fi = iptr->sx.s23.s3.fmiref->p.field;
1914 fieldtype = fi->type;
1918 /* implicit null-pointer check */
1919 switch (fieldtype) {
1921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1922 M_ILD32(d, s1, disp);
1926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1927 M_LLD32(d, s1, disp);
1930 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1931 M_FLD32(d, s1, disp);
1934 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1935 M_DLD32(d, s1, disp);
1938 emit_store_dst(jd, iptr, d);
1941 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1946 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1947 uf = iptr->sx.s23.s3.uf;
1948 fieldtype = uf->fieldref->parseddesc.fd->type;
1951 /* PROFILE_CYCLE_STOP; */
1953 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1955 /* PROFILE_CYCLE_START; */
1958 fi = iptr->sx.s23.s3.fmiref->p.field;
1959 fieldtype = fi->type;
1963 /* implicit null-pointer check */
1964 switch (fieldtype) {
1966 M_IST32(s2, s1, disp);
1970 M_LST32(s2, s1, disp);
1973 M_FST32(s2, s1, disp);
1976 M_DST32(s2, s1, disp);
1981 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1982 /* val = value (in current instruction) */
1983 /* following NOP) */
1985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1988 uf = iptr->sx.s23.s3.uf;
1989 fieldtype = uf->fieldref->parseddesc.fd->type;
1992 /* PROFILE_CYCLE_STOP; */
1994 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1996 /* PROFILE_CYCLE_START; */
1999 fi = iptr->sx.s23.s3.fmiref->p.field;
2000 fieldtype = fi->type;
2004 /* implicit null-pointer check */
2005 switch (fieldtype) {
2008 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2013 /* XXX why no check for IS_IMM32? -- probably because of the patcher */
2014 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
2015 if (disp) /* resolved, disp can never be 0 */
2016 M_LST(REG_ITMP2, s1, disp);
2017 else /* unresolved */
2018 M_LST32(REG_ITMP2, s1, disp);
2024 /* branch operations **************************************************/
2026 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2028 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2029 M_INTMOVE(s1, REG_ITMP1_XPTR);
2033 #ifdef ENABLE_VERIFIER
2034 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2035 uc = iptr->sx.s23.s2.uc;
2037 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2039 #endif /* ENABLE_VERIFIER */
2041 M_CALL_IMM(0); /* passing exception pc */
2042 M_POP(REG_ITMP2_XPC);
2044 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2048 case ICMD_GOTO: /* ... ==> ... */
2051 emit_br(cd, iptr->dst.block);
2055 case ICMD_JSR: /* ... ==> ... */
2057 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2061 case ICMD_IFNULL: /* ..., value ==> ... */
2062 case ICMD_IFNONNULL:
2064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2066 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2069 case ICMD_IFEQ: /* ..., value ==> ... */
2076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2077 M_ICMP_IMM(iptr->sx.val.i, s1);
2078 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2081 case ICMD_IF_LEQ: /* ..., value ==> ... */
2088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2089 if (IS_IMM32(iptr->sx.val.l))
2090 M_LCMP_IMM(iptr->sx.val.l, s1);
2092 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2093 M_LCMP(REG_ITMP2, s1);
2095 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2098 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2099 case ICMD_IF_ICMPNE:
2100 case ICMD_IF_ICMPLT:
2101 case ICMD_IF_ICMPGE:
2102 case ICMD_IF_ICMPGT:
2103 case ICMD_IF_ICMPLE:
2105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2106 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2108 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2111 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2112 case ICMD_IF_ACMPNE:
2114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2115 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2117 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2120 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2121 case ICMD_IF_LCMPNE:
2122 case ICMD_IF_LCMPLT:
2123 case ICMD_IF_LCMPGE:
2124 case ICMD_IF_LCMPGT:
2125 case ICMD_IF_LCMPLE:
2127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2128 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2130 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2133 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2136 REPLACEMENT_POINT_RETURN(cd, iptr);
2137 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2138 M_INTMOVE(s1, REG_RESULT);
2139 goto nowperformreturn;
2141 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2143 REPLACEMENT_POINT_RETURN(cd, iptr);
2144 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2145 M_INTMOVE(s1, REG_RESULT);
2147 #ifdef ENABLE_VERIFIER
2148 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2149 uc = iptr->sx.s23.s2.uc;
2153 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2155 PROFILE_CYCLE_START;
2157 #endif /* ENABLE_VERIFIER */
2158 goto nowperformreturn;
2160 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2163 REPLACEMENT_POINT_RETURN(cd, iptr);
2164 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2165 M_FLTMOVE(s1, REG_FRESULT);
2166 goto nowperformreturn;
2168 case ICMD_RETURN: /* ... ==> ... */
2170 REPLACEMENT_POINT_RETURN(cd, iptr);
2176 p = cd->stackframesize;
2178 #if !defined(NDEBUG)
2179 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2180 emit_verbosecall_exit(jd);
2181 #endif /* !defined(NDEBUG) */
2183 #if defined(ENABLE_THREADS)
2184 if (checksync && code_is_synchronized(code)) {
2185 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2187 /* we need to save the proper return value */
2188 switch (iptr->opc) {
2192 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2196 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2200 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2203 /* and now restore the proper return value */
2204 switch (iptr->opc) {
2208 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2212 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2218 /* restore saved registers */
2220 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2221 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2223 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2224 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2227 /* deallocate stack */
2229 if (cd->stackframesize)
2230 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2232 /* generate method profiling code */
2241 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2244 branch_target_t *table;
2246 table = iptr->dst.table;
2248 l = iptr->sx.s23.s2.tablelow;
2249 i = iptr->sx.s23.s3.tablehigh;
2251 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2252 M_INTMOVE(s1, REG_ITMP1);
2255 M_ISUB_IMM(l, REG_ITMP1);
2257 /* number of targets */
2262 M_ICMP_IMM(i - 1, REG_ITMP1);
2263 emit_bugt(cd, table[0].block);
2265 /* build jump table top down and use address of lowest entry */
2270 dseg_add_target(cd, table->block);
2274 /* length of dataseg after last dseg_add_target is used
2277 M_MOV_IMM(0, REG_ITMP2);
2279 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2285 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2288 lookup_target_t *lookup;
2290 lookup = iptr->dst.lookup;
2292 i = iptr->sx.s23.s2.lookupcount;
2294 MCODECHECK(8 + ((7 + 6) * i) + 5);
2295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2298 M_ICMP_IMM(lookup->value, s1);
2299 emit_beq(cd, lookup->target.block);
2303 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2309 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2311 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2313 bte = iptr->sx.s23.s3.bte;
2317 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2319 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2320 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2321 case ICMD_INVOKEINTERFACE:
2323 REPLACEMENT_POINT_INVOKE(cd, iptr);
2325 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2327 um = iptr->sx.s23.s3.um;
2328 md = um->methodref->parseddesc.md;
2331 lm = iptr->sx.s23.s3.fmiref->p.method;
2333 md = lm->parseddesc;
2337 s3 = md->paramcount;
2339 MCODECHECK((20 * s3) + 128);
2341 /* copy arguments to registers or stack location */
2343 for (s3 = s3 - 1; s3 >= 0; s3--) {
2344 var = VAR(iptr->sx.s23.s2.args[s3]);
2345 d = md->params[s3].regoff;
2347 /* already preallocated (ARGVAR)? */
2349 if (var->flags & PREALLOC)
2352 if (IS_INT_LNG_TYPE(var->type)) {
2353 if (!md->params[s3].inmemory) {
2354 s1 = emit_load(jd, iptr, var, d);
2358 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2359 M_LST(s1, REG_SP, d);
2363 if (!md->params[s3].inmemory) {
2364 s1 = emit_load(jd, iptr, var, d);
2368 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2370 if (IS_2_WORD_TYPE(var->type))
2371 M_DST(s1, REG_SP, d);
2373 M_FST(s1, REG_SP, d);
2378 /* generate method profiling code */
2382 switch (iptr->opc) {
2384 if (bte->stub == NULL) {
2385 M_MOV_IMM(bte->fp, REG_ITMP1);
2388 M_MOV_IMM(bte->stub, REG_ITMP1);
2393 case ICMD_INVOKESPECIAL:
2394 emit_nullpointer_check(cd, iptr, REG_A0);
2397 case ICMD_INVOKESTATIC:
2399 disp = dseg_add_unique_address(cd, um);
2401 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2405 disp = dseg_add_functionptr(cd, lm->stubroutine);
2408 M_ALD(REG_ITMP2, RIP, disp);
2412 case ICMD_INVOKEVIRTUAL:
2414 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2419 s1 = OFFSET(vftbl_t, table[0]) +
2420 sizeof(methodptr) * lm->vftblindex;
2423 /* implicit null-pointer check */
2424 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2425 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2429 case ICMD_INVOKEINTERFACE:
2431 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2437 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2438 sizeof(methodptr) * lm->clazz->index;
2440 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2443 /* implicit null-pointer check */
2444 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2445 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2446 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2451 /* generate method profiling code */
2453 PROFILE_CYCLE_START;
2455 /* store size of call code in replacement point */
2457 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2458 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2460 /* store return value */
2462 switch (md->returntype.type) {
2466 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2467 M_INTMOVE(REG_RESULT, s1);
2468 emit_store_dst(jd, iptr, s1);
2472 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2473 M_FLTMOVE(REG_FRESULT, s1);
2474 emit_store_dst(jd, iptr, s1);
2483 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2485 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2486 /* object type cast-check */
2491 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2496 super = iptr->sx.s23.s3.c.cls;
2497 superindex = super->index;
2500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2502 /* if class is not resolved, check which code to call */
2504 if (super == NULL) {
2506 emit_label_beq(cd, BRANCH_LABEL_1);
2508 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2509 iptr->sx.s23.s3.c.ref, 0);
2511 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2512 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2513 emit_label_beq(cd, BRANCH_LABEL_2);
2516 /* interface checkcast code */
2518 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2519 if (super != NULL) {
2521 emit_label_beq(cd, BRANCH_LABEL_3);
2524 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2526 if (super == NULL) {
2527 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2528 iptr->sx.s23.s3.c.ref,
2533 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2534 M_ICMP_IMM32(superindex, REG_ITMP3);
2535 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2537 M_ALD32(REG_ITMP3, REG_ITMP2,
2538 OFFSET(vftbl_t, interfacetable[0]) -
2539 superindex * sizeof(methodptr*));
2541 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2544 emit_label_br(cd, BRANCH_LABEL_4);
2546 emit_label(cd, BRANCH_LABEL_3);
2549 /* class checkcast code */
2551 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2552 if (super == NULL) {
2553 emit_label(cd, BRANCH_LABEL_2);
2555 cr = iptr->sx.s23.s3.c.ref;
2556 disp = dseg_add_unique_address(cd, cr);
2558 patcher_add_patch_ref(jd,
2559 PATCHER_resolve_classref_to_vftbl,
2564 emit_label_beq(cd, BRANCH_LABEL_5);
2566 disp = dseg_add_address(cd, super->vftbl);
2569 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2570 M_ALD(REG_ITMP3, RIP, disp);
2572 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2574 /* if (s1 != REG_ITMP1) { */
2575 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2576 /* OFFSET(vftbl_t, baseval), */
2578 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2579 /* OFFSET(vftbl_t, diffval), */
2581 /* #if defined(ENABLE_THREADS) */
2582 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2584 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2588 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2589 M_ISUB(REG_ITMP3, REG_ITMP2);
2590 M_ALD(REG_ITMP3, RIP, disp);
2591 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2594 M_ICMP(REG_ITMP3, REG_ITMP2);
2595 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2598 emit_label(cd, BRANCH_LABEL_5);
2601 if (super == NULL) {
2602 emit_label(cd, BRANCH_LABEL_1);
2603 emit_label(cd, BRANCH_LABEL_4);
2606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2609 /* array type cast-check */
2611 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2612 M_INTMOVE(s1, REG_A0);
2614 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2615 cr = iptr->sx.s23.s3.c.ref;
2616 disp = dseg_add_unique_address(cd, cr);
2618 patcher_add_patch_ref(jd,
2619 PATCHER_resolve_classref_to_classinfo,
2623 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2626 M_ALD(REG_A1, RIP, disp);
2627 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2630 /* s1 may have been destroyed over the function call */
2631 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2633 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2639 emit_store_dst(jd, iptr, d);
2642 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2648 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2653 super = iptr->sx.s23.s3.c.cls;
2654 superindex = super->index;
2657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2661 M_INTMOVE(s1, REG_ITMP1);
2667 /* if class is not resolved, check which code to call */
2669 if (super == NULL) {
2671 emit_label_beq(cd, BRANCH_LABEL_1);
2673 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2674 iptr->sx.s23.s3.c.ref, 0);
2676 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2677 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2678 emit_label_beq(cd, BRANCH_LABEL_2);
2681 /* interface instanceof code */
2683 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2684 if (super != NULL) {
2686 emit_label_beq(cd, BRANCH_LABEL_3);
2689 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2691 if (super == NULL) {
2692 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2693 iptr->sx.s23.s3.c.ref, 0);
2697 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2698 M_ICMP_IMM32(superindex, REG_ITMP3);
2700 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2703 M_ALD32(REG_ITMP1, REG_ITMP1,
2704 OFFSET(vftbl_t, interfacetable[0]) -
2705 superindex * sizeof(methodptr*));
2710 emit_label_br(cd, BRANCH_LABEL_4);
2712 emit_label(cd, BRANCH_LABEL_3);
2715 /* class instanceof code */
2717 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2718 if (super == NULL) {
2719 emit_label(cd, BRANCH_LABEL_2);
2721 cr = iptr->sx.s23.s3.c.ref;
2722 disp = dseg_add_unique_address(cd, cr);
2724 patcher_add_patch_ref(jd,
2725 PATCHER_resolve_classref_to_vftbl,
2730 emit_label_beq(cd, BRANCH_LABEL_5);
2732 disp = dseg_add_address(cd, super->vftbl);
2735 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2736 M_ALD(REG_ITMP2, RIP, disp);
2738 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2739 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2740 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2742 M_ISUB(REG_ITMP2, REG_ITMP1);
2743 M_CLR(d); /* may be REG_ITMP2 */
2744 M_ICMP(REG_ITMP3, REG_ITMP1);
2748 emit_label(cd, BRANCH_LABEL_5);
2751 if (super == NULL) {
2752 emit_label(cd, BRANCH_LABEL_1);
2753 emit_label(cd, BRANCH_LABEL_4);
2756 emit_store_dst(jd, iptr, d);
2760 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2762 /* check for negative sizes and copy sizes to stack if necessary */
2764 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2766 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2768 /* copy SAVEDVAR sizes to stack */
2769 var = VAR(iptr->sx.s23.s2.args[s1]);
2771 /* Already Preallocated? */
2772 if (!(var->flags & PREALLOC)) {
2773 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2774 M_LST(s2, REG_SP, s1 * 8);
2778 /* a0 = dimension count */
2780 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2782 /* is a patcher function set? */
2784 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2785 cr = iptr->sx.s23.s3.c.ref;
2786 disp = dseg_add_unique_address(cd, cr);
2788 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2792 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2795 /* a1 = classinfo */
2797 M_ALD(REG_A1, RIP, disp);
2799 /* a2 = pointer to dimensions = stack pointer */
2801 M_MOV(REG_SP, REG_A2);
2803 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2806 /* check for exception before result assignment */
2808 emit_exception_check(cd, iptr);
2810 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2811 M_INTMOVE(REG_RESULT, s1);
2812 emit_store_dst(jd, iptr, s1);
2816 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2821 } /* for instruction */
2823 MCODECHECK(512); /* XXX require a lower number? */
2825 /* At the end of a basic block we may have to append some nops,
2826 because the patcher stub calling code might be longer than the
2827 actual instruction. So codepatching does not change the
2828 following block unintentionally. */
2830 if (cd->mcodeptr < cd->lastmcodeptr) {
2831 while (cd->mcodeptr < cd->lastmcodeptr) {
2836 } /* if (bptr -> flags >= BBREACHED) */
2837 } /* for basic block */
2839 /* Generate patcher traps. */
2841 emit_patcher_traps(jd);
2843 /* everything's ok */
2849 /* codegen_emit_stub_native ****************************************************
2851 Emits a stub routine which calls a native method.
2853 *******************************************************************************/
2855 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2869 /* Get required compiler data. */
2875 /* initialize variables */
2879 /* calculate stack frame size */
2881 cd->stackframesize =
2882 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2883 sizeof(localref_table) / SIZEOF_VOID_P +
2885 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2888 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2890 /* create method header */
2892 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2893 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2894 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2895 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2896 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2898 #if defined(ENABLE_PROFILING)
2899 /* generate native method profiling code */
2901 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2902 /* count frequency */
2904 M_MOV_IMM(code, REG_ITMP3);
2905 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2909 /* generate stub code */
2911 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2913 #if defined(ENABLE_GC_CACAO)
2914 /* Save callee saved integer registers in stackframeinfo (GC may
2915 need to recover them during a collection). */
2917 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2918 OFFSET(stackframeinfo_t, intregs);
2920 for (i = 0; i < INT_SAV_CNT; i++)
2921 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2924 /* save integer and float argument registers */
2926 for (i = 0; i < md->paramcount; i++) {
2927 if (!md->params[i].inmemory) {
2928 s1 = md->params[i].regoff;
2930 switch (md->paramtypes[i].type) {
2934 M_LST(s1, REG_SP, i * 8);
2938 M_DST(s1, REG_SP, i * 8);
2944 /* create dynamic stack info */
2946 M_MOV(REG_SP, REG_A0);
2947 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2948 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2951 /* remember class argument */
2953 if (m->flags & ACC_STATIC)
2954 M_MOV(REG_RESULT, REG_ITMP2);
2956 /* restore integer and float argument registers */
2958 for (i = 0; i < md->paramcount; i++) {
2959 if (!md->params[i].inmemory) {
2960 s1 = md->params[i].regoff;
2962 switch (md->paramtypes[i].type) {
2966 M_LLD(s1, REG_SP, i * 8);
2970 M_DLD(s1, REG_SP, i * 8);
2976 /* Copy or spill arguments to new locations. */
2978 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2979 s2 = nmd->params[j].regoff;
2981 switch (md->paramtypes[i].type) {
2985 if (!md->params[i].inmemory) {
2986 s1 = md->params[i].regoff;
2988 if (!nmd->params[j].inmemory)
2991 M_LST(s1, REG_SP, s2);
2994 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2995 M_LLD(REG_ITMP1, REG_SP, s1);
2996 M_LST(REG_ITMP1, REG_SP, s2);
3000 /* We only copy spilled float arguments, as the float
3001 argument registers keep unchanged. */
3003 if (md->params[i].inmemory) {
3004 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3006 M_FLD(REG_FTMP1, REG_SP, s1);
3007 M_FST(REG_FTMP1, REG_SP, s2);
3011 if (md->params[i].inmemory) {
3012 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3013 M_DLD(REG_FTMP1, REG_SP, s1);
3014 M_DST(REG_FTMP1, REG_SP, s2);
3020 /* Handle native Java methods. */
3022 if (m->flags & ACC_NATIVE) {
3023 /* put class into second argument register */
3025 if (m->flags & ACC_STATIC)
3026 M_MOV(REG_ITMP2, REG_A1);
3028 /* put env into first argument register */
3030 M_MOV_IMM(VM_get_jnienv(), REG_A0);
3033 /* Call the native function. */
3035 disp = dseg_add_functionptr(cd, f);
3036 M_ALD(REG_ITMP1, RIP, disp);
3039 /* save return value */
3041 switch (md->returntype.type) {
3045 switch (md->returntype.primitivetype) {
3046 case PRIMITIVETYPE_BOOLEAN:
3047 M_BZEXT(REG_RESULT, REG_RESULT);
3049 case PRIMITIVETYPE_BYTE:
3050 M_BSEXT(REG_RESULT, REG_RESULT);
3052 case PRIMITIVETYPE_CHAR:
3053 M_CZEXT(REG_RESULT, REG_RESULT);
3055 case PRIMITIVETYPE_SHORT:
3056 M_SSEXT(REG_RESULT, REG_RESULT);
3059 M_LST(REG_RESULT, REG_SP, 0 * 8);
3063 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3069 /* remove native stackframe info */
3071 M_MOV(REG_SP, REG_A0);
3072 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3073 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3075 M_MOV(REG_RESULT, REG_ITMP3);
3077 /* restore return value */
3079 switch (md->returntype.type) {
3083 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3087 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3093 #if defined(ENABLE_GC_CACAO)
3094 /* Restore callee saved integer registers from stackframeinfo (GC
3095 might have modified them during a collection). */
3097 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3098 OFFSET(stackframeinfo_t, intregs);
3100 for (i = 0; i < INT_SAV_CNT; i++)
3101 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3104 /* remove stackframe */
3106 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3108 /* test for exception */
3114 /* handle exception */
3116 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3117 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3118 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3120 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3126 * These are local overrides for various environment variables in Emacs.
3127 * Please do not remove this and leave it at the end of the file, where
3128 * Emacs will automagically detect them.
3129 * ---------------------------------------------------------------------
3132 * indent-tabs-mode: t
3136 * vim:noexpandtab:sw=4:ts=4: