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"
71 #if defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
75 #include "vmcore/loader.h"
76 #include "vmcore/options.h"
77 #include "vmcore/statistics.h"
80 /* codegen_emit ****************************************************************
82 Generates machine code.
84 *******************************************************************************/
86 bool codegen_emit(jitdata *jd)
92 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 /* space to save used callee saved registers */
131 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
132 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
134 cd->stackframesize = rd->memuse + savedregs_num;
136 #if defined(ENABLE_THREADS)
137 /* space to save argument of monitor_enter */
139 if (checksync && code_is_synchronized(code))
140 cd->stackframesize++;
143 /* Keep stack of non-leaf functions 16-byte aligned for calls into
144 native code e.g. libc or jni (alignment problems with
147 if (!code_is_leafmethod(code) || opt_verbosecall)
148 cd->stackframesize |= 0x1;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 code->synchronizedoffset = rd->memuse * 8;
157 if (code_is_leafmethod(code))
158 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
160 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
162 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
163 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
165 #if defined(ENABLE_PROFILING)
166 /* generate method profiling code */
168 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
169 /* count frequency */
171 M_MOV_IMM(code, REG_ITMP3);
172 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
178 /* create stack frame (if necessary) */
180 if (cd->stackframesize)
181 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
183 /* save used callee saved registers */
185 p = cd->stackframesize;
186 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
187 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
189 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
193 /* take arguments out of register or stack frame */
197 for (p = 0, l = 0; p < md->paramcount; p++) {
198 t = md->paramtypes[p].type;
200 varindex = jd->local_map[l * 5 + t];
203 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
206 if (varindex == UNUSED)
211 s1 = md->params[p].regoff;
213 if (IS_INT_LNG_TYPE(t)) { /* integer args */
214 if (!md->params[p].inmemory) { /* register arguments */
215 if (!IS_INMEMORY(var->flags))
216 M_INTMOVE(s1, var->vv.regoff);
218 M_LST(s1, REG_SP, var->vv.regoff);
220 else { /* stack arguments */
221 if (!IS_INMEMORY(var->flags))
222 /* + 8 for return address */
223 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
225 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
228 else { /* floating args */
229 if (!md->params[p].inmemory) { /* register arguments */
230 if (!IS_INMEMORY(var->flags))
231 M_FLTMOVE(s1, var->vv.regoff);
233 M_DST(s1, REG_SP, var->vv.regoff);
235 else { /* stack arguments */
236 if (!IS_INMEMORY(var->flags))
237 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
239 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
244 /* save monitorenter argument */
246 #if defined(ENABLE_THREADS)
247 if (checksync && code_is_synchronized(code)) {
248 /* stack offset for monitor argument */
252 if (opt_verbosecall) {
253 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
255 for (p = 0; p < INT_ARG_CNT; p++)
256 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
258 for (p = 0; p < FLT_ARG_CNT; p++)
259 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
261 s1 += INT_ARG_CNT + FLT_ARG_CNT;
264 /* decide which monitor enter function to call */
266 if (m->flags & ACC_STATIC) {
267 M_MOV_IMM(&m->class->object.header, REG_A0);
272 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
275 M_AST(REG_A0, REG_SP, s1 * 8);
276 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
279 if (opt_verbosecall) {
280 for (p = 0; p < INT_ARG_CNT; p++)
281 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
283 for (p = 0; p < FLT_ARG_CNT; p++)
284 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
286 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
292 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
293 emit_verbosecall_enter(jd);
294 #endif /* !defined(NDEBUG) */
298 /* end of header generation */
300 /* create replacement points */
302 REPLACEMENT_POINTS_INIT(cd, jd);
304 /* walk through all basic blocks */
306 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
308 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
310 if (bptr->flags >= BBREACHED) {
312 /* branch resolving */
314 codegen_resolve_branchrefs(cd, bptr);
316 /* handle replacement points */
318 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
320 /* copy interface registers to their destination */
325 #if defined(ENABLE_PROFILING)
326 /* generate basicblock profiling code */
328 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
329 /* count frequency */
331 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
332 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
334 /* if this is an exception handler, start profiling again */
336 if (bptr->type == BBTYPE_EXH)
341 #if defined(ENABLE_LSRA)
345 src = bptr->invars[len];
346 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
347 if (bptr->type == BBTYPE_EXH) {
348 /* d = reg_of_var(rd, src, REG_ITMP1); */
349 if (!IS_INMEMORY(src->flags))
353 M_INTMOVE(REG_ITMP1, d);
354 emit_store(jd, NULL, src, d);
364 var = VAR(bptr->invars[len]);
365 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
366 if (bptr->type == BBTYPE_EXH) {
367 d = codegen_reg_of_var(0, var, REG_ITMP1);
368 M_INTMOVE(REG_ITMP1, d);
369 emit_store(jd, NULL, var, d);
373 assert((var->flags & INOUT));
376 #if defined(ENABLE_LSRA)
379 /* walk through all instructions */
384 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
385 if (iptr->line != currentline) {
386 linenumbertable_list_entry_add(cd, iptr->line);
387 currentline = iptr->line;
390 MCODECHECK(1024); /* 1KB should be enough */
393 case ICMD_NOP: /* ... ==> ... */
394 case ICMD_POP: /* ..., value ==> ... */
395 case ICMD_POP2: /* ..., value, value ==> ... */
398 case ICMD_INLINE_START:
400 REPLACEMENT_POINT_INLINE_START(cd, iptr);
403 case ICMD_INLINE_BODY:
405 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
406 linenumbertable_list_entry_add_inline_start(cd, iptr);
407 linenumbertable_list_entry_add(cd, iptr->line);
410 case ICMD_INLINE_END:
412 linenumbertable_list_entry_add_inline_end(cd, iptr);
413 linenumbertable_list_entry_add(cd, iptr->line);
416 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
419 emit_nullpointer_check(cd, iptr, s1);
422 /* constant operations ************************************************/
424 case ICMD_ICONST: /* ... ==> ..., constant */
426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
427 ICONST(d, iptr->sx.val.i);
428 emit_store_dst(jd, iptr, d);
431 case ICMD_LCONST: /* ... ==> ..., constant */
433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
434 LCONST(d, iptr->sx.val.l);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_FCONST: /* ... ==> ..., constant */
440 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
441 disp = dseg_add_float(cd, iptr->sx.val.f);
442 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
443 emit_store_dst(jd, iptr, d);
446 case ICMD_DCONST: /* ... ==> ..., constant */
448 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
449 disp = dseg_add_double(cd, iptr->sx.val.d);
450 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
451 emit_store_dst(jd, iptr, d);
454 case ICMD_ACONST: /* ... ==> ..., constant */
456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
458 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
459 cr = iptr->sx.val.c.ref;
460 disp = dseg_add_unique_address(cd, cr);
462 /* PROFILE_CYCLE_STOP; */
464 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
467 /* PROFILE_CYCLE_START; */
472 if (iptr->sx.val.anyptr == 0) {
476 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
480 emit_store_dst(jd, iptr, d);
484 /* load/store/copy/move operations ************************************/
486 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
487 case ICMD_ALOAD: /* s1 = local variable */
491 case ICMD_ISTORE: /* ..., value ==> ... */
502 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
506 /* integer operations *************************************************/
508 case ICMD_INEG: /* ..., value ==> ..., - value */
510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
514 emit_store_dst(jd, iptr, d);
517 case ICMD_LNEG: /* ..., value ==> ..., - value */
519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
520 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
523 emit_store_dst(jd, iptr, d);
526 case ICMD_I2L: /* ..., value ==> ..., value */
528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
529 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
531 emit_store_dst(jd, iptr, d);
534 case ICMD_L2I: /* ..., value ==> ..., value */
536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
547 emit_store_dst(jd, iptr, d);
550 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
555 emit_store_dst(jd, iptr, d);
558 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
563 emit_store_dst(jd, iptr, d);
567 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 emit_store_dst(jd, iptr, d);
582 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
583 /* sx.val.i = constant */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
588 /* Using inc and dec is not faster than add (tested with
592 M_IADD_IMM(iptr->sx.val.i, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
611 /* sx.val.l = constant */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
616 if (IS_IMM32(iptr->sx.val.l))
617 M_LADD_IMM(iptr->sx.val.l, d);
619 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
620 M_LADD(REG_ITMP2, d);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 M_INTMOVE(s1, REG_ITMP1);
632 M_ISUB(s2, REG_ITMP1);
633 M_INTMOVE(REG_ITMP1, d);
638 emit_store_dst(jd, iptr, d);
641 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
642 /* sx.val.i = constant */
644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
645 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
647 M_ISUB_IMM(iptr->sx.val.i, d);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 M_INTMOVE(s1, REG_ITMP1);
658 M_LSUB(s2, REG_ITMP1);
659 M_INTMOVE(REG_ITMP1, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
668 /* sx.val.l = constant */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
673 if (IS_IMM32(iptr->sx.val.l))
674 M_LSUB_IMM(iptr->sx.val.l, d);
676 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
677 M_LSUB(REG_ITMP2, d);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
697 /* sx.val.i = constant */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
701 if (iptr->sx.val.i == 2) {
705 M_IMUL_IMM(s1, iptr->sx.val.i, d);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
720 emit_store_dst(jd, iptr, d);
723 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
724 /* sx.val.l = constant */
726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
728 if (IS_IMM32(iptr->sx.val.l))
729 M_LMUL_IMM(s1, iptr->sx.val.l, d);
731 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
733 M_LMUL(REG_ITMP2, d);
735 emit_store_dst(jd, iptr, d);
738 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
740 s1 = emit_load_s1(jd, iptr, RAX);
741 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
742 d = codegen_reg_of_dst(jd, iptr, RAX);
745 M_INTMOVE(s2, REG_ITMP3);
746 emit_arithmetic_check(cd, iptr, REG_ITMP3);
748 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
750 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
752 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
753 M_BEQ(1 + 3); /* 6 bytes */
755 emit_cltd(cd); /* 1 byte */
756 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
759 emit_store_dst(jd, iptr, d);
760 dst = VAROP(iptr->dst);
761 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
762 M_MOV(REG_ITMP2, RDX); /* restore RDX */
765 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
767 s1 = emit_load_s1(jd, iptr, RAX);
768 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
769 d = codegen_reg_of_dst(jd, iptr, RDX);
772 M_INTMOVE(s2, REG_ITMP3);
773 emit_arithmetic_check(cd, iptr, REG_ITMP3);
775 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
777 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
779 M_CLR(RDX); /* 3 bytes */
780 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
781 M_BEQ(1 + 3); /* 6 bytes */
783 emit_cltd(cd); /* 1 byte */
784 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
787 emit_store_dst(jd, iptr, d);
788 dst = VAROP(iptr->dst);
789 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
790 M_MOV(REG_ITMP2, RDX); /* restore RDX */
793 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
794 /* sx.val.i = constant */
796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
798 M_INTMOVE(s1, REG_ITMP1);
799 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
800 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
801 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
802 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
803 emit_mov_reg_reg(cd, REG_ITMP1, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
808 /* sx.val.i = constant */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
812 M_INTMOVE(s1, REG_ITMP1);
813 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
814 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
815 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
816 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
817 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
818 emit_mov_reg_reg(cd, REG_ITMP1, d);
819 emit_store_dst(jd, iptr, d);
823 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
825 s1 = emit_load_s1(jd, iptr, RAX);
826 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
827 d = codegen_reg_of_dst(jd, iptr, RAX);
830 M_INTMOVE(s2, REG_ITMP3);
831 emit_arithmetic_check(cd, iptr, REG_ITMP3);
833 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
835 /* check as described in jvm spec */
836 disp = dseg_add_s8(cd, 0x8000000000000000LL);
837 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
839 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
840 M_BEQ(2 + 3); /* 6 bytes */
842 emit_cqto(cd); /* 2 bytes */
843 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
846 emit_store_dst(jd, iptr, d);
847 dst = VAROP(iptr->dst);
848 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
849 M_MOV(REG_ITMP2, RDX); /* restore RDX */
852 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
854 s1 = emit_load_s1(jd, iptr, RAX);
855 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
856 d = codegen_reg_of_dst(jd, iptr, RDX);
859 M_INTMOVE(s2, REG_ITMP3);
860 emit_arithmetic_check(cd, iptr, REG_ITMP3);
862 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
864 /* check as described in jvm spec */
865 disp = dseg_add_s8(cd, 0x8000000000000000LL);
866 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
868 M_LXOR(RDX, RDX); /* 3 bytes */
869 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
870 M_BEQ(2 + 3); /* 6 bytes */
872 emit_cqto(cd); /* 2 bytes */
873 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
876 emit_store_dst(jd, iptr, d);
877 dst = VAROP(iptr->dst);
878 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
879 M_MOV(REG_ITMP2, RDX); /* restore RDX */
882 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
883 /* sx.val.i = constant */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
887 M_INTMOVE(s1, REG_ITMP1);
888 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
889 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
890 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
891 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
892 emit_mov_reg_reg(cd, REG_ITMP1, d);
893 emit_store_dst(jd, iptr, d);
896 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
897 /* sx.val.l = constant */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
901 M_INTMOVE(s1, REG_ITMP1);
902 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
903 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
904 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
905 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
906 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
907 emit_mov_reg_reg(cd, REG_ITMP1, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
913 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
914 emit_ishift(jd, SHIFT_SHL, iptr);
917 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
918 /* sx.val.i = constant */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
923 M_ISLL_IMM(iptr->sx.val.i, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
929 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
930 emit_ishift(jd, SHIFT_SAR, iptr);
933 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
934 /* sx.val.i = constant */
936 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
937 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
939 M_ISRA_IMM(iptr->sx.val.i, d);
940 emit_store_dst(jd, iptr, d);
943 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
945 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
946 emit_ishift(jd, SHIFT_SHR, iptr);
949 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
950 /* sx.val.i = constant */
952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
953 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
955 M_ISRL_IMM(iptr->sx.val.i, d);
956 emit_store_dst(jd, iptr, d);
959 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
961 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
962 emit_lshift(jd, SHIFT_SHL, iptr);
965 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
966 /* sx.val.i = constant */
968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
971 M_LSLL_IMM(iptr->sx.val.i, d);
972 emit_store_dst(jd, iptr, d);
975 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
977 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
978 emit_lshift(jd, SHIFT_SAR, iptr);
981 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
982 /* sx.val.i = constant */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987 M_LSRA_IMM(iptr->sx.val.i, d);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
993 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
994 emit_lshift(jd, SHIFT_SHR, iptr);
997 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
998 /* sx.val.l = constant */
1000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1001 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 M_LSRL_IMM(iptr->sx.val.i, d);
1004 emit_store_dst(jd, iptr, d);
1007 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1022 /* sx.val.i = constant */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1027 M_IAND_IMM(iptr->sx.val.i, d);
1028 emit_store_dst(jd, iptr, d);
1031 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1035 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1046 /* sx.val.l = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1051 if (IS_IMM32(iptr->sx.val.l))
1052 M_LAND_IMM(iptr->sx.val.l, d);
1054 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1055 M_LAND(REG_ITMP2, d);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1075 /* sx.val.i = constant */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1080 M_IOR_IMM(iptr->sx.val.i, d);
1081 emit_store_dst(jd, iptr, d);
1084 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1087 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1099 /* sx.val.l = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1104 if (IS_IMM32(iptr->sx.val.l))
1105 M_LOR_IMM(iptr->sx.val.l, d);
1107 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1108 M_LOR(REG_ITMP2, d);
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1124 emit_store_dst(jd, iptr, d);
1127 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1128 /* sx.val.i = constant */
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1133 M_IXOR_IMM(iptr->sx.val.i, d);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1140 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1152 /* sx.val.l = constant */
1154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1157 if (IS_IMM32(iptr->sx.val.l))
1158 M_LXOR_IMM(iptr->sx.val.l, d);
1160 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1161 M_LXOR(REG_ITMP2, d);
1163 emit_store_dst(jd, iptr, d);
1167 /* floating operations ************************************************/
1169 case ICMD_FNEG: /* ..., value ==> ..., - value */
1171 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1172 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1173 disp = dseg_add_s4(cd, 0x80000000);
1175 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1176 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1177 emit_store_dst(jd, iptr, d);
1180 case ICMD_DNEG: /* ..., value ==> ..., - value */
1182 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1183 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1184 disp = dseg_add_s8(cd, 0x8000000000000000);
1186 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1187 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1193 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1194 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1195 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1207 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1208 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1221 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1222 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1223 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1225 M_FLTMOVE(s2, REG_FTMP2);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1237 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239 M_FLTMOVE(s2, REG_FTMP2);
1244 emit_store_dst(jd, iptr, d);
1247 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1251 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1258 emit_store_dst(jd, iptr, d);
1261 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1263 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1264 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1265 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1277 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1279 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1281 M_FLTMOVE(s2, REG_FTMP2);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1291 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1295 M_FLTMOVE(s2, REG_FTMP2);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1306 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1308 emit_store_dst(jd, iptr, d);
1311 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1314 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1316 emit_store_dst(jd, iptr, d);
1319 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1321 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1322 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1332 emit_store_dst(jd, iptr, d);
1335 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1337 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1338 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1340 M_ICMP_IMM(0x80000000, d); /* corner cases */
1341 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1342 ((REG_RESULT == d) ? 0 : 3);
1344 M_FLTMOVE(s1, REG_FTMP1);
1345 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1347 M_INTMOVE(REG_RESULT, d);
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1353 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1356 M_ICMP_IMM(0x80000000, d); /* corner cases */
1357 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1358 ((REG_RESULT == d) ? 0 : 3);
1360 M_FLTMOVE(s1, REG_FTMP1);
1361 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1363 M_INTMOVE(REG_RESULT, d);
1364 emit_store_dst(jd, iptr, d);
1367 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1369 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1372 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1373 M_LCMP(REG_ITMP2, d); /* corner cases */
1374 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1375 ((REG_RESULT == d) ? 0 : 3);
1377 M_FLTMOVE(s1, REG_FTMP1);
1378 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1380 M_INTMOVE(REG_RESULT, d);
1381 emit_store_dst(jd, iptr, d);
1384 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1386 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1389 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1390 M_LCMP(REG_ITMP2, d); /* corner cases */
1391 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1392 ((REG_RESULT == d) ? 0 : 3);
1394 M_FLTMOVE(s1, REG_FTMP1);
1395 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1397 M_INTMOVE(REG_RESULT, d);
1398 emit_store_dst(jd, iptr, d);
1401 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1403 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1404 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1411 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1412 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1414 emit_store_dst(jd, iptr, d);
1417 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1418 /* == => 0, < => 1, > => -1 */
1420 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1421 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1424 M_MOV_IMM(1, REG_ITMP1);
1425 M_MOV_IMM(-1, REG_ITMP2);
1426 emit_ucomiss_reg_reg(cd, s1, s2);
1427 M_CMOVULT(REG_ITMP1, d);
1428 M_CMOVUGT(REG_ITMP2, d);
1429 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1434 /* == => 0, < => 1, > => -1 */
1436 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1437 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1438 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1440 M_MOV_IMM(1, REG_ITMP1);
1441 M_MOV_IMM(-1, REG_ITMP2);
1442 emit_ucomiss_reg_reg(cd, s1, s2);
1443 M_CMOVULT(REG_ITMP1, d);
1444 M_CMOVUGT(REG_ITMP2, d);
1445 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1446 emit_store_dst(jd, iptr, d);
1449 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1450 /* == => 0, < => 1, > => -1 */
1452 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1456 M_MOV_IMM(1, REG_ITMP1);
1457 M_MOV_IMM(-1, REG_ITMP2);
1458 emit_ucomisd_reg_reg(cd, s1, s2);
1459 M_CMOVULT(REG_ITMP1, d);
1460 M_CMOVUGT(REG_ITMP2, d);
1461 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1466 /* == => 0, < => 1, > => -1 */
1468 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1469 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1470 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1472 M_MOV_IMM(1, REG_ITMP1);
1473 M_MOV_IMM(-1, REG_ITMP2);
1474 emit_ucomisd_reg_reg(cd, s1, s2);
1475 M_CMOVULT(REG_ITMP1, d);
1476 M_CMOVUGT(REG_ITMP2, d);
1477 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1478 emit_store_dst(jd, iptr, d);
1482 /* memory operations **************************************************/
1484 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1488 /* implicit null-pointer check */
1489 M_ILD(d, s1, OFFSET(java_array_t, size));
1490 emit_store_dst(jd, iptr, d);
1493 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1497 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1498 /* implicit null-pointer check */
1499 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1500 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1501 emit_store_dst(jd, iptr, d);
1504 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1509 /* implicit null-pointer check */
1510 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1511 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1512 emit_store_dst(jd, iptr, d);
1515 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1520 /* implicit null-pointer check */
1521 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1522 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1523 emit_store_dst(jd, iptr, d);
1526 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1529 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1531 /* implicit null-pointer check */
1532 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1533 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1534 emit_store_dst(jd, iptr, d);
1537 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1542 /* implicit null-pointer check */
1543 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1544 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1545 emit_store_dst(jd, iptr, d);
1548 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1552 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1553 /* implicit null-pointer check */
1554 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1555 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1563 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1564 /* implicit null-pointer check */
1565 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1566 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1575 /* implicit null-pointer check */
1576 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1577 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1578 emit_store_dst(jd, iptr, d);
1582 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1585 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1586 /* implicit null-pointer check */
1587 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1588 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1589 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1592 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1595 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1596 /* implicit null-pointer check */
1597 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1598 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1599 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1602 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1605 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1606 /* implicit null-pointer check */
1607 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1608 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1609 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1612 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1615 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1616 /* implicit null-pointer check */
1617 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1618 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1619 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1622 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1626 /* implicit null-pointer check */
1627 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1628 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1629 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1632 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1635 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1636 /* implicit null-pointer check */
1637 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1638 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1639 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1642 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1646 /* implicit null-pointer check */
1647 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1648 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1649 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1652 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1655 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1656 /* implicit null-pointer check */
1657 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1658 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1662 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1664 emit_arraystore_check(cd, iptr);
1666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1667 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1668 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1669 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1673 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1676 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1677 /* implicit null-pointer check */
1678 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1679 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1682 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1686 /* implicit null-pointer check */
1687 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1688 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1691 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1695 /* implicit null-pointer check */
1696 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1697 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1700 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1704 /* implicit null-pointer check */
1705 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1706 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1709 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1713 /* implicit null-pointer check */
1714 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1716 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1717 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1720 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1721 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1725 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1729 /* implicit null-pointer check */
1730 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1731 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1735 case ICMD_GETSTATIC: /* ... ==> ..., value */
1737 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1738 uf = iptr->sx.s23.s3.uf;
1739 fieldtype = uf->fieldref->parseddesc.fd->type;
1740 disp = dseg_add_unique_address(cd, uf);
1742 /* PROFILE_CYCLE_STOP; */
1744 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1746 /* PROFILE_CYCLE_START; */
1749 fi = iptr->sx.s23.s3.fmiref->p.field;
1750 fieldtype = fi->type;
1751 disp = dseg_add_address(cd, fi->value);
1753 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1756 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1759 PROFILE_CYCLE_START;
1763 /* This approach is much faster than moving the field
1764 address inline into a register. */
1766 M_ALD(REG_ITMP1, RIP, disp);
1768 switch (fieldtype) {
1770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1771 M_ILD(d, REG_ITMP1, 0);
1775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1776 M_LLD(d, REG_ITMP1, 0);
1779 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1780 M_FLD(d, REG_ITMP1, 0);
1783 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1784 M_DLD(d, REG_ITMP1, 0);
1787 emit_store_dst(jd, iptr, d);
1790 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1792 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1793 uf = iptr->sx.s23.s3.uf;
1794 fieldtype = uf->fieldref->parseddesc.fd->type;
1795 disp = dseg_add_unique_address(cd, uf);
1797 /* PROFILE_CYCLE_STOP; */
1799 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1801 /* PROFILE_CYCLE_START; */
1804 fi = iptr->sx.s23.s3.fmiref->p.field;
1805 fieldtype = fi->type;
1806 disp = dseg_add_address(cd, fi->value);
1808 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1811 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1814 PROFILE_CYCLE_START;
1818 /* This approach is much faster than moving the field
1819 address inline into a register. */
1821 M_ALD(REG_ITMP1, RIP, disp);
1823 switch (fieldtype) {
1825 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1826 M_IST(s1, REG_ITMP1, 0);
1830 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1831 M_LST(s1, REG_ITMP1, 0);
1834 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1835 M_FST(s1, REG_ITMP1, 0);
1838 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1839 M_DST(s1, REG_ITMP1, 0);
1844 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1845 /* val = value (in current instruction) */
1846 /* following NOP) */
1848 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1849 uf = iptr->sx.s23.s3.uf;
1850 fieldtype = uf->fieldref->parseddesc.fd->type;
1851 disp = dseg_add_unique_address(cd, uf);
1853 /* PROFILE_CYCLE_STOP; */
1855 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1857 /* PROFILE_CYCLE_START; */
1860 fi = iptr->sx.s23.s3.fmiref->p.field;
1861 fieldtype = fi->type;
1862 disp = dseg_add_address(cd, fi->value);
1864 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1867 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1870 PROFILE_CYCLE_START;
1874 /* This approach is much faster than moving the field
1875 address inline into a register. */
1877 M_ALD(REG_ITMP1, RIP, disp);
1879 switch (fieldtype) {
1882 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1887 if (IS_IMM32(iptr->sx.s23.s2.constval))
1888 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1890 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1891 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1897 case ICMD_GETFIELD: /* ... ==> ..., value */
1899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1902 uf = iptr->sx.s23.s3.uf;
1903 fieldtype = uf->fieldref->parseddesc.fd->type;
1906 /* PROFILE_CYCLE_STOP; */
1908 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1910 /* PROFILE_CYCLE_START; */
1913 fi = iptr->sx.s23.s3.fmiref->p.field;
1914 fieldtype = fi->type;
1918 /* implicit null-pointer check */
1919 switch (fieldtype) {
1921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1922 M_ILD32(d, s1, disp);
1926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1927 M_LLD32(d, s1, disp);
1930 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1931 M_FLD32(d, s1, disp);
1934 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1935 M_DLD32(d, s1, disp);
1938 emit_store_dst(jd, iptr, d);
1941 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1946 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1947 uf = iptr->sx.s23.s3.uf;
1948 fieldtype = uf->fieldref->parseddesc.fd->type;
1951 /* PROFILE_CYCLE_STOP; */
1953 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1955 /* PROFILE_CYCLE_START; */
1958 fi = iptr->sx.s23.s3.fmiref->p.field;
1959 fieldtype = fi->type;
1963 /* implicit null-pointer check */
1964 switch (fieldtype) {
1966 M_IST32(s2, s1, disp);
1970 M_LST32(s2, s1, disp);
1973 M_FST32(s2, s1, disp);
1976 M_DST32(s2, s1, disp);
1981 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1982 /* val = value (in current instruction) */
1983 /* following NOP) */
1985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1988 uf = iptr->sx.s23.s3.uf;
1989 fieldtype = uf->fieldref->parseddesc.fd->type;
1992 /* PROFILE_CYCLE_STOP; */
1994 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1996 /* PROFILE_CYCLE_START; */
1999 fi = iptr->sx.s23.s3.fmiref->p.field;
2000 fieldtype = fi->type;
2004 /* implicit null-pointer check */
2005 switch (fieldtype) {
2008 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2013 /* XXX why no check for IS_IMM32? */
2014 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2015 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2021 /* branch operations **************************************************/
2023 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2026 M_INTMOVE(s1, REG_ITMP1_XPTR);
2030 #ifdef ENABLE_VERIFIER
2031 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2032 uc = iptr->sx.s23.s2.uc;
2034 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2036 #endif /* ENABLE_VERIFIER */
2038 M_CALL_IMM(0); /* passing exception pc */
2039 M_POP(REG_ITMP2_XPC);
2041 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2045 case ICMD_GOTO: /* ... ==> ... */
2048 emit_br(cd, iptr->dst.block);
2052 case ICMD_JSR: /* ... ==> ... */
2054 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2058 case ICMD_IFNULL: /* ..., value ==> ... */
2059 case ICMD_IFNONNULL:
2061 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2066 case ICMD_IFEQ: /* ..., value ==> ... */
2073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2074 M_ICMP_IMM(iptr->sx.val.i, s1);
2075 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2078 case ICMD_IF_LEQ: /* ..., value ==> ... */
2085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2086 if (IS_IMM32(iptr->sx.val.l))
2087 M_LCMP_IMM(iptr->sx.val.l, s1);
2089 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2090 M_LCMP(REG_ITMP2, s1);
2092 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2095 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2096 case ICMD_IF_ICMPNE:
2097 case ICMD_IF_ICMPLT:
2098 case ICMD_IF_ICMPGE:
2099 case ICMD_IF_ICMPGT:
2100 case ICMD_IF_ICMPLE:
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2105 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2108 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2109 case ICMD_IF_ACMPNE:
2111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2112 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2114 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2117 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2118 case ICMD_IF_LCMPNE:
2119 case ICMD_IF_LCMPLT:
2120 case ICMD_IF_LCMPGE:
2121 case ICMD_IF_LCMPGT:
2122 case ICMD_IF_LCMPLE:
2124 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2125 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2127 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2130 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2133 REPLACEMENT_POINT_RETURN(cd, iptr);
2134 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2135 M_INTMOVE(s1, REG_RESULT);
2136 goto nowperformreturn;
2138 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2140 REPLACEMENT_POINT_RETURN(cd, iptr);
2141 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2142 M_INTMOVE(s1, REG_RESULT);
2144 #ifdef ENABLE_VERIFIER
2145 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2146 uc = iptr->sx.s23.s2.uc;
2150 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2152 PROFILE_CYCLE_START;
2154 #endif /* ENABLE_VERIFIER */
2155 goto nowperformreturn;
2157 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2160 REPLACEMENT_POINT_RETURN(cd, iptr);
2161 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2162 M_FLTMOVE(s1, REG_FRESULT);
2163 goto nowperformreturn;
2165 case ICMD_RETURN: /* ... ==> ... */
2167 REPLACEMENT_POINT_RETURN(cd, iptr);
2173 p = cd->stackframesize;
2175 #if !defined(NDEBUG)
2176 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2177 emit_verbosecall_exit(jd);
2178 #endif /* !defined(NDEBUG) */
2180 #if defined(ENABLE_THREADS)
2181 if (checksync && code_is_synchronized(code)) {
2182 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2184 /* we need to save the proper return value */
2185 switch (iptr->opc) {
2189 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2193 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2197 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2200 /* and now restore the proper return value */
2201 switch (iptr->opc) {
2205 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2209 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2215 /* restore saved registers */
2217 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2218 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2220 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2221 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2224 /* deallocate stack */
2226 if (cd->stackframesize)
2227 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2229 /* generate method profiling code */
2238 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2241 branch_target_t *table;
2243 table = iptr->dst.table;
2245 l = iptr->sx.s23.s2.tablelow;
2246 i = iptr->sx.s23.s3.tablehigh;
2248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2249 M_INTMOVE(s1, REG_ITMP1);
2252 M_ISUB_IMM(l, REG_ITMP1);
2254 /* number of targets */
2259 M_ICMP_IMM(i - 1, REG_ITMP1);
2260 emit_bugt(cd, table[0].block);
2262 /* build jump table top down and use address of lowest entry */
2267 dseg_add_target(cd, table->block);
2271 /* length of dataseg after last dseg_add_target is used
2274 M_MOV_IMM(0, REG_ITMP2);
2276 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2282 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2285 lookup_target_t *lookup;
2287 lookup = iptr->dst.lookup;
2289 i = iptr->sx.s23.s2.lookupcount;
2291 MCODECHECK(8 + ((7 + 6) * i) + 5);
2292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2295 M_ICMP_IMM(lookup->value, s1);
2296 emit_beq(cd, lookup->target.block);
2300 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2306 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2308 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2310 bte = iptr->sx.s23.s3.bte;
2314 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2316 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2317 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2318 case ICMD_INVOKEINTERFACE:
2320 REPLACEMENT_POINT_INVOKE(cd, iptr);
2322 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2324 um = iptr->sx.s23.s3.um;
2325 md = um->methodref->parseddesc.md;
2328 lm = iptr->sx.s23.s3.fmiref->p.method;
2330 md = lm->parseddesc;
2334 s3 = md->paramcount;
2336 MCODECHECK((20 * s3) + 128);
2338 /* copy arguments to registers or stack location */
2340 for (s3 = s3 - 1; s3 >= 0; s3--) {
2341 var = VAR(iptr->sx.s23.s2.args[s3]);
2342 d = md->params[s3].regoff;
2344 /* already preallocated (ARGVAR)? */
2346 if (var->flags & PREALLOC)
2349 if (IS_INT_LNG_TYPE(var->type)) {
2350 if (!md->params[s3].inmemory) {
2351 s1 = emit_load(jd, iptr, var, d);
2355 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2356 M_LST(s1, REG_SP, d);
2360 if (!md->params[s3].inmemory) {
2361 s1 = emit_load(jd, iptr, var, d);
2365 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2367 if (IS_2_WORD_TYPE(var->type))
2368 M_DST(s1, REG_SP, d);
2370 M_FST(s1, REG_SP, d);
2375 /* generate method profiling code */
2379 switch (iptr->opc) {
2381 if (bte->stub == NULL) {
2382 M_MOV_IMM(bte->fp, REG_ITMP1);
2385 M_MOV_IMM(bte->stub, REG_ITMP1);
2390 case ICMD_INVOKESPECIAL:
2391 emit_nullpointer_check(cd, iptr, REG_A0);
2394 case ICMD_INVOKESTATIC:
2396 disp = dseg_add_unique_address(cd, um);
2398 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2402 disp = dseg_add_functionptr(cd, lm->stubroutine);
2405 M_ALD(REG_ITMP2, RIP, disp);
2409 case ICMD_INVOKEVIRTUAL:
2411 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2416 s1 = OFFSET(vftbl_t, table[0]) +
2417 sizeof(methodptr) * lm->vftblindex;
2420 /* implicit null-pointer check */
2421 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2422 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2426 case ICMD_INVOKEINTERFACE:
2428 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2434 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2435 sizeof(methodptr) * lm->class->index;
2437 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2440 /* implicit null-pointer check */
2441 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2442 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2443 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2448 /* generate method profiling code */
2450 PROFILE_CYCLE_START;
2452 /* store size of call code in replacement point */
2454 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2455 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2457 /* store return value */
2459 switch (md->returntype.type) {
2463 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2464 M_INTMOVE(REG_RESULT, s1);
2465 emit_store_dst(jd, iptr, s1);
2469 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2470 M_FLTMOVE(REG_FRESULT, s1);
2471 emit_store_dst(jd, iptr, s1);
2480 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2482 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2483 /* object type cast-check */
2488 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2493 super = iptr->sx.s23.s3.c.cls;
2494 superindex = super->index;
2497 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2498 CODEGEN_CRITICAL_SECTION_NEW;
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 CODEGEN_CRITICAL_SECTION_START;
2574 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2576 /* if (s1 != REG_ITMP1) { */
2577 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2578 /* OFFSET(vftbl_t, baseval), */
2580 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2581 /* OFFSET(vftbl_t, diffval), */
2583 /* #if defined(ENABLE_THREADS) */
2584 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2586 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2590 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2591 M_ISUB(REG_ITMP3, REG_ITMP2);
2592 M_ALD(REG_ITMP3, RIP, disp);
2593 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2596 CODEGEN_CRITICAL_SECTION_END;
2598 M_ICMP(REG_ITMP3, REG_ITMP2);
2599 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2602 emit_label(cd, BRANCH_LABEL_5);
2605 if (super == NULL) {
2606 emit_label(cd, BRANCH_LABEL_1);
2607 emit_label(cd, BRANCH_LABEL_4);
2610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2613 /* array type cast-check */
2615 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2616 M_INTMOVE(s1, REG_A0);
2618 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2619 cr = iptr->sx.s23.s3.c.ref;
2620 disp = dseg_add_unique_address(cd, cr);
2622 patcher_add_patch_ref(jd,
2623 PATCHER_resolve_classref_to_classinfo,
2627 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2630 M_ALD(REG_A1, RIP, disp);
2631 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2634 /* s1 may have been destroyed over the function call */
2635 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2637 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2643 emit_store_dst(jd, iptr, d);
2646 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2652 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2657 super = iptr->sx.s23.s3.c.cls;
2658 superindex = super->index;
2661 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2662 CODEGEN_CRITICAL_SECTION_NEW;
2664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2668 M_INTMOVE(s1, REG_ITMP1);
2674 /* if class is not resolved, check which code to call */
2676 if (super == NULL) {
2678 emit_label_beq(cd, BRANCH_LABEL_1);
2680 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2681 iptr->sx.s23.s3.c.ref, 0);
2683 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2684 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2685 emit_label_beq(cd, BRANCH_LABEL_2);
2688 /* interface instanceof code */
2690 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2691 if (super != NULL) {
2693 emit_label_beq(cd, BRANCH_LABEL_3);
2696 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2698 if (super == NULL) {
2699 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2700 iptr->sx.s23.s3.c.ref, 0);
2704 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2705 M_ICMP_IMM32(superindex, REG_ITMP3);
2707 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2710 M_ALD32(REG_ITMP1, REG_ITMP1,
2711 OFFSET(vftbl_t, interfacetable[0]) -
2712 superindex * sizeof(methodptr*));
2717 emit_label_br(cd, BRANCH_LABEL_4);
2719 emit_label(cd, BRANCH_LABEL_3);
2722 /* class instanceof code */
2724 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2725 if (super == NULL) {
2726 emit_label(cd, BRANCH_LABEL_2);
2728 cr = iptr->sx.s23.s3.c.ref;
2729 disp = dseg_add_unique_address(cd, cr);
2731 patcher_add_patch_ref(jd,
2732 PATCHER_resolve_classref_to_vftbl,
2737 emit_label_beq(cd, BRANCH_LABEL_5);
2739 disp = dseg_add_address(cd, super->vftbl);
2742 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2743 M_ALD(REG_ITMP2, RIP, disp);
2745 CODEGEN_CRITICAL_SECTION_START;
2747 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2748 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2749 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2751 CODEGEN_CRITICAL_SECTION_END;
2753 M_ISUB(REG_ITMP2, REG_ITMP1);
2754 M_CLR(d); /* may be REG_ITMP2 */
2755 M_ICMP(REG_ITMP3, REG_ITMP1);
2759 emit_label(cd, BRANCH_LABEL_5);
2762 if (super == NULL) {
2763 emit_label(cd, BRANCH_LABEL_1);
2764 emit_label(cd, BRANCH_LABEL_4);
2767 emit_store_dst(jd, iptr, d);
2771 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2773 /* check for negative sizes and copy sizes to stack if necessary */
2775 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2777 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2779 /* copy SAVEDVAR sizes to stack */
2780 var = VAR(iptr->sx.s23.s2.args[s1]);
2782 /* Already Preallocated? */
2783 if (!(var->flags & PREALLOC)) {
2784 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2785 M_LST(s2, REG_SP, s1 * 8);
2789 /* a0 = dimension count */
2791 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2793 /* is a patcher function set? */
2795 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2796 cr = iptr->sx.s23.s3.c.ref;
2797 disp = dseg_add_unique_address(cd, cr);
2799 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2803 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2806 /* a1 = classinfo */
2808 M_ALD(REG_A1, RIP, disp);
2810 /* a2 = pointer to dimensions = stack pointer */
2812 M_MOV(REG_SP, REG_A2);
2814 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2817 /* check for exception before result assignment */
2819 emit_exception_check(cd, iptr);
2821 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2822 M_INTMOVE(REG_RESULT, s1);
2823 emit_store_dst(jd, iptr, s1);
2827 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2832 } /* for instruction */
2834 MCODECHECK(512); /* XXX require a lower number? */
2836 /* At the end of a basic block we may have to append some nops,
2837 because the patcher stub calling code might be longer than the
2838 actual instruction. So codepatching does not change the
2839 following block unintentionally. */
2841 if (cd->mcodeptr < cd->lastmcodeptr) {
2842 while (cd->mcodeptr < cd->lastmcodeptr) {
2847 } /* if (bptr -> flags >= BBREACHED) */
2848 } /* for basic block */
2850 /* Generate patcher traps. */
2852 emit_patcher_traps(jd);
2854 /* everything's ok */
2860 /* codegen_emit_stub_native ****************************************************
2862 Emits a stub routine which calls a native method.
2864 *******************************************************************************/
2866 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2880 /* Get required compiler data. */
2886 /* initialize variables */
2890 /* calculate stack frame size */
2892 cd->stackframesize =
2893 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2894 sizeof(localref_table) / SIZEOF_VOID_P +
2896 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2899 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2901 /* create method header */
2903 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2904 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2905 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2906 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2907 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2909 #if defined(ENABLE_PROFILING)
2910 /* generate native method profiling code */
2912 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2913 /* count frequency */
2915 M_MOV_IMM(code, REG_ITMP3);
2916 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2920 /* generate stub code */
2922 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2924 #if defined(ENABLE_GC_CACAO)
2925 /* Save callee saved integer registers in stackframeinfo (GC may
2926 need to recover them during a collection). */
2928 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2929 OFFSET(stackframeinfo_t, intregs);
2931 for (i = 0; i < INT_SAV_CNT; i++)
2932 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2935 /* save integer and float argument registers */
2937 for (i = 0; i < md->paramcount; i++) {
2938 if (!md->params[i].inmemory) {
2939 s1 = md->params[i].regoff;
2941 switch (md->paramtypes[i].type) {
2945 M_LST(s1, REG_SP, i * 8);
2949 M_DST(s1, REG_SP, i * 8);
2955 /* create dynamic stack info */
2957 M_MOV(REG_SP, REG_A0);
2958 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2959 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2962 /* remember class argument */
2964 if (m->flags & ACC_STATIC)
2965 M_MOV(REG_RESULT, REG_ITMP2);
2967 /* restore integer and float argument registers */
2969 for (i = 0; i < md->paramcount; i++) {
2970 if (!md->params[i].inmemory) {
2971 s1 = md->params[i].regoff;
2973 switch (md->paramtypes[i].type) {
2977 M_LLD(s1, REG_SP, i * 8);
2981 M_DLD(s1, REG_SP, i * 8);
2987 /* Copy or spill arguments to new locations. */
2989 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2990 s2 = nmd->params[j].regoff;
2992 switch (md->paramtypes[i].type) {
2996 if (!md->params[i].inmemory) {
2997 s1 = md->params[i].regoff;
2999 if (!nmd->params[j].inmemory)
3002 M_LST(s1, REG_SP, s2);
3005 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3006 M_LLD(REG_ITMP1, REG_SP, s1);
3007 M_LST(REG_ITMP1, REG_SP, s2);
3011 /* We only copy spilled float arguments, as the float
3012 argument registers keep unchanged. */
3014 if (md->params[i].inmemory) {
3015 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3017 M_FLD(REG_FTMP1, REG_SP, s1);
3018 M_FST(REG_FTMP1, REG_SP, s2);
3022 if (md->params[i].inmemory) {
3023 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3024 M_DLD(REG_FTMP1, REG_SP, s1);
3025 M_DST(REG_FTMP1, REG_SP, s2);
3031 /* Handle native Java methods. */
3033 if (m->flags & ACC_NATIVE) {
3034 /* put class into second argument register */
3036 if (m->flags & ACC_STATIC)
3037 M_MOV(REG_ITMP2, REG_A1);
3039 /* put env into first argument register */
3041 M_MOV_IMM(_Jv_env, REG_A0);
3044 /* Call the native function. */
3046 disp = dseg_add_functionptr(cd, f);
3047 M_ALD(REG_ITMP1, RIP, disp);
3050 /* save return value */
3052 switch (md->returntype.type) {
3056 M_LST(REG_RESULT, REG_SP, 0 * 8);
3060 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3066 /* remove native stackframe info */
3068 M_MOV(REG_SP, REG_A0);
3069 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3070 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3072 M_MOV(REG_RESULT, REG_ITMP3);
3074 /* restore return value */
3076 switch (md->returntype.type) {
3080 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3084 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3090 #if defined(ENABLE_GC_CACAO)
3091 /* Restore callee saved integer registers from stackframeinfo (GC
3092 might have modified them during a collection). */
3094 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3095 OFFSET(stackframeinfo_t, intregs);
3097 for (i = 0; i < INT_SAV_CNT; i++)
3098 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3101 /* remove stackframe */
3103 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3105 /* test for exception */
3111 /* handle exception */
3113 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3114 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3115 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3117 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3123 * These are local overrides for various environment variables in Emacs.
3124 * Please do not remove this and leave it at the end of the file, where
3125 * Emacs will automagically detect them.
3126 * ---------------------------------------------------------------------
3129 * indent-tabs-mode: t
3133 * vim:noexpandtab:sw=4:ts=4: