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/linenumbertable.h"
64 #include "vm/jit/methodheader.h"
65 #include "vm/jit/parse.h"
66 #include "vm/jit/patcher-common.h"
67 #include "vm/jit/reg.h"
68 #include "vm/jit/replace.h"
69 #include "vm/jit/stacktrace.h"
70 #include "vm/jit/trap.h"
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
76 #include "vmcore/loader.h"
77 #include "vmcore/options.h"
78 #include "vmcore/statistics.h"
81 /* codegen_emit ****************************************************************
83 Generates machine code.
85 *******************************************************************************/
87 bool codegen_emit(jitdata *jd)
93 s4 len, s1, s2, s3, d, disp;
99 constant_classref *cr;
100 unresolved_class *uc;
101 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
102 unresolved_method *um;
103 builtintable_entry *bte;
106 unresolved_field *uf;
110 /* get required compiler data */
117 /* prevent compiler warnings */
130 /* space to save used callee saved registers */
132 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
133 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
135 cd->stackframesize = rd->memuse + savedregs_num;
137 #if defined(ENABLE_THREADS)
138 /* space to save argument of monitor_enter */
140 if (checksync && code_is_synchronized(code))
141 cd->stackframesize++;
144 /* Keep stack of non-leaf functions 16-byte aligned for calls into
145 native code e.g. libc or jni (alignment problems with
148 if (!code_is_leafmethod(code) || opt_verbosecall)
149 cd->stackframesize |= 0x1;
151 /* create method header */
153 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
154 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
156 code->synchronizedoffset = rd->memuse * 8;
158 if (code_is_leafmethod(code))
159 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
161 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
163 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
164 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
166 #if defined(ENABLE_PROFILING)
167 /* generate method profiling code */
169 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
170 /* count frequency */
172 M_MOV_IMM(code, REG_ITMP3);
173 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
179 /* create stack frame (if necessary) */
181 if (cd->stackframesize)
182 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
184 /* save used callee saved registers */
186 p = cd->stackframesize;
187 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
188 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
190 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
191 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
194 /* take arguments out of register or stack frame */
198 for (p = 0, l = 0; p < md->paramcount; p++) {
199 t = md->paramtypes[p].type;
201 varindex = jd->local_map[l * 5 + t];
204 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
207 if (varindex == UNUSED)
212 s1 = md->params[p].regoff;
214 if (IS_INT_LNG_TYPE(t)) { /* integer args */
215 if (!md->params[p].inmemory) { /* register arguments */
216 if (!IS_INMEMORY(var->flags))
217 M_INTMOVE(s1, var->vv.regoff);
219 M_LST(s1, REG_SP, var->vv.regoff);
221 else { /* stack arguments */
222 if (!IS_INMEMORY(var->flags))
223 /* + 8 for return address */
224 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
226 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
229 else { /* floating args */
230 if (!md->params[p].inmemory) { /* register arguments */
231 if (!IS_INMEMORY(var->flags))
232 M_FLTMOVE(s1, var->vv.regoff);
234 M_DST(s1, REG_SP, var->vv.regoff);
236 else { /* stack arguments */
237 if (!IS_INMEMORY(var->flags))
238 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
240 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
245 /* save monitorenter argument */
247 #if defined(ENABLE_THREADS)
248 if (checksync && code_is_synchronized(code)) {
249 /* stack offset for monitor argument */
253 if (opt_verbosecall) {
254 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
256 for (p = 0; p < INT_ARG_CNT; p++)
257 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
259 for (p = 0; p < FLT_ARG_CNT; p++)
260 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
262 s1 += INT_ARG_CNT + FLT_ARG_CNT;
265 /* decide which monitor enter function to call */
267 if (m->flags & ACC_STATIC) {
268 M_MOV_IMM(&m->clazz->object.header, REG_A0);
273 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
276 M_AST(REG_A0, REG_SP, s1 * 8);
277 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
280 if (opt_verbosecall) {
281 for (p = 0; p < INT_ARG_CNT; p++)
282 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
284 for (p = 0; p < FLT_ARG_CNT; p++)
285 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
287 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
293 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
294 emit_verbosecall_enter(jd);
295 #endif /* !defined(NDEBUG) */
299 /* end of header generation */
301 /* create replacement points */
303 REPLACEMENT_POINTS_INIT(cd, jd);
305 /* walk through all basic blocks */
307 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
309 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
311 if (bptr->flags >= BBREACHED) {
313 /* branch resolving */
315 codegen_resolve_branchrefs(cd, bptr);
317 /* handle replacement points */
319 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
321 /* copy interface registers to their destination */
326 #if defined(ENABLE_PROFILING)
327 /* generate basicblock profiling code */
329 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
330 /* count frequency */
332 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
333 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
335 /* if this is an exception handler, start profiling again */
337 if (bptr->type == BBTYPE_EXH)
342 #if defined(ENABLE_LSRA)
346 src = bptr->invars[len];
347 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
348 if (bptr->type == BBTYPE_EXH) {
349 /* d = reg_of_var(rd, src, REG_ITMP1); */
350 if (!IS_INMEMORY(src->flags))
354 M_INTMOVE(REG_ITMP1, d);
355 emit_store(jd, NULL, src, d);
365 var = VAR(bptr->invars[len]);
366 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
367 if (bptr->type == BBTYPE_EXH) {
368 d = codegen_reg_of_var(0, var, REG_ITMP1);
369 M_INTMOVE(REG_ITMP1, d);
370 emit_store(jd, NULL, var, d);
374 assert((var->flags & INOUT));
377 #if defined(ENABLE_LSRA)
380 /* walk through all instructions */
385 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
386 if (iptr->line != currentline) {
387 linenumbertable_list_entry_add(cd, iptr->line);
388 currentline = iptr->line;
391 MCODECHECK(1024); /* 1KB should be enough */
394 case ICMD_NOP: /* ... ==> ... */
395 case ICMD_POP: /* ..., value ==> ... */
396 case ICMD_POP2: /* ..., value, value ==> ... */
399 case ICMD_INLINE_START:
401 REPLACEMENT_POINT_INLINE_START(cd, iptr);
404 case ICMD_INLINE_BODY:
406 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
407 linenumbertable_list_entry_add_inline_start(cd, iptr);
408 linenumbertable_list_entry_add(cd, iptr->line);
411 case ICMD_INLINE_END:
413 linenumbertable_list_entry_add_inline_end(cd, iptr);
414 linenumbertable_list_entry_add(cd, iptr->line);
417 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
420 emit_nullpointer_check(cd, iptr, s1);
423 /* constant operations ************************************************/
425 case ICMD_ICONST: /* ... ==> ..., constant */
427 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
428 ICONST(d, iptr->sx.val.i);
429 emit_store_dst(jd, iptr, d);
432 case ICMD_LCONST: /* ... ==> ..., constant */
434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
435 LCONST(d, iptr->sx.val.l);
436 emit_store_dst(jd, iptr, d);
439 case ICMD_FCONST: /* ... ==> ..., constant */
441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
442 disp = dseg_add_float(cd, iptr->sx.val.f);
443 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
444 emit_store_dst(jd, iptr, d);
447 case ICMD_DCONST: /* ... ==> ..., constant */
449 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
450 disp = dseg_add_double(cd, iptr->sx.val.d);
451 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
452 emit_store_dst(jd, iptr, d);
455 case ICMD_ACONST: /* ... ==> ..., constant */
457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
459 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
460 cr = iptr->sx.val.c.ref;
461 disp = dseg_add_unique_address(cd, cr);
463 /* PROFILE_CYCLE_STOP; */
465 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
468 /* PROFILE_CYCLE_START; */
473 if (iptr->sx.val.anyptr == 0) {
477 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
481 emit_store_dst(jd, iptr, d);
485 /* load/store/copy/move operations ************************************/
487 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
488 case ICMD_ALOAD: /* s1 = local variable */
492 case ICMD_ISTORE: /* ..., value ==> ... */
503 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
507 /* integer operations *************************************************/
509 case ICMD_INEG: /* ..., value ==> ..., - value */
511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
515 emit_store_dst(jd, iptr, d);
518 case ICMD_LNEG: /* ..., value ==> ..., - value */
520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
524 emit_store_dst(jd, iptr, d);
527 case ICMD_I2L: /* ..., value ==> ..., value */
529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
532 emit_store_dst(jd, iptr, d);
535 case ICMD_L2I: /* ..., value ==> ..., value */
537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
548 emit_store_dst(jd, iptr, d);
551 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
556 emit_store_dst(jd, iptr, d);
559 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
564 emit_store_dst(jd, iptr, d);
568 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
579 emit_store_dst(jd, iptr, d);
583 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
584 /* sx.val.i = constant */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
589 /* Using inc and dec is not faster than add (tested with
593 M_IADD_IMM(iptr->sx.val.i, d);
594 emit_store_dst(jd, iptr, d);
597 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
612 /* sx.val.l = constant */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
617 if (IS_IMM32(iptr->sx.val.l))
618 M_LADD_IMM(iptr->sx.val.l, d);
620 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
621 M_LADD(REG_ITMP2, d);
623 emit_store_dst(jd, iptr, d);
626 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
629 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
632 M_INTMOVE(s1, REG_ITMP1);
633 M_ISUB(s2, REG_ITMP1);
634 M_INTMOVE(REG_ITMP1, d);
639 emit_store_dst(jd, iptr, d);
642 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
643 /* sx.val.i = constant */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
648 M_ISUB_IMM(iptr->sx.val.i, d);
649 emit_store_dst(jd, iptr, d);
652 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658 M_INTMOVE(s1, REG_ITMP1);
659 M_LSUB(s2, REG_ITMP1);
660 M_INTMOVE(REG_ITMP1, d);
665 emit_store_dst(jd, iptr, d);
668 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
669 /* sx.val.l = constant */
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
674 if (IS_IMM32(iptr->sx.val.l))
675 M_LSUB_IMM(iptr->sx.val.l, d);
677 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
678 M_LSUB(REG_ITMP2, d);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
698 /* sx.val.i = constant */
700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
702 if (iptr->sx.val.i == 2) {
706 M_IMUL_IMM(s1, iptr->sx.val.i, d);
707 emit_store_dst(jd, iptr, d);
710 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
721 emit_store_dst(jd, iptr, d);
724 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
725 /* sx.val.l = constant */
727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
728 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
729 if (IS_IMM32(iptr->sx.val.l))
730 M_LMUL_IMM(s1, iptr->sx.val.l, d);
732 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
734 M_LMUL(REG_ITMP2, d);
736 emit_store_dst(jd, iptr, d);
739 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
741 s1 = emit_load_s1(jd, iptr, RAX);
742 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
743 d = codegen_reg_of_dst(jd, iptr, RAX);
746 M_INTMOVE(s2, REG_ITMP3);
747 emit_arithmetic_check(cd, iptr, REG_ITMP3);
749 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
751 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
753 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
754 M_BEQ(1 + 3); /* 6 bytes */
756 emit_cltd(cd); /* 1 byte */
757 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
760 emit_store_dst(jd, iptr, d);
761 dst = VAROP(iptr->dst);
762 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
763 M_MOV(REG_ITMP2, RDX); /* restore RDX */
766 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
768 s1 = emit_load_s1(jd, iptr, RAX);
769 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
770 d = codegen_reg_of_dst(jd, iptr, RDX);
773 M_INTMOVE(s2, REG_ITMP3);
774 emit_arithmetic_check(cd, iptr, REG_ITMP3);
776 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
778 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
780 M_CLR(RDX); /* 3 bytes */
781 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
782 M_BEQ(1 + 3); /* 6 bytes */
784 emit_cltd(cd); /* 1 byte */
785 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
788 emit_store_dst(jd, iptr, d);
789 dst = VAROP(iptr->dst);
790 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
791 M_MOV(REG_ITMP2, RDX); /* restore RDX */
794 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
795 /* sx.val.i = constant */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
799 M_INTMOVE(s1, REG_ITMP1);
800 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
801 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
802 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
803 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
804 emit_mov_reg_reg(cd, REG_ITMP1, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
809 /* sx.val.i = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
813 M_INTMOVE(s1, REG_ITMP1);
814 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
815 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
816 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
817 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
818 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
819 emit_mov_reg_reg(cd, REG_ITMP1, d);
820 emit_store_dst(jd, iptr, d);
824 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
826 s1 = emit_load_s1(jd, iptr, RAX);
827 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
828 d = codegen_reg_of_dst(jd, iptr, RAX);
831 M_INTMOVE(s2, REG_ITMP3);
832 emit_arithmetic_check(cd, iptr, REG_ITMP3);
834 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
836 /* check as described in jvm spec */
837 disp = dseg_add_s8(cd, 0x8000000000000000LL);
838 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
840 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
841 M_BEQ(2 + 3); /* 6 bytes */
843 emit_cqto(cd); /* 2 bytes */
844 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
847 emit_store_dst(jd, iptr, d);
848 dst = VAROP(iptr->dst);
849 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
850 M_MOV(REG_ITMP2, RDX); /* restore RDX */
853 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
855 s1 = emit_load_s1(jd, iptr, RAX);
856 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
857 d = codegen_reg_of_dst(jd, iptr, RDX);
860 M_INTMOVE(s2, REG_ITMP3);
861 emit_arithmetic_check(cd, iptr, REG_ITMP3);
863 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
865 /* check as described in jvm spec */
866 disp = dseg_add_s8(cd, 0x8000000000000000LL);
867 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
869 M_LXOR(RDX, RDX); /* 3 bytes */
870 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
871 M_BEQ(2 + 3); /* 6 bytes */
873 emit_cqto(cd); /* 2 bytes */
874 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
877 emit_store_dst(jd, iptr, d);
878 dst = VAROP(iptr->dst);
879 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
880 M_MOV(REG_ITMP2, RDX); /* restore RDX */
883 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
884 /* sx.val.i = constant */
886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
888 M_INTMOVE(s1, REG_ITMP1);
889 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
890 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
891 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
892 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
893 emit_mov_reg_reg(cd, REG_ITMP1, d);
894 emit_store_dst(jd, iptr, d);
897 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
898 /* sx.val.l = constant */
900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
901 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
902 M_INTMOVE(s1, REG_ITMP1);
903 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
904 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
905 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
906 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
907 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
908 emit_mov_reg_reg(cd, REG_ITMP1, d);
909 emit_store_dst(jd, iptr, d);
912 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
914 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
915 emit_ishift(jd, SHIFT_SHL, iptr);
918 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
919 /* sx.val.i = constant */
921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
924 M_ISLL_IMM(iptr->sx.val.i, d);
925 emit_store_dst(jd, iptr, d);
928 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
930 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
931 emit_ishift(jd, SHIFT_SAR, iptr);
934 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
935 /* sx.val.i = constant */
937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
938 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
940 M_ISRA_IMM(iptr->sx.val.i, d);
941 emit_store_dst(jd, iptr, d);
944 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
946 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
947 emit_ishift(jd, SHIFT_SHR, iptr);
950 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
951 /* sx.val.i = constant */
953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
956 M_ISRL_IMM(iptr->sx.val.i, d);
957 emit_store_dst(jd, iptr, d);
960 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
962 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
963 emit_lshift(jd, SHIFT_SHL, iptr);
966 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
967 /* sx.val.i = constant */
969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
970 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
972 M_LSLL_IMM(iptr->sx.val.i, d);
973 emit_store_dst(jd, iptr, d);
976 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
978 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
979 emit_lshift(jd, SHIFT_SAR, iptr);
982 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
983 /* sx.val.i = constant */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
988 M_LSRA_IMM(iptr->sx.val.i, d);
989 emit_store_dst(jd, iptr, d);
992 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
994 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
995 emit_lshift(jd, SHIFT_SHR, iptr);
998 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
999 /* sx.val.l = constant */
1001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1004 M_LSRL_IMM(iptr->sx.val.i, d);
1005 emit_store_dst(jd, iptr, d);
1008 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1019 emit_store_dst(jd, iptr, d);
1022 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1023 /* sx.val.i = constant */
1025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1028 M_IAND_IMM(iptr->sx.val.i, d);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1034 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1035 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1036 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1047 /* sx.val.l = constant */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1052 if (IS_IMM32(iptr->sx.val.l))
1053 M_LAND_IMM(iptr->sx.val.l, d);
1055 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1056 M_LAND(REG_ITMP2, d);
1058 emit_store_dst(jd, iptr, d);
1061 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1065 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1076 /* sx.val.i = constant */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1081 M_IOR_IMM(iptr->sx.val.i, d);
1082 emit_store_dst(jd, iptr, d);
1085 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1100 /* sx.val.l = constant */
1102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1105 if (IS_IMM32(iptr->sx.val.l))
1106 M_LOR_IMM(iptr->sx.val.l, d);
1108 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1109 M_LOR(REG_ITMP2, d);
1111 emit_store_dst(jd, iptr, d);
1114 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1116 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1117 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1118 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1129 /* sx.val.i = constant */
1131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1134 M_IXOR_IMM(iptr->sx.val.i, d);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1153 /* sx.val.l = constant */
1155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1156 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1158 if (IS_IMM32(iptr->sx.val.l))
1159 M_LXOR_IMM(iptr->sx.val.l, d);
1161 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1162 M_LXOR(REG_ITMP2, d);
1164 emit_store_dst(jd, iptr, d);
1168 /* floating operations ************************************************/
1170 case ICMD_FNEG: /* ..., value ==> ..., - value */
1172 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1173 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1174 disp = dseg_add_s4(cd, 0x80000000);
1176 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1177 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1178 emit_store_dst(jd, iptr, d);
1181 case ICMD_DNEG: /* ..., value ==> ..., - value */
1183 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1184 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1185 disp = dseg_add_s8(cd, 0x8000000000000000);
1187 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1188 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1189 emit_store_dst(jd, iptr, d);
1192 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1194 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1195 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1208 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1209 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1210 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1222 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1224 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1226 M_FLTMOVE(s2, REG_FTMP2);
1231 emit_store_dst(jd, iptr, d);
1234 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1236 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1237 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1238 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1240 M_FLTMOVE(s2, REG_FTMP2);
1245 emit_store_dst(jd, iptr, d);
1248 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1250 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1251 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1264 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1265 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1266 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1278 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1279 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1280 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1282 M_FLTMOVE(s2, REG_FTMP2);
1287 emit_store_dst(jd, iptr, d);
1290 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1292 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 M_FLTMOVE(s2, REG_FTMP2);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1309 emit_store_dst(jd, iptr, d);
1312 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1314 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1315 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1317 emit_store_dst(jd, iptr, d);
1320 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1322 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1323 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1330 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1338 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1339 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1341 M_ICMP_IMM(0x80000000, d); /* corner cases */
1342 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1343 ((REG_RESULT == d) ? 0 : 3);
1345 M_FLTMOVE(s1, REG_FTMP1);
1346 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1348 M_INTMOVE(REG_RESULT, d);
1349 emit_store_dst(jd, iptr, d);
1352 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1354 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1357 M_ICMP_IMM(0x80000000, d); /* corner cases */
1358 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1359 ((REG_RESULT == d) ? 0 : 3);
1361 M_FLTMOVE(s1, REG_FTMP1);
1362 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1364 M_INTMOVE(REG_RESULT, d);
1365 emit_store_dst(jd, iptr, d);
1368 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1370 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1371 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1373 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1374 M_LCMP(REG_ITMP2, d); /* corner cases */
1375 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1376 ((REG_RESULT == d) ? 0 : 3);
1378 M_FLTMOVE(s1, REG_FTMP1);
1379 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1381 M_INTMOVE(REG_RESULT, d);
1382 emit_store_dst(jd, iptr, d);
1385 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1387 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1390 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1391 M_LCMP(REG_ITMP2, d); /* corner cases */
1392 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1393 ((REG_RESULT == d) ? 0 : 3);
1395 M_FLTMOVE(s1, REG_FTMP1);
1396 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1398 M_INTMOVE(REG_RESULT, d);
1399 emit_store_dst(jd, iptr, d);
1402 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1404 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1405 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1407 emit_store_dst(jd, iptr, d);
1410 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1412 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1413 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1415 emit_store_dst(jd, iptr, d);
1418 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1419 /* == => 0, < => 1, > => -1 */
1421 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1422 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1423 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1425 M_MOV_IMM(1, REG_ITMP1);
1426 M_MOV_IMM(-1, REG_ITMP2);
1427 emit_ucomiss_reg_reg(cd, s1, s2);
1428 M_CMOVULT(REG_ITMP1, d);
1429 M_CMOVUGT(REG_ITMP2, d);
1430 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1431 emit_store_dst(jd, iptr, d);
1434 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1435 /* == => 0, < => 1, > => -1 */
1437 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1438 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1439 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1441 M_MOV_IMM(1, REG_ITMP1);
1442 M_MOV_IMM(-1, REG_ITMP2);
1443 emit_ucomiss_reg_reg(cd, s1, s2);
1444 M_CMOVULT(REG_ITMP1, d);
1445 M_CMOVUGT(REG_ITMP2, d);
1446 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1447 emit_store_dst(jd, iptr, d);
1450 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1451 /* == => 0, < => 1, > => -1 */
1453 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1454 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1457 M_MOV_IMM(1, REG_ITMP1);
1458 M_MOV_IMM(-1, REG_ITMP2);
1459 emit_ucomisd_reg_reg(cd, s1, s2);
1460 M_CMOVULT(REG_ITMP1, d);
1461 M_CMOVUGT(REG_ITMP2, d);
1462 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1463 emit_store_dst(jd, iptr, d);
1466 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1467 /* == => 0, < => 1, > => -1 */
1469 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1470 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1473 M_MOV_IMM(1, REG_ITMP1);
1474 M_MOV_IMM(-1, REG_ITMP2);
1475 emit_ucomisd_reg_reg(cd, s1, s2);
1476 M_CMOVULT(REG_ITMP1, d);
1477 M_CMOVUGT(REG_ITMP2, d);
1478 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1479 emit_store_dst(jd, iptr, d);
1483 /* memory operations **************************************************/
1485 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1487 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1489 /* implicit null-pointer check */
1490 M_ILD(d, s1, OFFSET(java_array_t, size));
1491 emit_store_dst(jd, iptr, d);
1494 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1496 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1497 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1499 /* implicit null-pointer check */
1500 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1502 emit_store_dst(jd, iptr, d);
1505 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1508 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1510 /* implicit null-pointer check */
1511 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1512 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1513 emit_store_dst(jd, iptr, d);
1516 case ICMD_SALOAD: /* ..., 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_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1524 emit_store_dst(jd, iptr, d);
1527 case ICMD_IALOAD: /* ..., 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_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1535 emit_store_dst(jd, iptr, d);
1538 case ICMD_LALOAD: /* ..., 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_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1546 emit_store_dst(jd, iptr, d);
1549 case ICMD_FALOAD: /* ..., 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_FTMP3);
1554 /* implicit null-pointer check */
1555 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1556 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1557 emit_store_dst(jd, iptr, d);
1560 case ICMD_DALOAD: /* ..., 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_FTMP3);
1565 /* implicit null-pointer check */
1566 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1567 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1568 emit_store_dst(jd, iptr, d);
1571 case ICMD_AALOAD: /* ..., 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_ITMP3);
1576 /* implicit null-pointer check */
1577 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1578 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1579 emit_store_dst(jd, iptr, d);
1583 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1586 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1587 /* implicit null-pointer check */
1588 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1589 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1590 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1593 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1596 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1597 /* implicit null-pointer check */
1598 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1599 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1600 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1603 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1607 /* implicit null-pointer check */
1608 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1609 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1610 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1613 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1616 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1617 /* implicit null-pointer check */
1618 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1619 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1620 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1623 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1626 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1627 /* implicit null-pointer check */
1628 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1629 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1630 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1633 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1635 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1636 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1637 /* implicit null-pointer check */
1638 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1639 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1640 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1643 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1647 /* implicit null-pointer check */
1648 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1649 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1650 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1653 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1656 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1657 /* implicit null-pointer check */
1658 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1659 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1663 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1665 emit_arraystore_check(cd, iptr);
1667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1669 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1670 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1674 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1678 /* implicit null-pointer check */
1679 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1680 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1683 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687 /* implicit null-pointer check */
1688 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1689 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1692 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1695 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1696 /* implicit null-pointer check */
1697 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1698 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1701 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1704 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1705 /* implicit null-pointer check */
1706 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1707 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1710 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1714 /* implicit null-pointer check */
1715 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1717 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1718 emit_mov_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 & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1722 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1726 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1730 /* implicit null-pointer check */
1731 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1732 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1736 case ICMD_GETSTATIC: /* ... ==> ..., value */
1738 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1739 uf = iptr->sx.s23.s3.uf;
1740 fieldtype = uf->fieldref->parseddesc.fd->type;
1741 disp = dseg_add_unique_address(cd, uf);
1743 /* PROFILE_CYCLE_STOP; */
1745 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1747 /* PROFILE_CYCLE_START; */
1750 fi = iptr->sx.s23.s3.fmiref->p.field;
1751 fieldtype = fi->type;
1752 disp = dseg_add_address(cd, fi->value);
1754 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1757 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1760 PROFILE_CYCLE_START;
1764 /* This approach is much faster than moving the field
1765 address inline into a register. */
1767 M_ALD(REG_ITMP1, RIP, disp);
1769 switch (fieldtype) {
1771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1772 M_ILD(d, REG_ITMP1, 0);
1776 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1777 M_LLD(d, REG_ITMP1, 0);
1780 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1781 M_FLD(d, REG_ITMP1, 0);
1784 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1785 M_DLD(d, REG_ITMP1, 0);
1788 emit_store_dst(jd, iptr, d);
1791 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1793 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1794 uf = iptr->sx.s23.s3.uf;
1795 fieldtype = uf->fieldref->parseddesc.fd->type;
1796 disp = dseg_add_unique_address(cd, uf);
1798 /* PROFILE_CYCLE_STOP; */
1800 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1802 /* PROFILE_CYCLE_START; */
1805 fi = iptr->sx.s23.s3.fmiref->p.field;
1806 fieldtype = fi->type;
1807 disp = dseg_add_address(cd, fi->value);
1809 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1812 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1815 PROFILE_CYCLE_START;
1819 /* This approach is much faster than moving the field
1820 address inline into a register. */
1822 M_ALD(REG_ITMP1, RIP, disp);
1824 switch (fieldtype) {
1826 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1827 M_IST(s1, REG_ITMP1, 0);
1831 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1832 M_LST(s1, REG_ITMP1, 0);
1835 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1836 M_FST(s1, REG_ITMP1, 0);
1839 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1840 M_DST(s1, REG_ITMP1, 0);
1845 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1846 /* val = value (in current instruction) */
1847 /* following NOP) */
1849 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1850 uf = iptr->sx.s23.s3.uf;
1851 fieldtype = uf->fieldref->parseddesc.fd->type;
1852 disp = dseg_add_unique_address(cd, uf);
1854 /* PROFILE_CYCLE_STOP; */
1856 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1858 /* PROFILE_CYCLE_START; */
1861 fi = iptr->sx.s23.s3.fmiref->p.field;
1862 fieldtype = fi->type;
1863 disp = dseg_add_address(cd, fi->value);
1865 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1868 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1871 PROFILE_CYCLE_START;
1875 /* This approach is much faster than moving the field
1876 address inline into a register. */
1878 M_ALD(REG_ITMP1, RIP, disp);
1880 switch (fieldtype) {
1883 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1888 if (IS_IMM32(iptr->sx.s23.s2.constval))
1889 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1891 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1892 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1898 case ICMD_GETFIELD: /* ... ==> ..., value */
1900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1902 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1903 uf = iptr->sx.s23.s3.uf;
1904 fieldtype = uf->fieldref->parseddesc.fd->type;
1907 /* PROFILE_CYCLE_STOP; */
1909 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1911 /* PROFILE_CYCLE_START; */
1914 fi = iptr->sx.s23.s3.fmiref->p.field;
1915 fieldtype = fi->type;
1919 /* implicit null-pointer check */
1920 switch (fieldtype) {
1922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1923 M_ILD32(d, s1, disp);
1927 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1928 M_LLD32(d, s1, disp);
1931 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1932 M_FLD32(d, s1, disp);
1935 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1936 M_DLD32(d, s1, disp);
1939 emit_store_dst(jd, iptr, d);
1942 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1944 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1945 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1947 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1948 uf = iptr->sx.s23.s3.uf;
1949 fieldtype = uf->fieldref->parseddesc.fd->type;
1952 /* PROFILE_CYCLE_STOP; */
1954 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1956 /* PROFILE_CYCLE_START; */
1959 fi = iptr->sx.s23.s3.fmiref->p.field;
1960 fieldtype = fi->type;
1964 /* implicit null-pointer check */
1965 switch (fieldtype) {
1967 M_IST32(s2, s1, disp);
1971 M_LST32(s2, s1, disp);
1974 M_FST32(s2, s1, disp);
1977 M_DST32(s2, s1, disp);
1982 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1983 /* val = value (in current instruction) */
1984 /* following NOP) */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1988 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1989 uf = iptr->sx.s23.s3.uf;
1990 fieldtype = uf->fieldref->parseddesc.fd->type;
1993 /* PROFILE_CYCLE_STOP; */
1995 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1997 /* PROFILE_CYCLE_START; */
2000 fi = iptr->sx.s23.s3.fmiref->p.field;
2001 fieldtype = fi->type;
2005 /* implicit null-pointer check */
2006 switch (fieldtype) {
2009 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2014 /* XXX why no check for IS_IMM32? */
2015 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2016 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2022 /* branch operations **************************************************/
2024 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027 M_INTMOVE(s1, REG_ITMP1_XPTR);
2031 #ifdef ENABLE_VERIFIER
2032 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2033 uc = iptr->sx.s23.s2.uc;
2035 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2037 #endif /* ENABLE_VERIFIER */
2039 M_CALL_IMM(0); /* passing exception pc */
2040 M_POP(REG_ITMP2_XPC);
2042 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2046 case ICMD_GOTO: /* ... ==> ... */
2049 emit_br(cd, iptr->dst.block);
2053 case ICMD_JSR: /* ... ==> ... */
2055 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2059 case ICMD_IFNULL: /* ..., value ==> ... */
2060 case ICMD_IFNONNULL:
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2064 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2067 case ICMD_IFEQ: /* ..., value ==> ... */
2074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2075 M_ICMP_IMM(iptr->sx.val.i, s1);
2076 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2079 case ICMD_IF_LEQ: /* ..., value ==> ... */
2086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2087 if (IS_IMM32(iptr->sx.val.l))
2088 M_LCMP_IMM(iptr->sx.val.l, s1);
2090 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2091 M_LCMP(REG_ITMP2, s1);
2093 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2096 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2097 case ICMD_IF_ICMPNE:
2098 case ICMD_IF_ICMPLT:
2099 case ICMD_IF_ICMPGE:
2100 case ICMD_IF_ICMPGT:
2101 case ICMD_IF_ICMPLE:
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2106 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2109 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2110 case ICMD_IF_ACMPNE:
2112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2115 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2118 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2119 case ICMD_IF_LCMPNE:
2120 case ICMD_IF_LCMPLT:
2121 case ICMD_IF_LCMPGE:
2122 case ICMD_IF_LCMPGT:
2123 case ICMD_IF_LCMPLE:
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2128 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2131 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2134 REPLACEMENT_POINT_RETURN(cd, iptr);
2135 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2136 M_INTMOVE(s1, REG_RESULT);
2137 goto nowperformreturn;
2139 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2141 REPLACEMENT_POINT_RETURN(cd, iptr);
2142 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2143 M_INTMOVE(s1, REG_RESULT);
2145 #ifdef ENABLE_VERIFIER
2146 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2147 uc = iptr->sx.s23.s2.uc;
2151 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2153 PROFILE_CYCLE_START;
2155 #endif /* ENABLE_VERIFIER */
2156 goto nowperformreturn;
2158 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2161 REPLACEMENT_POINT_RETURN(cd, iptr);
2162 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2163 M_FLTMOVE(s1, REG_FRESULT);
2164 goto nowperformreturn;
2166 case ICMD_RETURN: /* ... ==> ... */
2168 REPLACEMENT_POINT_RETURN(cd, iptr);
2174 p = cd->stackframesize;
2176 #if !defined(NDEBUG)
2177 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2178 emit_verbosecall_exit(jd);
2179 #endif /* !defined(NDEBUG) */
2181 #if defined(ENABLE_THREADS)
2182 if (checksync && code_is_synchronized(code)) {
2183 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2185 /* we need to save the proper return value */
2186 switch (iptr->opc) {
2190 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2194 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2198 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2201 /* and now restore the proper return value */
2202 switch (iptr->opc) {
2206 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2210 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2216 /* restore saved registers */
2218 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2219 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2221 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2222 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2225 /* deallocate stack */
2227 if (cd->stackframesize)
2228 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2230 /* generate method profiling code */
2239 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2242 branch_target_t *table;
2244 table = iptr->dst.table;
2246 l = iptr->sx.s23.s2.tablelow;
2247 i = iptr->sx.s23.s3.tablehigh;
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 M_INTMOVE(s1, REG_ITMP1);
2253 M_ISUB_IMM(l, REG_ITMP1);
2255 /* number of targets */
2260 M_ICMP_IMM(i - 1, REG_ITMP1);
2261 emit_bugt(cd, table[0].block);
2263 /* build jump table top down and use address of lowest entry */
2268 dseg_add_target(cd, table->block);
2272 /* length of dataseg after last dseg_add_target is used
2275 M_MOV_IMM(0, REG_ITMP2);
2277 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2283 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2286 lookup_target_t *lookup;
2288 lookup = iptr->dst.lookup;
2290 i = iptr->sx.s23.s2.lookupcount;
2292 MCODECHECK(8 + ((7 + 6) * i) + 5);
2293 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2296 M_ICMP_IMM(lookup->value, s1);
2297 emit_beq(cd, lookup->target.block);
2301 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2307 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2309 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2311 bte = iptr->sx.s23.s3.bte;
2315 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2317 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2318 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2319 case ICMD_INVOKEINTERFACE:
2321 REPLACEMENT_POINT_INVOKE(cd, iptr);
2323 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2325 um = iptr->sx.s23.s3.um;
2326 md = um->methodref->parseddesc.md;
2329 lm = iptr->sx.s23.s3.fmiref->p.method;
2331 md = lm->parseddesc;
2335 s3 = md->paramcount;
2337 MCODECHECK((20 * s3) + 128);
2339 /* copy arguments to registers or stack location */
2341 for (s3 = s3 - 1; s3 >= 0; s3--) {
2342 var = VAR(iptr->sx.s23.s2.args[s3]);
2343 d = md->params[s3].regoff;
2345 /* already preallocated (ARGVAR)? */
2347 if (var->flags & PREALLOC)
2350 if (IS_INT_LNG_TYPE(var->type)) {
2351 if (!md->params[s3].inmemory) {
2352 s1 = emit_load(jd, iptr, var, d);
2356 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2357 M_LST(s1, REG_SP, d);
2361 if (!md->params[s3].inmemory) {
2362 s1 = emit_load(jd, iptr, var, d);
2366 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2368 if (IS_2_WORD_TYPE(var->type))
2369 M_DST(s1, REG_SP, d);
2371 M_FST(s1, REG_SP, d);
2376 /* generate method profiling code */
2380 switch (iptr->opc) {
2382 if (bte->stub == NULL) {
2383 M_MOV_IMM(bte->fp, REG_ITMP1);
2386 M_MOV_IMM(bte->stub, REG_ITMP1);
2391 case ICMD_INVOKESPECIAL:
2392 emit_nullpointer_check(cd, iptr, REG_A0);
2395 case ICMD_INVOKESTATIC:
2397 disp = dseg_add_unique_address(cd, um);
2399 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2403 disp = dseg_add_functionptr(cd, lm->stubroutine);
2406 M_ALD(REG_ITMP2, RIP, disp);
2410 case ICMD_INVOKEVIRTUAL:
2412 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2417 s1 = OFFSET(vftbl_t, table[0]) +
2418 sizeof(methodptr) * lm->vftblindex;
2421 /* implicit null-pointer check */
2422 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2423 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2427 case ICMD_INVOKEINTERFACE:
2429 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2435 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2436 sizeof(methodptr) * lm->clazz->index;
2438 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2441 /* implicit null-pointer check */
2442 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2443 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2444 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2449 /* generate method profiling code */
2451 PROFILE_CYCLE_START;
2453 /* store size of call code in replacement point */
2455 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2456 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2458 /* store return value */
2460 switch (md->returntype.type) {
2464 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2465 M_INTMOVE(REG_RESULT, s1);
2466 emit_store_dst(jd, iptr, s1);
2470 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2471 M_FLTMOVE(REG_FRESULT, s1);
2472 emit_store_dst(jd, iptr, s1);
2481 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2483 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2484 /* object type cast-check */
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 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2573 M_AADD_IMM(-32, REG_SP); /* need some stack */
2574 if (s1 == REG_ITMP1)
2575 M_AST(REG_ITMP1, REG_SP, -8 + 32);
2577 M_ALD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2579 *(cd->mcodeptr++) = 0x4d;
2580 *(cd->mcodeptr++) = 0x3b;
2581 *(cd->mcodeptr++) = 0x1c;
2582 *(cd->mcodeptr++) = 0x02;
2583 /* cmp (ITMP2, ITMP1, 1), ITMP3 */
2585 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
2587 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2588 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2590 M_AST(REG_ITMP3, REG_SP, -16 + 32);
2591 M_AST_IMM32(0, REG_SP, -24 + 32);
2592 M_ALD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2593 looptarget = cd->mcodeptr - cd->mcodebase;
2595 M_ALD(REG_ITMP3, REG_SP, -24 + 32);
2596 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_overflow_length), REG_ITMP3);
2597 emit_label_bge(cd, BRANCH_LABEL_9); /* throw */
2599 *(cd->mcodeptr++) = 0x4e;
2600 *(cd->mcodeptr++) = 0x8b;
2601 *(cd->mcodeptr++) = 0x1c;
2602 *(cd->mcodeptr++) = 0xd8;
2603 /* movq (ITMP1, ITMP3, 8), ITMP3 */
2605 M_LCMP_MEMBASE(REG_SP, -16 + 32, REG_ITMP3);
2606 emit_label_beq(cd, BRANCH_LABEL_7); /* good, pop */
2608 M_LINC_MEMBASE(REG_SP, -24 + 32);
2609 M_JMP_IMM2(looptarget - (cd->mcodeptr - cd->mcodebase) - 2); /* 1 byte displacement */
2611 emit_label(cd, BRANCH_LABEL_9);
2612 M_AADD_IMM(32, REG_SP); /* restore stack frame */
2613 M_ALD_MEM(REG_ITMP3, TRAP_ClassCastException);
2615 emit_label(cd, BRANCH_LABEL_7);
2617 emit_label(cd, BRANCH_LABEL_6);
2619 if (s1 == REG_ITMP1)
2620 M_ALD(REG_ITMP1, REG_SP, -8 + 32);
2621 M_AADD_IMM(32, REG_SP);
2624 assert(super->vftbl->subtype_offset < 0x80);
2625 *(cd->mcodeptr++) = 0x4d;
2626 *(cd->mcodeptr++) = 0x3b;
2627 *(cd->mcodeptr++) = 0x5a;
2628 *(cd->mcodeptr++) = super->vftbl->subtype_offset;
2629 /* cmp off(ITMP1), ITMP2 */
2631 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2635 emit_label(cd, BRANCH_LABEL_5);
2638 if (super == NULL) {
2639 emit_label(cd, BRANCH_LABEL_1);
2640 emit_label(cd, BRANCH_LABEL_4);
2643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2646 /* array type cast-check */
2648 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2649 M_INTMOVE(s1, REG_A0);
2651 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2652 cr = iptr->sx.s23.s3.c.ref;
2653 disp = dseg_add_unique_address(cd, cr);
2655 patcher_add_patch_ref(jd,
2656 PATCHER_resolve_classref_to_classinfo,
2660 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2663 M_ALD(REG_A1, RIP, disp);
2664 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2667 /* s1 may have been destroyed over the function call */
2668 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2670 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2676 emit_store_dst(jd, iptr, d);
2679 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2687 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2692 super = iptr->sx.s23.s3.c.cls;
2693 superindex = super->index;
2696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2700 M_INTMOVE(s1, REG_ITMP1);
2706 /* if class is not resolved, check which code to call */
2708 if (super == NULL) {
2710 emit_label_beq(cd, BRANCH_LABEL_1);
2712 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2713 iptr->sx.s23.s3.c.ref, 0);
2715 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2716 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2717 emit_label_beq(cd, BRANCH_LABEL_2);
2720 /* interface instanceof code */
2722 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2723 if (super != NULL) {
2725 emit_label_beq(cd, BRANCH_LABEL_3);
2728 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2730 if (super == NULL) {
2731 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2732 iptr->sx.s23.s3.c.ref, 0);
2736 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2737 M_ICMP_IMM32(superindex, REG_ITMP3);
2739 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2742 M_ALD32(REG_ITMP1, REG_ITMP1,
2743 OFFSET(vftbl_t, interfacetable[0]) -
2744 superindex * sizeof(methodptr*));
2749 emit_label_br(cd, BRANCH_LABEL_4);
2751 emit_label(cd, BRANCH_LABEL_3);
2754 /* class instanceof code */
2756 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2757 if (super == NULL) {
2758 emit_label(cd, BRANCH_LABEL_2);
2760 cr = iptr->sx.s23.s3.c.ref;
2761 disp = dseg_add_unique_address(cd, cr);
2763 patcher_add_patch_ref(jd,
2764 PATCHER_resolve_classref_to_vftbl,
2769 emit_label_beq(cd, BRANCH_LABEL_5);
2771 disp = dseg_add_address(cd, super->vftbl);
2774 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2775 M_ALD(REG_ITMP3, RIP, disp);
2777 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2778 M_AADD_IMM(-32, REG_SP); /* need some stack */
2779 M_ALD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2781 *(cd->mcodeptr++) = 0x4d;
2782 *(cd->mcodeptr++) = 0x3b;
2783 *(cd->mcodeptr++) = 0x1c;
2784 *(cd->mcodeptr++) = 0x02;
2785 /* cmp (ITMP2, ITMP1, 1), ITMP3 */
2787 emit_label_bne(cd, BRANCH_LABEL_6);
2788 if (d == REG_ITMP2) {
2793 emit_label_br(cd, BRANCH_LABEL_7); /* ende true */
2795 emit_label(cd, BRANCH_LABEL_6);
2797 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2798 emit_label_bne(cd, BRANCH_LABEL_6); /* ende false */
2800 M_AST(REG_ITMP3, REG_SP, -16 + 32);
2801 M_AST_IMM32(0, REG_SP, -24 + 32);
2802 M_ALD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2803 looptarget = cd->mcodeptr - cd->mcodebase;
2805 M_ALD(REG_ITMP3, REG_SP, -24 + 32);
2806 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_overflow_length), REG_ITMP3);
2807 emit_label_bge(cd, BRANCH_LABEL_8); /* ende false */
2809 *(cd->mcodeptr++) = 0x4e;
2810 *(cd->mcodeptr++) = 0x8b;
2811 *(cd->mcodeptr++) = 0x1c;
2812 *(cd->mcodeptr++) = 0xd8;
2813 /* movq (ITMP1, ITMP3, 8), ITMP3 */
2815 M_LCMP_MEMBASE(REG_SP, -16 + 32, REG_ITMP3);
2816 emit_label_bne(cd, BRANCH_LABEL_9);
2817 if (d == REG_ITMP2) {
2822 emit_label_br(cd, BRANCH_LABEL_10); /* ende true */
2823 emit_label(cd, BRANCH_LABEL_9);
2825 M_LINC_MEMBASE(REG_SP, -24 + 32);
2826 M_JMP_IMM2(looptarget - (cd->mcodeptr - cd->mcodebase) - 2); /* 1 byte displacement */
2828 emit_label(cd, BRANCH_LABEL_8);
2829 emit_label(cd, BRANCH_LABEL_6);
2834 emit_label(cd, BRANCH_LABEL_10);
2835 emit_label(cd, BRANCH_LABEL_7);
2836 M_AADD_IMM(32, REG_SP);
2839 assert(super->vftbl->subtype_offset < 0x80);
2840 *(cd->mcodeptr++) = 0x4d;
2841 *(cd->mcodeptr++) = 0x3b;
2842 *(cd->mcodeptr++) = 0x5a;
2843 *(cd->mcodeptr++) = super->vftbl->subtype_offset;
2844 /* cmp off(ITMP1), ITMP2 */
2852 emit_label(cd, BRANCH_LABEL_5);
2855 if (super == NULL) {
2856 emit_label(cd, BRANCH_LABEL_1);
2857 emit_label(cd, BRANCH_LABEL_4);
2860 emit_store_dst(jd, iptr, d);
2864 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2866 /* check for negative sizes and copy sizes to stack if necessary */
2868 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2870 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2872 /* copy SAVEDVAR sizes to stack */
2873 var = VAR(iptr->sx.s23.s2.args[s1]);
2875 /* Already Preallocated? */
2876 if (!(var->flags & PREALLOC)) {
2877 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2878 M_LST(s2, REG_SP, s1 * 8);
2882 /* a0 = dimension count */
2884 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2886 /* is a patcher function set? */
2888 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2889 cr = iptr->sx.s23.s3.c.ref;
2890 disp = dseg_add_unique_address(cd, cr);
2892 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2896 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2899 /* a1 = classinfo */
2901 M_ALD(REG_A1, RIP, disp);
2903 /* a2 = pointer to dimensions = stack pointer */
2905 M_MOV(REG_SP, REG_A2);
2907 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2910 /* check for exception before result assignment */
2912 emit_exception_check(cd, iptr);
2914 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2915 M_INTMOVE(REG_RESULT, s1);
2916 emit_store_dst(jd, iptr, s1);
2920 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2925 } /* for instruction */
2927 MCODECHECK(512); /* XXX require a lower number? */
2929 /* At the end of a basic block we may have to append some nops,
2930 because the patcher stub calling code might be longer than the
2931 actual instruction. So codepatching does not change the
2932 following block unintentionally. */
2934 if (cd->mcodeptr < cd->lastmcodeptr) {
2935 while (cd->mcodeptr < cd->lastmcodeptr) {
2940 } /* if (bptr -> flags >= BBREACHED) */
2941 } /* for basic block */
2943 /* Generate patcher traps. */
2945 emit_patcher_traps(jd);
2947 /* everything's ok */
2953 /* codegen_emit_stub_native ****************************************************
2955 Emits a stub routine which calls a native method.
2957 *******************************************************************************/
2959 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2973 /* Get required compiler data. */
2979 /* initialize variables */
2983 /* calculate stack frame size */
2985 cd->stackframesize =
2986 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2987 sizeof(localref_table) / SIZEOF_VOID_P +
2989 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2992 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2994 /* create method header */
2996 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2997 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2998 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2999 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3000 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3002 #if defined(ENABLE_PROFILING)
3003 /* generate native method profiling code */
3005 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3006 /* count frequency */
3008 M_MOV_IMM(code, REG_ITMP3);
3009 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3013 /* generate stub code */
3015 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3017 #if defined(ENABLE_GC_CACAO)
3018 /* Save callee saved integer registers in stackframeinfo (GC may
3019 need to recover them during a collection). */
3021 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3022 OFFSET(stackframeinfo_t, intregs);
3024 for (i = 0; i < INT_SAV_CNT; i++)
3025 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3028 /* save integer and float argument registers */
3030 for (i = 0; i < md->paramcount; i++) {
3031 if (!md->params[i].inmemory) {
3032 s1 = md->params[i].regoff;
3034 switch (md->paramtypes[i].type) {
3038 M_LST(s1, REG_SP, i * 8);
3042 M_DST(s1, REG_SP, i * 8);
3048 /* create dynamic stack info */
3050 M_MOV(REG_SP, REG_A0);
3051 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3052 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3055 /* remember class argument */
3057 if (m->flags & ACC_STATIC)
3058 M_MOV(REG_RESULT, REG_ITMP2);
3060 /* restore integer and float argument registers */
3062 for (i = 0; i < md->paramcount; i++) {
3063 if (!md->params[i].inmemory) {
3064 s1 = md->params[i].regoff;
3066 switch (md->paramtypes[i].type) {
3070 M_LLD(s1, REG_SP, i * 8);
3074 M_DLD(s1, REG_SP, i * 8);
3080 /* Copy or spill arguments to new locations. */
3082 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3083 s2 = nmd->params[j].regoff;
3085 switch (md->paramtypes[i].type) {
3089 if (!md->params[i].inmemory) {
3090 s1 = md->params[i].regoff;
3092 if (!nmd->params[j].inmemory)
3095 M_LST(s1, REG_SP, s2);
3098 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3099 M_LLD(REG_ITMP1, REG_SP, s1);
3100 M_LST(REG_ITMP1, REG_SP, s2);
3104 /* We only copy spilled float arguments, as the float
3105 argument registers keep unchanged. */
3107 if (md->params[i].inmemory) {
3108 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3110 M_FLD(REG_FTMP1, REG_SP, s1);
3111 M_FST(REG_FTMP1, REG_SP, s2);
3115 if (md->params[i].inmemory) {
3116 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3117 M_DLD(REG_FTMP1, REG_SP, s1);
3118 M_DST(REG_FTMP1, REG_SP, s2);
3124 /* Handle native Java methods. */
3126 if (m->flags & ACC_NATIVE) {
3127 /* put class into second argument register */
3129 if (m->flags & ACC_STATIC)
3130 M_MOV(REG_ITMP2, REG_A1);
3132 /* put env into first argument register */
3134 M_MOV_IMM(_Jv_env, REG_A0);
3137 /* Call the native function. */
3139 disp = dseg_add_functionptr(cd, f);
3140 M_ALD(REG_ITMP1, RIP, disp);
3143 /* save return value */
3145 switch (md->returntype.type) {
3149 M_LST(REG_RESULT, REG_SP, 0 * 8);
3153 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3159 /* remove native stackframe info */
3161 M_MOV(REG_SP, REG_A0);
3162 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3163 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3165 M_MOV(REG_RESULT, REG_ITMP3);
3167 /* restore return value */
3169 switch (md->returntype.type) {
3173 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3177 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3183 #if defined(ENABLE_GC_CACAO)
3184 /* Restore callee saved integer registers from stackframeinfo (GC
3185 might have modified them during a collection). */
3187 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3188 OFFSET(stackframeinfo_t, intregs);
3190 for (i = 0; i < INT_SAV_CNT; i++)
3191 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3194 /* remove stackframe */
3196 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3198 /* test for exception */
3204 /* handle exception */
3206 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3207 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3208 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3210 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3216 * These are local overrides for various environment variables in Emacs.
3217 * Please do not remove this and leave it at the end of the file, where
3218 * Emacs will automagically detect them.
3219 * ---------------------------------------------------------------------
3222 * indent-tabs-mode: t
3226 * vim:noexpandtab:sw=4:ts=4: