1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 #include "vm/jit/x86_64/arch.h"
39 #include "vm/jit/x86_64/codegen.h"
40 #include "vm/jit/x86_64/emit.h"
42 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/localref.h"
46 #include "native/native.h"
48 #include "threads/lock-common.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/stringlocal.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/code.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/emit-common.h"
62 #include "vm/jit/jit.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.h"
70 #if defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
74 #include "vmcore/loader.h"
75 #include "vmcore/options.h"
76 #include "vmcore/statistics.h"
79 /* codegen_emit ****************************************************************
81 Generates machine code.
83 *******************************************************************************/
85 bool codegen_emit(jitdata *jd)
91 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 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
160 /* XXX Remove this "offset by one". */
162 code->synchronizedoffset = (rd->memuse + 1) * 8;
164 /* REMOVEME dummy IsSync */
165 (void) dseg_add_unique_s4(cd, 0);
167 if (code_is_leafmethod(code))
168 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
170 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
172 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
173 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
175 (void) dseg_addlinenumbertablesize(cd);
177 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
179 /* create exception table */
181 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
182 dseg_add_target(cd, ex->start);
183 dseg_add_target(cd, ex->end);
184 dseg_add_target(cd, ex->handler);
185 (void) dseg_add_unique_address(cd, ex->catchtype.any);
188 #if defined(ENABLE_PROFILING)
189 /* generate method profiling code */
191 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
192 /* count frequency */
194 M_MOV_IMM(code, REG_ITMP3);
195 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
201 /* create stack frame (if necessary) */
203 if (cd->stackframesize)
204 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
206 /* save used callee saved registers */
208 p = cd->stackframesize;
209 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
210 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
212 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
213 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
216 /* take arguments out of register or stack frame */
220 for (p = 0, l = 0; p < md->paramcount; p++) {
221 t = md->paramtypes[p].type;
223 varindex = jd->local_map[l * 5 + t];
226 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
229 if (varindex == UNUSED)
234 s1 = md->params[p].regoff;
236 if (IS_INT_LNG_TYPE(t)) { /* integer args */
237 if (!md->params[p].inmemory) { /* register arguments */
238 if (!IS_INMEMORY(var->flags))
239 M_INTMOVE(s1, var->vv.regoff);
241 M_LST(s1, REG_SP, var->vv.regoff);
243 else { /* stack arguments */
244 if (!IS_INMEMORY(var->flags))
245 /* + 8 for return address */
246 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
248 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
251 else { /* floating args */
252 if (!md->params[p].inmemory) { /* register arguments */
253 if (!IS_INMEMORY(var->flags))
254 M_FLTMOVE(s1, var->vv.regoff);
256 M_DST(s1, REG_SP, var->vv.regoff);
258 else { /* stack arguments */
259 if (!IS_INMEMORY(var->flags))
260 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
262 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
267 /* save monitorenter argument */
269 #if defined(ENABLE_THREADS)
270 if (checksync && code_is_synchronized(code)) {
271 /* stack offset for monitor argument */
275 if (opt_verbosecall) {
276 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
278 for (p = 0; p < INT_ARG_CNT; p++)
279 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
281 for (p = 0; p < FLT_ARG_CNT; p++)
282 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
284 s1 += INT_ARG_CNT + FLT_ARG_CNT;
287 /* decide which monitor enter function to call */
289 if (m->flags & ACC_STATIC) {
290 M_MOV_IMM(&m->class->object.header, REG_A0);
295 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
298 M_AST(REG_A0, REG_SP, s1 * 8);
299 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
302 if (opt_verbosecall) {
303 for (p = 0; p < INT_ARG_CNT; p++)
304 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
306 for (p = 0; p < FLT_ARG_CNT; p++)
307 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
309 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
315 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
316 emit_verbosecall_enter(jd);
317 #endif /* !defined(NDEBUG) */
321 /* end of header generation */
323 /* create replacement points */
325 REPLACEMENT_POINTS_INIT(cd, jd);
327 /* walk through all basic blocks */
329 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
331 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
333 if (bptr->flags >= BBREACHED) {
335 /* branch resolving */
337 codegen_resolve_branchrefs(cd, bptr);
339 /* handle replacement points */
341 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
343 /* copy interface registers to their destination */
348 #if defined(ENABLE_PROFILING)
349 /* generate basicblock profiling code */
351 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
352 /* count frequency */
354 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
355 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
357 /* if this is an exception handler, start profiling again */
359 if (bptr->type == BBTYPE_EXH)
364 #if defined(ENABLE_LSRA)
368 src = bptr->invars[len];
369 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
370 if (bptr->type == BBTYPE_EXH) {
371 /* d = reg_of_var(rd, src, REG_ITMP1); */
372 if (!IS_INMEMORY(src->flags))
376 M_INTMOVE(REG_ITMP1, d);
377 emit_store(jd, NULL, src, d);
387 var = VAR(bptr->invars[len]);
388 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
389 if (bptr->type == BBTYPE_EXH) {
390 d = codegen_reg_of_var(0, var, REG_ITMP1);
391 M_INTMOVE(REG_ITMP1, d);
392 emit_store(jd, NULL, var, d);
396 assert((var->flags & INOUT));
399 #if defined(ENABLE_LSRA)
402 /* walk through all instructions */
407 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
408 if (iptr->line != currentline) {
409 dseg_addlinenumber(cd, iptr->line);
410 currentline = iptr->line;
413 MCODECHECK(1024); /* 1KB should be enough */
416 case ICMD_NOP: /* ... ==> ... */
417 case ICMD_POP: /* ..., value ==> ... */
418 case ICMD_POP2: /* ..., value, value ==> ... */
421 case ICMD_INLINE_START:
423 REPLACEMENT_POINT_INLINE_START(cd, iptr);
426 case ICMD_INLINE_BODY:
428 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
429 dseg_addlinenumber_inline_start(cd, iptr);
430 dseg_addlinenumber(cd, iptr->line);
433 case ICMD_INLINE_END:
435 dseg_addlinenumber_inline_end(cd, iptr);
436 dseg_addlinenumber(cd, iptr->line);
439 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
442 emit_nullpointer_check(cd, iptr, s1);
445 /* constant operations ************************************************/
447 case ICMD_ICONST: /* ... ==> ..., constant */
449 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
450 ICONST(d, iptr->sx.val.i);
451 emit_store_dst(jd, iptr, d);
454 case ICMD_LCONST: /* ... ==> ..., constant */
456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
457 LCONST(d, iptr->sx.val.l);
458 emit_store_dst(jd, iptr, d);
461 case ICMD_FCONST: /* ... ==> ..., constant */
463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
464 disp = dseg_add_float(cd, iptr->sx.val.f);
465 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_DCONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
472 disp = dseg_add_double(cd, iptr->sx.val.d);
473 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_ACONST: /* ... ==> ..., constant */
479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
481 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
482 cr = iptr->sx.val.c.ref;
483 disp = dseg_add_unique_address(cd, cr);
485 /* PROFILE_CYCLE_STOP; */
487 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
490 /* PROFILE_CYCLE_START; */
495 if (iptr->sx.val.anyptr == 0) {
499 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
503 emit_store_dst(jd, iptr, d);
507 /* load/store/copy/move operations ************************************/
509 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
510 case ICMD_ALOAD: /* s1 = local variable */
514 case ICMD_ISTORE: /* ..., value ==> ... */
525 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
529 /* integer operations *************************************************/
531 case ICMD_INEG: /* ..., value ==> ..., - value */
533 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
537 emit_store_dst(jd, iptr, d);
540 case ICMD_LNEG: /* ..., value ==> ..., - value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
546 emit_store_dst(jd, iptr, d);
549 case ICMD_I2L: /* ..., value ==> ..., value */
551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_L2I: /* ..., value ==> ..., value */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
562 emit_store_dst(jd, iptr, d);
565 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
578 emit_store_dst(jd, iptr, d);
581 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
586 emit_store_dst(jd, iptr, d);
590 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
601 emit_store_dst(jd, iptr, d);
605 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
606 /* sx.val.i = constant */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
611 /* Using inc and dec is not faster than add (tested with
615 M_IADD_IMM(iptr->sx.val.i, d);
616 emit_store_dst(jd, iptr, d);
619 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630 emit_store_dst(jd, iptr, d);
633 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
634 /* sx.val.l = constant */
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
639 if (IS_IMM32(iptr->sx.val.l))
640 M_LADD_IMM(iptr->sx.val.l, d);
642 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
643 M_LADD(REG_ITMP2, d);
645 emit_store_dst(jd, iptr, d);
648 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
650 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
651 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
654 M_INTMOVE(s1, REG_ITMP1);
655 M_ISUB(s2, REG_ITMP1);
656 M_INTMOVE(REG_ITMP1, d);
661 emit_store_dst(jd, iptr, d);
664 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
665 /* sx.val.i = constant */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
670 M_ISUB_IMM(iptr->sx.val.i, d);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680 M_INTMOVE(s1, REG_ITMP1);
681 M_LSUB(s2, REG_ITMP1);
682 M_INTMOVE(REG_ITMP1, d);
687 emit_store_dst(jd, iptr, d);
690 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
691 /* sx.val.l = constant */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
696 if (IS_IMM32(iptr->sx.val.l))
697 M_LSUB_IMM(iptr->sx.val.l, d);
699 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
700 M_LSUB(REG_ITMP2, d);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
716 emit_store_dst(jd, iptr, d);
719 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
720 /* sx.val.i = constant */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
724 if (iptr->sx.val.i == 2) {
728 M_IMUL_IMM(s1, iptr->sx.val.i, d);
729 emit_store_dst(jd, iptr, d);
732 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
743 emit_store_dst(jd, iptr, d);
746 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
747 /* sx.val.l = constant */
749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
751 if (IS_IMM32(iptr->sx.val.l))
752 M_LMUL_IMM(s1, iptr->sx.val.l, d);
754 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
756 M_LMUL(REG_ITMP2, d);
758 emit_store_dst(jd, iptr, d);
761 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
763 s1 = emit_load_s1(jd, iptr, RAX);
764 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
765 d = codegen_reg_of_dst(jd, iptr, RAX);
768 M_INTMOVE(s2, REG_ITMP3);
769 emit_arithmetic_check(cd, iptr, REG_ITMP3);
771 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
773 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
775 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
776 M_BEQ(1 + 3); /* 6 bytes */
778 emit_cltd(cd); /* 1 byte */
779 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
782 emit_store_dst(jd, iptr, d);
783 dst = VAROP(iptr->dst);
784 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
785 M_MOV(REG_ITMP2, RDX); /* restore RDX */
788 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
790 s1 = emit_load_s1(jd, iptr, RAX);
791 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
792 d = codegen_reg_of_dst(jd, iptr, RDX);
795 M_INTMOVE(s2, REG_ITMP3);
796 emit_arithmetic_check(cd, iptr, REG_ITMP3);
798 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
800 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
802 M_CLR(RDX); /* 3 bytes */
803 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
804 M_BEQ(1 + 3); /* 6 bytes */
806 emit_cltd(cd); /* 1 byte */
807 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
810 emit_store_dst(jd, iptr, d);
811 dst = VAROP(iptr->dst);
812 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
813 M_MOV(REG_ITMP2, RDX); /* restore RDX */
816 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
817 /* sx.val.i = constant */
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
821 M_INTMOVE(s1, REG_ITMP1);
822 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
823 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
824 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
825 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
826 emit_mov_reg_reg(cd, REG_ITMP1, d);
827 emit_store_dst(jd, iptr, d);
830 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
831 /* sx.val.i = constant */
833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
834 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
835 M_INTMOVE(s1, REG_ITMP1);
836 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
837 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
838 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
839 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
840 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
841 emit_mov_reg_reg(cd, REG_ITMP1, d);
842 emit_store_dst(jd, iptr, d);
846 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
848 s1 = emit_load_s1(jd, iptr, RAX);
849 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
850 d = codegen_reg_of_dst(jd, iptr, RAX);
853 M_INTMOVE(s2, REG_ITMP3);
854 emit_arithmetic_check(cd, iptr, REG_ITMP3);
856 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
858 /* check as described in jvm spec */
859 disp = dseg_add_s8(cd, 0x8000000000000000LL);
860 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
862 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
863 M_BEQ(2 + 3); /* 6 bytes */
865 emit_cqto(cd); /* 2 bytes */
866 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
869 emit_store_dst(jd, iptr, d);
870 dst = VAROP(iptr->dst);
871 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
872 M_MOV(REG_ITMP2, RDX); /* restore RDX */
875 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
877 s1 = emit_load_s1(jd, iptr, RAX);
878 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
879 d = codegen_reg_of_dst(jd, iptr, RDX);
882 M_INTMOVE(s2, REG_ITMP3);
883 emit_arithmetic_check(cd, iptr, REG_ITMP3);
885 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
887 /* check as described in jvm spec */
888 disp = dseg_add_s8(cd, 0x8000000000000000LL);
889 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
891 M_LXOR(RDX, RDX); /* 3 bytes */
892 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
893 M_BEQ(2 + 3); /* 6 bytes */
895 emit_cqto(cd); /* 2 bytes */
896 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
899 emit_store_dst(jd, iptr, d);
900 dst = VAROP(iptr->dst);
901 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
902 M_MOV(REG_ITMP2, RDX); /* restore RDX */
905 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
906 /* sx.val.i = constant */
908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
910 M_INTMOVE(s1, REG_ITMP1);
911 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
912 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
913 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
914 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
915 emit_mov_reg_reg(cd, REG_ITMP1, d);
916 emit_store_dst(jd, iptr, d);
919 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
920 /* sx.val.l = constant */
922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
924 M_INTMOVE(s1, REG_ITMP1);
925 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
926 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
927 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
928 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
929 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
930 emit_mov_reg_reg(cd, REG_ITMP1, d);
931 emit_store_dst(jd, iptr, d);
934 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
936 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
937 emit_ishift(jd, SHIFT_SHL, iptr);
940 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
941 /* sx.val.i = constant */
943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
946 M_ISLL_IMM(iptr->sx.val.i, d);
947 emit_store_dst(jd, iptr, d);
950 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
952 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
953 emit_ishift(jd, SHIFT_SAR, iptr);
956 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
957 /* sx.val.i = constant */
959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
960 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
962 M_ISRA_IMM(iptr->sx.val.i, d);
963 emit_store_dst(jd, iptr, d);
966 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
968 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
969 emit_ishift(jd, SHIFT_SHR, iptr);
972 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
973 /* sx.val.i = constant */
975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
976 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
978 M_ISRL_IMM(iptr->sx.val.i, d);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
984 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
985 emit_lshift(jd, SHIFT_SHL, iptr);
988 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
989 /* sx.val.i = constant */
991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
994 M_LSLL_IMM(iptr->sx.val.i, d);
995 emit_store_dst(jd, iptr, d);
998 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1000 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1001 emit_lshift(jd, SHIFT_SAR, iptr);
1004 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1005 /* sx.val.i = constant */
1007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1008 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1010 M_LSRA_IMM(iptr->sx.val.i, d);
1011 emit_store_dst(jd, iptr, d);
1014 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1016 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1017 emit_lshift(jd, SHIFT_SHR, iptr);
1020 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1021 /* sx.val.l = constant */
1023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1024 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026 M_LSRL_IMM(iptr->sx.val.i, d);
1027 emit_store_dst(jd, iptr, d);
1030 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1032 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1033 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1045 /* sx.val.i = constant */
1047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1048 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1050 M_IAND_IMM(iptr->sx.val.i, d);
1051 emit_store_dst(jd, iptr, d);
1054 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1057 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1058 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 emit_store_dst(jd, iptr, d);
1068 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1069 /* sx.val.l = constant */
1071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1072 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1074 if (IS_IMM32(iptr->sx.val.l))
1075 M_LAND_IMM(iptr->sx.val.l, d);
1077 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1078 M_LAND(REG_ITMP2, d);
1080 emit_store_dst(jd, iptr, d);
1083 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1094 emit_store_dst(jd, iptr, d);
1097 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1098 /* sx.val.i = constant */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1103 M_IOR_IMM(iptr->sx.val.i, d);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1118 emit_store_dst(jd, iptr, d);
1121 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1122 /* sx.val.l = constant */
1124 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1125 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1127 if (IS_IMM32(iptr->sx.val.l))
1128 M_LOR_IMM(iptr->sx.val.l, d);
1130 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1131 M_LOR(REG_ITMP2, d);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1147 emit_store_dst(jd, iptr, d);
1150 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1151 /* sx.val.i = constant */
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1156 M_IXOR_IMM(iptr->sx.val.i, d);
1157 emit_store_dst(jd, iptr, d);
1160 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1164 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1171 emit_store_dst(jd, iptr, d);
1174 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1175 /* sx.val.l = constant */
1177 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1180 if (IS_IMM32(iptr->sx.val.l))
1181 M_LXOR_IMM(iptr->sx.val.l, d);
1183 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1184 M_LXOR(REG_ITMP2, d);
1186 emit_store_dst(jd, iptr, d);
1190 /* floating operations ************************************************/
1192 case ICMD_FNEG: /* ..., value ==> ..., - value */
1194 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1195 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1196 disp = dseg_add_s4(cd, 0x80000000);
1198 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1199 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_DNEG: /* ..., value ==> ..., - value */
1205 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1206 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1207 disp = dseg_add_s8(cd, 0x8000000000000000);
1209 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1210 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1211 emit_store_dst(jd, iptr, d);
1214 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1216 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1217 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1218 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1225 emit_store_dst(jd, iptr, d);
1228 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1230 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1231 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1232 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239 emit_store_dst(jd, iptr, d);
1242 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1244 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1245 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1246 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1248 M_FLTMOVE(s2, REG_FTMP2);
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1258 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1260 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1262 M_FLTMOVE(s2, REG_FTMP2);
1267 emit_store_dst(jd, iptr, d);
1270 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1272 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1273 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1274 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1286 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1287 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1288 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1300 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1301 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1302 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1304 M_FLTMOVE(s2, REG_FTMP2);
1309 emit_store_dst(jd, iptr, d);
1312 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1314 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1315 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1316 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1318 M_FLTMOVE(s2, REG_FTMP2);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1328 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1329 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1331 emit_store_dst(jd, iptr, d);
1334 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1337 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1353 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1355 emit_store_dst(jd, iptr, d);
1358 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1360 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1361 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1363 M_ICMP_IMM(0x80000000, d); /* corner cases */
1364 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1365 ((REG_RESULT == d) ? 0 : 3);
1367 M_FLTMOVE(s1, REG_FTMP1);
1368 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1370 M_INTMOVE(REG_RESULT, d);
1371 emit_store_dst(jd, iptr, d);
1374 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1376 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1379 M_ICMP_IMM(0x80000000, d); /* corner cases */
1380 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1381 ((REG_RESULT == d) ? 0 : 3);
1383 M_FLTMOVE(s1, REG_FTMP1);
1384 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1386 M_INTMOVE(REG_RESULT, d);
1387 emit_store_dst(jd, iptr, d);
1390 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1392 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1393 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1395 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1396 M_LCMP(REG_ITMP2, d); /* corner cases */
1397 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1398 ((REG_RESULT == d) ? 0 : 3);
1400 M_FLTMOVE(s1, REG_FTMP1);
1401 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1403 M_INTMOVE(REG_RESULT, d);
1404 emit_store_dst(jd, iptr, d);
1407 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1409 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1410 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1412 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1413 M_LCMP(REG_ITMP2, d); /* corner cases */
1414 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1415 ((REG_RESULT == d) ? 0 : 3);
1417 M_FLTMOVE(s1, REG_FTMP1);
1418 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1420 M_INTMOVE(REG_RESULT, d);
1421 emit_store_dst(jd, iptr, d);
1424 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1426 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1427 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1429 emit_store_dst(jd, iptr, d);
1432 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1434 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1435 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1437 emit_store_dst(jd, iptr, d);
1440 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1441 /* == => 0, < => 1, > => -1 */
1443 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1444 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1445 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1447 M_MOV_IMM(1, REG_ITMP1);
1448 M_MOV_IMM(-1, REG_ITMP2);
1449 emit_ucomiss_reg_reg(cd, s1, s2);
1450 M_CMOVULT(REG_ITMP1, d);
1451 M_CMOVUGT(REG_ITMP2, d);
1452 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1453 emit_store_dst(jd, iptr, d);
1456 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1457 /* == => 0, < => 1, > => -1 */
1459 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1460 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1461 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1463 M_MOV_IMM(1, REG_ITMP1);
1464 M_MOV_IMM(-1, REG_ITMP2);
1465 emit_ucomiss_reg_reg(cd, s1, s2);
1466 M_CMOVULT(REG_ITMP1, d);
1467 M_CMOVUGT(REG_ITMP2, d);
1468 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1469 emit_store_dst(jd, iptr, d);
1472 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1473 /* == => 0, < => 1, > => -1 */
1475 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1476 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1477 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1479 M_MOV_IMM(1, REG_ITMP1);
1480 M_MOV_IMM(-1, REG_ITMP2);
1481 emit_ucomisd_reg_reg(cd, s1, s2);
1482 M_CMOVULT(REG_ITMP1, d);
1483 M_CMOVUGT(REG_ITMP2, d);
1484 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1485 emit_store_dst(jd, iptr, d);
1488 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1489 /* == => 0, < => 1, > => -1 */
1491 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1493 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1495 M_MOV_IMM(1, REG_ITMP1);
1496 M_MOV_IMM(-1, REG_ITMP2);
1497 emit_ucomisd_reg_reg(cd, s1, s2);
1498 M_CMOVULT(REG_ITMP1, d);
1499 M_CMOVUGT(REG_ITMP2, d);
1500 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1501 emit_store_dst(jd, iptr, d);
1505 /* memory operations **************************************************/
1507 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1511 /* implicit null-pointer check */
1512 M_ILD(d, s1, OFFSET(java_array_t, size));
1513 emit_store_dst(jd, iptr, d);
1516 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1519 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1520 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1521 /* implicit null-pointer check */
1522 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1523 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1524 emit_store_dst(jd, iptr, d);
1527 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1532 /* implicit null-pointer check */
1533 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1534 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1535 emit_store_dst(jd, iptr, d);
1538 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1541 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1543 /* implicit null-pointer check */
1544 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1545 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1546 emit_store_dst(jd, iptr, d);
1549 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1552 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1554 /* implicit null-pointer check */
1555 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1556 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1557 emit_store_dst(jd, iptr, d);
1560 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1563 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1565 /* implicit null-pointer check */
1566 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1567 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1568 emit_store_dst(jd, iptr, d);
1571 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1574 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1575 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1576 /* implicit null-pointer check */
1577 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1578 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1579 emit_store_dst(jd, iptr, d);
1582 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1585 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1586 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1587 /* implicit null-pointer check */
1588 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1589 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1590 emit_store_dst(jd, iptr, d);
1593 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1596 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1597 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1598 /* implicit null-pointer check */
1599 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1600 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1601 emit_store_dst(jd, iptr, d);
1605 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1608 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1609 /* implicit null-pointer check */
1610 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1611 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1612 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1615 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1618 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1619 /* implicit null-pointer check */
1620 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1621 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1622 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1625 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1629 /* implicit null-pointer check */
1630 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1631 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1632 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1635 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1639 /* implicit null-pointer check */
1640 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1645 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1649 /* implicit null-pointer check */
1650 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1651 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1652 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1655 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1659 /* implicit null-pointer check */
1660 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1661 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1662 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1665 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1669 /* implicit null-pointer check */
1670 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1671 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1672 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1675 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1679 /* implicit null-pointer check */
1680 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1681 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1685 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1687 emit_arraystore_check(cd, iptr);
1689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1692 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1696 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1700 /* implicit null-pointer check */
1701 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1702 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1705 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1708 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1709 /* implicit null-pointer check */
1710 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1711 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1714 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1717 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1718 /* implicit null-pointer check */
1719 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1720 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1723 case ICMD_IASTORECONST: /* ..., 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_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1732 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1736 /* implicit null-pointer check */
1737 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1739 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1740 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1743 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1744 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1748 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1752 /* implicit null-pointer check */
1753 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1754 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1758 case ICMD_GETSTATIC: /* ... ==> ..., value */
1760 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1761 uf = iptr->sx.s23.s3.uf;
1762 fieldtype = uf->fieldref->parseddesc.fd->type;
1763 disp = dseg_add_unique_address(cd, uf);
1765 /* PROFILE_CYCLE_STOP; */
1767 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1769 /* PROFILE_CYCLE_START; */
1772 fi = iptr->sx.s23.s3.fmiref->p.field;
1773 fieldtype = fi->type;
1774 disp = dseg_add_address(cd, fi->value);
1776 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1779 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1782 PROFILE_CYCLE_START;
1786 /* This approach is much faster than moving the field
1787 address inline into a register. */
1789 M_ALD(REG_ITMP1, RIP, disp);
1791 switch (fieldtype) {
1793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1794 M_ILD(d, REG_ITMP1, 0);
1798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1799 M_LLD(d, REG_ITMP1, 0);
1802 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1803 M_FLD(d, REG_ITMP1, 0);
1806 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1807 M_DLD(d, REG_ITMP1, 0);
1810 emit_store_dst(jd, iptr, d);
1813 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816 uf = iptr->sx.s23.s3.uf;
1817 fieldtype = uf->fieldref->parseddesc.fd->type;
1818 disp = dseg_add_unique_address(cd, uf);
1820 /* PROFILE_CYCLE_STOP; */
1822 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1824 /* PROFILE_CYCLE_START; */
1827 fi = iptr->sx.s23.s3.fmiref->p.field;
1828 fieldtype = fi->type;
1829 disp = dseg_add_address(cd, fi->value);
1831 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1834 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1837 PROFILE_CYCLE_START;
1841 /* This approach is much faster than moving the field
1842 address inline into a register. */
1844 M_ALD(REG_ITMP1, RIP, disp);
1846 switch (fieldtype) {
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1849 M_IST(s1, REG_ITMP1, 0);
1853 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1854 M_LST(s1, REG_ITMP1, 0);
1857 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1858 M_FST(s1, REG_ITMP1, 0);
1861 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1862 M_DST(s1, REG_ITMP1, 0);
1867 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1868 /* val = value (in current instruction) */
1869 /* following NOP) */
1871 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1872 uf = iptr->sx.s23.s3.uf;
1873 fieldtype = uf->fieldref->parseddesc.fd->type;
1874 disp = dseg_add_unique_address(cd, uf);
1876 /* PROFILE_CYCLE_STOP; */
1878 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1880 /* PROFILE_CYCLE_START; */
1883 fi = iptr->sx.s23.s3.fmiref->p.field;
1884 fieldtype = fi->type;
1885 disp = dseg_add_address(cd, fi->value);
1887 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1890 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1893 PROFILE_CYCLE_START;
1897 /* This approach is much faster than moving the field
1898 address inline into a register. */
1900 M_ALD(REG_ITMP1, RIP, disp);
1902 switch (fieldtype) {
1905 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1910 if (IS_IMM32(iptr->sx.s23.s2.constval))
1911 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1913 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1914 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1920 case ICMD_GETFIELD: /* ... ==> ..., value */
1922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1924 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1925 uf = iptr->sx.s23.s3.uf;
1926 fieldtype = uf->fieldref->parseddesc.fd->type;
1929 /* PROFILE_CYCLE_STOP; */
1931 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1933 /* PROFILE_CYCLE_START; */
1936 fi = iptr->sx.s23.s3.fmiref->p.field;
1937 fieldtype = fi->type;
1941 /* implicit null-pointer check */
1942 switch (fieldtype) {
1944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1945 M_ILD32(d, s1, disp);
1949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1950 M_LLD32(d, s1, disp);
1953 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1954 M_FLD32(d, s1, disp);
1957 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1958 M_DLD32(d, s1, disp);
1961 emit_store_dst(jd, iptr, d);
1964 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1969 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1970 uf = iptr->sx.s23.s3.uf;
1971 fieldtype = uf->fieldref->parseddesc.fd->type;
1974 /* PROFILE_CYCLE_STOP; */
1976 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1978 /* PROFILE_CYCLE_START; */
1981 fi = iptr->sx.s23.s3.fmiref->p.field;
1982 fieldtype = fi->type;
1986 /* implicit null-pointer check */
1987 switch (fieldtype) {
1989 M_IST32(s2, s1, disp);
1993 M_LST32(s2, s1, disp);
1996 M_FST32(s2, s1, disp);
1999 M_DST32(s2, s1, disp);
2004 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2005 /* val = value (in current instruction) */
2006 /* following NOP) */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2010 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2011 uf = iptr->sx.s23.s3.uf;
2012 fieldtype = uf->fieldref->parseddesc.fd->type;
2015 /* PROFILE_CYCLE_STOP; */
2017 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
2019 /* PROFILE_CYCLE_START; */
2022 fi = iptr->sx.s23.s3.fmiref->p.field;
2023 fieldtype = fi->type;
2027 /* implicit null-pointer check */
2028 switch (fieldtype) {
2031 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2036 /* XXX why no check for IS_IMM32? */
2037 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2038 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2044 /* branch operations **************************************************/
2046 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2049 M_INTMOVE(s1, REG_ITMP1_XPTR);
2053 #ifdef ENABLE_VERIFIER
2054 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2055 uc = iptr->sx.s23.s2.uc;
2057 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2059 #endif /* ENABLE_VERIFIER */
2061 M_CALL_IMM(0); /* passing exception pc */
2062 M_POP(REG_ITMP2_XPC);
2064 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2068 case ICMD_GOTO: /* ... ==> ... */
2071 emit_br(cd, iptr->dst.block);
2075 case ICMD_JSR: /* ... ==> ... */
2077 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2081 case ICMD_IFNULL: /* ..., value ==> ... */
2082 case ICMD_IFNONNULL:
2084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2086 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2089 case ICMD_IFEQ: /* ..., value ==> ... */
2096 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2097 M_ICMP_IMM(iptr->sx.val.i, s1);
2098 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2101 case ICMD_IF_LEQ: /* ..., value ==> ... */
2108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2109 if (IS_IMM32(iptr->sx.val.l))
2110 M_LCMP_IMM(iptr->sx.val.l, s1);
2112 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2113 M_LCMP(REG_ITMP2, s1);
2115 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2118 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2119 case ICMD_IF_ICMPNE:
2120 case ICMD_IF_ICMPLT:
2121 case ICMD_IF_ICMPGE:
2122 case ICMD_IF_ICMPGT:
2123 case ICMD_IF_ICMPLE:
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_ICMPEQ, BRANCH_OPT_NONE);
2131 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2132 case ICMD_IF_ACMPNE:
2134 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2135 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2137 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2140 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2141 case ICMD_IF_LCMPNE:
2142 case ICMD_IF_LCMPLT:
2143 case ICMD_IF_LCMPGE:
2144 case ICMD_IF_LCMPGT:
2145 case ICMD_IF_LCMPLE:
2147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2148 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2150 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2153 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2156 REPLACEMENT_POINT_RETURN(cd, iptr);
2157 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2158 M_INTMOVE(s1, REG_RESULT);
2159 goto nowperformreturn;
2161 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2163 REPLACEMENT_POINT_RETURN(cd, iptr);
2164 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2165 M_INTMOVE(s1, REG_RESULT);
2167 #ifdef ENABLE_VERIFIER
2168 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2169 uc = iptr->sx.s23.s2.uc;
2173 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2175 PROFILE_CYCLE_START;
2177 #endif /* ENABLE_VERIFIER */
2178 goto nowperformreturn;
2180 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2183 REPLACEMENT_POINT_RETURN(cd, iptr);
2184 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2185 M_FLTMOVE(s1, REG_FRESULT);
2186 goto nowperformreturn;
2188 case ICMD_RETURN: /* ... ==> ... */
2190 REPLACEMENT_POINT_RETURN(cd, iptr);
2196 p = cd->stackframesize;
2198 #if !defined(NDEBUG)
2199 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2200 emit_verbosecall_exit(jd);
2201 #endif /* !defined(NDEBUG) */
2203 #if defined(ENABLE_THREADS)
2204 if (checksync && code_is_synchronized(code)) {
2205 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2207 /* we need to save the proper return value */
2208 switch (iptr->opc) {
2212 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2216 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2220 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2223 /* and now restore the proper return value */
2224 switch (iptr->opc) {
2228 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2232 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2238 /* restore saved registers */
2240 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2241 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2243 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2244 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2247 /* deallocate stack */
2249 if (cd->stackframesize)
2250 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2252 /* generate method profiling code */
2261 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2264 branch_target_t *table;
2266 table = iptr->dst.table;
2268 l = iptr->sx.s23.s2.tablelow;
2269 i = iptr->sx.s23.s3.tablehigh;
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2272 M_INTMOVE(s1, REG_ITMP1);
2275 M_ISUB_IMM(l, REG_ITMP1);
2277 /* number of targets */
2282 M_ICMP_IMM(i - 1, REG_ITMP1);
2283 emit_bugt(cd, table[0].block);
2285 /* build jump table top down and use address of lowest entry */
2290 dseg_add_target(cd, table->block);
2294 /* length of dataseg after last dseg_add_target is used
2297 M_MOV_IMM(0, REG_ITMP2);
2299 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2305 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2308 lookup_target_t *lookup;
2310 lookup = iptr->dst.lookup;
2312 i = iptr->sx.s23.s2.lookupcount;
2314 MCODECHECK(8 + ((7 + 6) * i) + 5);
2315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318 M_ICMP_IMM(lookup->value, s1);
2319 emit_beq(cd, lookup->target.block);
2323 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2329 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2331 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2333 bte = iptr->sx.s23.s3.bte;
2337 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2339 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2340 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2341 case ICMD_INVOKEINTERFACE:
2343 REPLACEMENT_POINT_INVOKE(cd, iptr);
2345 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2347 um = iptr->sx.s23.s3.um;
2348 md = um->methodref->parseddesc.md;
2351 lm = iptr->sx.s23.s3.fmiref->p.method;
2353 md = lm->parseddesc;
2357 s3 = md->paramcount;
2359 MCODECHECK((20 * s3) + 128);
2361 /* copy arguments to registers or stack location */
2363 for (s3 = s3 - 1; s3 >= 0; s3--) {
2364 var = VAR(iptr->sx.s23.s2.args[s3]);
2365 d = md->params[s3].regoff;
2367 /* already preallocated (ARGVAR)? */
2369 if (var->flags & PREALLOC)
2372 if (IS_INT_LNG_TYPE(var->type)) {
2373 if (!md->params[s3].inmemory) {
2374 s1 = emit_load(jd, iptr, var, d);
2378 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2379 M_LST(s1, REG_SP, d);
2383 if (!md->params[s3].inmemory) {
2384 s1 = emit_load(jd, iptr, var, d);
2388 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2390 if (IS_2_WORD_TYPE(var->type))
2391 M_DST(s1, REG_SP, d);
2393 M_FST(s1, REG_SP, d);
2398 /* generate method profiling code */
2402 switch (iptr->opc) {
2404 if (bte->stub == NULL) {
2405 M_MOV_IMM(bte->fp, REG_ITMP1);
2408 M_MOV_IMM(bte->stub, REG_ITMP1);
2413 case ICMD_INVOKESPECIAL:
2414 emit_nullpointer_check(cd, iptr, REG_A0);
2417 case ICMD_INVOKESTATIC:
2419 disp = dseg_add_unique_address(cd, um);
2421 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2425 disp = dseg_add_functionptr(cd, lm->stubroutine);
2428 M_ALD(REG_ITMP2, RIP, disp);
2432 case ICMD_INVOKEVIRTUAL:
2434 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2439 s1 = OFFSET(vftbl_t, table[0]) +
2440 sizeof(methodptr) * lm->vftblindex;
2443 /* implicit null-pointer check */
2444 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2445 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2449 case ICMD_INVOKEINTERFACE:
2451 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2457 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2458 sizeof(methodptr) * lm->class->index;
2460 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2463 /* implicit null-pointer check */
2464 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2465 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2466 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2471 /* generate method profiling code */
2473 PROFILE_CYCLE_START;
2475 /* store size of call code in replacement point */
2477 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2478 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2480 /* store return value */
2482 switch (md->returntype.type) {
2486 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2487 M_INTMOVE(REG_RESULT, s1);
2488 emit_store_dst(jd, iptr, s1);
2492 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2493 M_FLTMOVE(REG_FRESULT, s1);
2494 emit_store_dst(jd, iptr, s1);
2503 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2505 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2506 /* object type cast-check */
2511 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2516 super = iptr->sx.s23.s3.c.cls;
2517 superindex = super->index;
2520 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2521 CODEGEN_CRITICAL_SECTION_NEW;
2523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2525 /* if class is not resolved, check which code to call */
2527 if (super == NULL) {
2529 emit_label_beq(cd, BRANCH_LABEL_1);
2531 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2532 iptr->sx.s23.s3.c.ref, 0);
2534 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2535 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2536 emit_label_beq(cd, BRANCH_LABEL_2);
2539 /* interface checkcast code */
2541 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2542 if (super != NULL) {
2544 emit_label_beq(cd, BRANCH_LABEL_3);
2547 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2549 if (super == NULL) {
2550 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2551 iptr->sx.s23.s3.c.ref,
2556 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2557 M_ICMP_IMM32(superindex, REG_ITMP3);
2558 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2560 M_ALD32(REG_ITMP3, REG_ITMP2,
2561 OFFSET(vftbl_t, interfacetable[0]) -
2562 superindex * sizeof(methodptr*));
2564 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2567 emit_label_br(cd, BRANCH_LABEL_4);
2569 emit_label(cd, BRANCH_LABEL_3);
2572 /* class checkcast code */
2574 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2575 if (super == NULL) {
2576 emit_label(cd, BRANCH_LABEL_2);
2578 cr = iptr->sx.s23.s3.c.ref;
2579 disp = dseg_add_unique_address(cd, cr);
2581 patcher_add_patch_ref(jd,
2582 PATCHER_resolve_classref_to_vftbl,
2587 emit_label_beq(cd, BRANCH_LABEL_5);
2589 disp = dseg_add_address(cd, super->vftbl);
2592 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2593 M_ALD(REG_ITMP3, RIP, disp);
2595 CODEGEN_CRITICAL_SECTION_START;
2597 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2599 /* if (s1 != REG_ITMP1) { */
2600 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2601 /* OFFSET(vftbl_t, baseval), */
2603 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2604 /* OFFSET(vftbl_t, diffval), */
2606 /* #if defined(ENABLE_THREADS) */
2607 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2609 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2613 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2614 M_ISUB(REG_ITMP3, REG_ITMP2);
2615 M_ALD(REG_ITMP3, RIP, disp);
2616 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2619 CODEGEN_CRITICAL_SECTION_END;
2621 M_ICMP(REG_ITMP3, REG_ITMP2);
2622 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2625 emit_label(cd, BRANCH_LABEL_5);
2628 if (super == NULL) {
2629 emit_label(cd, BRANCH_LABEL_1);
2630 emit_label(cd, BRANCH_LABEL_4);
2633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2636 /* array type cast-check */
2638 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2639 M_INTMOVE(s1, REG_A0);
2641 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2642 cr = iptr->sx.s23.s3.c.ref;
2643 disp = dseg_add_unique_address(cd, cr);
2645 patcher_add_patch_ref(jd,
2646 PATCHER_resolve_classref_to_classinfo,
2650 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2653 M_ALD(REG_A1, RIP, disp);
2654 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2657 /* s1 may have been destroyed over the function call */
2658 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2660 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2666 emit_store_dst(jd, iptr, d);
2669 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2675 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2680 super = iptr->sx.s23.s3.c.cls;
2681 superindex = super->index;
2684 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2685 CODEGEN_CRITICAL_SECTION_NEW;
2687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2691 M_INTMOVE(s1, REG_ITMP1);
2697 /* if class is not resolved, check which code to call */
2699 if (super == NULL) {
2701 emit_label_beq(cd, BRANCH_LABEL_1);
2703 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2704 iptr->sx.s23.s3.c.ref, 0);
2706 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2707 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2708 emit_label_beq(cd, BRANCH_LABEL_2);
2711 /* interface instanceof code */
2713 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2714 if (super != NULL) {
2716 emit_label_beq(cd, BRANCH_LABEL_3);
2719 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2721 if (super == NULL) {
2722 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2723 iptr->sx.s23.s3.c.ref, 0);
2727 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2728 M_ICMP_IMM32(superindex, REG_ITMP3);
2730 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2733 M_ALD32(REG_ITMP1, REG_ITMP1,
2734 OFFSET(vftbl_t, interfacetable[0]) -
2735 superindex * sizeof(methodptr*));
2740 emit_label_br(cd, BRANCH_LABEL_4);
2742 emit_label(cd, BRANCH_LABEL_3);
2745 /* class instanceof code */
2747 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2748 if (super == NULL) {
2749 emit_label(cd, BRANCH_LABEL_2);
2751 cr = iptr->sx.s23.s3.c.ref;
2752 disp = dseg_add_unique_address(cd, cr);
2754 patcher_add_patch_ref(jd,
2755 PATCHER_resolve_classref_to_vftbl,
2760 emit_label_beq(cd, BRANCH_LABEL_5);
2762 disp = dseg_add_address(cd, super->vftbl);
2765 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2766 M_ALD(REG_ITMP2, RIP, disp);
2768 CODEGEN_CRITICAL_SECTION_START;
2770 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2771 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2772 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2774 CODEGEN_CRITICAL_SECTION_END;
2776 M_ISUB(REG_ITMP2, REG_ITMP1);
2777 M_CLR(d); /* may be REG_ITMP2 */
2778 M_ICMP(REG_ITMP3, REG_ITMP1);
2782 emit_label(cd, BRANCH_LABEL_5);
2785 if (super == NULL) {
2786 emit_label(cd, BRANCH_LABEL_1);
2787 emit_label(cd, BRANCH_LABEL_4);
2790 emit_store_dst(jd, iptr, d);
2794 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2796 /* check for negative sizes and copy sizes to stack if necessary */
2798 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2800 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2802 /* copy SAVEDVAR sizes to stack */
2803 var = VAR(iptr->sx.s23.s2.args[s1]);
2805 /* Already Preallocated? */
2806 if (!(var->flags & PREALLOC)) {
2807 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2808 M_LST(s2, REG_SP, s1 * 8);
2812 /* a0 = dimension count */
2814 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2816 /* is a patcher function set? */
2818 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2819 cr = iptr->sx.s23.s3.c.ref;
2820 disp = dseg_add_unique_address(cd, cr);
2822 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2826 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2829 /* a1 = classinfo */
2831 M_ALD(REG_A1, RIP, disp);
2833 /* a2 = pointer to dimensions = stack pointer */
2835 M_MOV(REG_SP, REG_A2);
2837 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2840 /* check for exception before result assignment */
2842 emit_exception_check(cd, iptr);
2844 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2845 M_INTMOVE(REG_RESULT, s1);
2846 emit_store_dst(jd, iptr, s1);
2850 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2855 } /* for instruction */
2857 MCODECHECK(512); /* XXX require a lower number? */
2859 /* At the end of a basic block we may have to append some nops,
2860 because the patcher stub calling code might be longer than the
2861 actual instruction. So codepatching does not change the
2862 following block unintentionally. */
2864 if (cd->mcodeptr < cd->lastmcodeptr) {
2865 while (cd->mcodeptr < cd->lastmcodeptr) {
2870 } /* if (bptr -> flags >= BBREACHED) */
2871 } /* for basic block */
2873 dseg_createlinenumbertable(cd);
2875 /* Generate patcher traps. */
2877 emit_patcher_traps(jd);
2879 /* everything's ok */
2885 /* codegen_emit_stub_native ****************************************************
2887 Emits a stub routine which calls a native method.
2889 *******************************************************************************/
2891 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2905 /* Get required compiler data. */
2911 /* initialize variables */
2915 /* calculate stack frame size */
2917 cd->stackframesize =
2918 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2919 sizeof(localref_table) / SIZEOF_VOID_P +
2921 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2924 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2926 /* create method header */
2928 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2929 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2930 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2931 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2932 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2933 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2934 (void) dseg_addlinenumbertablesize(cd);
2935 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2937 #if defined(ENABLE_PROFILING)
2938 /* generate native method profiling code */
2940 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2941 /* count frequency */
2943 M_MOV_IMM(code, REG_ITMP3);
2944 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2948 /* generate stub code */
2950 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2952 #if defined(ENABLE_GC_CACAO)
2953 /* Save callee saved integer registers in stackframeinfo (GC may
2954 need to recover them during a collection). */
2956 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2957 OFFSET(stackframeinfo_t, intregs);
2959 for (i = 0; i < INT_SAV_CNT; i++)
2960 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2963 /* save integer and float argument registers */
2965 for (i = 0; i < md->paramcount; i++) {
2966 if (!md->params[i].inmemory) {
2967 s1 = md->params[i].regoff;
2969 switch (md->paramtypes[i].type) {
2973 M_LST(s1, REG_SP, i * 8);
2977 M_DST(s1, REG_SP, i * 8);
2983 /* create dynamic stack info */
2985 M_MOV(REG_SP, REG_A0);
2986 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2987 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2990 /* remember class argument */
2992 if (m->flags & ACC_STATIC)
2993 M_MOV(REG_RESULT, REG_ITMP2);
2995 /* restore integer and float argument registers */
2997 for (i = 0; i < md->paramcount; i++) {
2998 if (!md->params[i].inmemory) {
2999 s1 = md->params[i].regoff;
3001 switch (md->paramtypes[i].type) {
3005 M_LLD(s1, REG_SP, i * 8);
3009 M_DLD(s1, REG_SP, i * 8);
3015 /* Copy or spill arguments to new locations. */
3017 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3018 s2 = nmd->params[j].regoff;
3020 switch (md->paramtypes[i].type) {
3024 if (!md->params[i].inmemory) {
3025 s1 = md->params[i].regoff;
3027 if (!nmd->params[j].inmemory)
3030 M_LST(s1, REG_SP, s2);
3033 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3034 M_LLD(REG_ITMP1, REG_SP, s1);
3035 M_LST(REG_ITMP1, REG_SP, s2);
3039 /* We only copy spilled float arguments, as the float
3040 argument registers keep unchanged. */
3042 if (md->params[i].inmemory) {
3043 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3045 M_FLD(REG_FTMP1, REG_SP, s1);
3046 M_FST(REG_FTMP1, REG_SP, s2);
3050 if (md->params[i].inmemory) {
3051 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3052 M_DLD(REG_FTMP1, REG_SP, s1);
3053 M_DST(REG_FTMP1, REG_SP, s2);
3059 /* Handle native Java methods. */
3061 if (m->flags & ACC_NATIVE) {
3062 /* put class into second argument register */
3064 if (m->flags & ACC_STATIC)
3065 M_MOV(REG_ITMP2, REG_A1);
3067 /* put env into first argument register */
3069 M_MOV_IMM(_Jv_env, REG_A0);
3072 /* Call the native function. */
3074 disp = dseg_add_functionptr(cd, f);
3075 M_ALD(REG_ITMP1, RIP, disp);
3078 /* save return value */
3080 switch (md->returntype.type) {
3084 M_LST(REG_RESULT, REG_SP, 0 * 8);
3088 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3094 /* remove native stackframe info */
3096 M_MOV(REG_SP, REG_A0);
3097 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3098 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3100 M_MOV(REG_RESULT, REG_ITMP3);
3102 /* restore return value */
3104 switch (md->returntype.type) {
3108 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3112 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3118 #if defined(ENABLE_GC_CACAO)
3119 /* Restore callee saved integer registers from stackframeinfo (GC
3120 might have modified them during a collection). */
3122 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3123 OFFSET(stackframeinfo_t, intregs);
3125 for (i = 0; i < INT_SAV_CNT; i++)
3126 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3129 /* remove stackframe */
3131 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3133 /* test for exception */
3139 /* handle exception */
3141 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3142 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3143 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3145 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3151 * These are local overrides for various environment variables in Emacs.
3152 * Please do not remove this and leave it at the end of the file, where
3153 * Emacs will automagically detect them.
3154 * ---------------------------------------------------------------------
3157 * indent-tabs-mode: t
3161 * vim:noexpandtab:sw=4:ts=4: