1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
38 #include "vm/jit/x86_64/arch.h"
39 #include "vm/jit/x86_64/codegen.h"
40 #include "vm/jit/x86_64/emit.h"
42 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/localref.h"
46 #include "native/native.h"
48 #include "threads/lock-common.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/stringlocal.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/code.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/emit-common.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/parse.h"
65 #include "vm/jit/patcher-common.h"
66 #include "vm/jit/reg.h"
67 #include "vm/jit/replace.h"
68 #include "vm/jit/stacktrace.h"
70 #if defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
74 #include "vmcore/loader.h"
75 #include "vmcore/options.h"
76 #include "vmcore/statistics.h"
79 /* codegen_emit ****************************************************************
81 Generates machine code.
83 *******************************************************************************/
85 bool codegen_emit(jitdata *jd)
91 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 /* space to save used callee saved registers */
131 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
132 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
134 cd->stackframesize = rd->memuse + savedregs_num;
136 #if defined(ENABLE_THREADS)
137 /* space to save argument of monitor_enter */
139 if (checksync && code_is_synchronized(code))
140 cd->stackframesize++;
143 /* Keep stack of non-leaf functions 16-byte aligned for calls into
144 native code e.g. libc or jni (alignment problems with
147 if (!code_is_leafmethod(code) || opt_verbosecall)
148 cd->stackframesize |= 0x1;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
160 /* XXX Remove this "offset by one". */
162 code->synchronizedoffset = (rd->memuse + 1) * 8;
164 if (code_is_leafmethod(code))
165 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
167 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
169 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
170 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
172 (void) dseg_addlinenumbertablesize(cd);
174 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
176 /* create exception table */
178 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
179 dseg_add_target(cd, ex->start);
180 dseg_add_target(cd, ex->end);
181 dseg_add_target(cd, ex->handler);
182 (void) dseg_add_unique_address(cd, ex->catchtype.any);
185 #if defined(ENABLE_PROFILING)
186 /* generate method profiling code */
188 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
189 /* count frequency */
191 M_MOV_IMM(code, REG_ITMP3);
192 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
198 /* create stack frame (if necessary) */
200 if (cd->stackframesize)
201 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
203 /* save used callee saved registers */
205 p = cd->stackframesize;
206 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
207 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
209 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
210 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
213 /* take arguments out of register or stack frame */
217 for (p = 0, l = 0; p < md->paramcount; p++) {
218 t = md->paramtypes[p].type;
220 varindex = jd->local_map[l * 5 + t];
223 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
226 if (varindex == UNUSED)
231 s1 = md->params[p].regoff;
233 if (IS_INT_LNG_TYPE(t)) { /* integer args */
234 if (!md->params[p].inmemory) { /* register arguments */
235 if (!IS_INMEMORY(var->flags))
236 M_INTMOVE(s1, var->vv.regoff);
238 M_LST(s1, REG_SP, var->vv.regoff);
240 else { /* stack arguments */
241 if (!IS_INMEMORY(var->flags))
242 /* + 8 for return address */
243 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
245 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
248 else { /* floating args */
249 if (!md->params[p].inmemory) { /* register arguments */
250 if (!IS_INMEMORY(var->flags))
251 M_FLTMOVE(s1, var->vv.regoff);
253 M_DST(s1, REG_SP, var->vv.regoff);
255 else { /* stack arguments */
256 if (!IS_INMEMORY(var->flags))
257 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
259 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
264 /* save monitorenter argument */
266 #if defined(ENABLE_THREADS)
267 if (checksync && code_is_synchronized(code)) {
268 /* stack offset for monitor argument */
272 if (opt_verbosecall) {
273 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
275 for (p = 0; p < INT_ARG_CNT; p++)
276 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
278 for (p = 0; p < FLT_ARG_CNT; p++)
279 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
281 s1 += INT_ARG_CNT + FLT_ARG_CNT;
284 /* decide which monitor enter function to call */
286 if (m->flags & ACC_STATIC) {
287 M_MOV_IMM(&m->class->object.header, REG_A0);
292 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
295 M_AST(REG_A0, REG_SP, s1 * 8);
296 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
299 if (opt_verbosecall) {
300 for (p = 0; p < INT_ARG_CNT; p++)
301 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
303 for (p = 0; p < FLT_ARG_CNT; p++)
304 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
306 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
312 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
313 emit_verbosecall_enter(jd);
314 #endif /* !defined(NDEBUG) */
318 /* end of header generation */
320 /* create replacement points */
322 REPLACEMENT_POINTS_INIT(cd, jd);
324 /* walk through all basic blocks */
326 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
328 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
330 if (bptr->flags >= BBREACHED) {
332 /* branch resolving */
334 codegen_resolve_branchrefs(cd, bptr);
336 /* handle replacement points */
338 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
340 /* copy interface registers to their destination */
345 #if defined(ENABLE_PROFILING)
346 /* generate basicblock profiling code */
348 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
349 /* count frequency */
351 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
352 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
354 /* if this is an exception handler, start profiling again */
356 if (bptr->type == BBTYPE_EXH)
361 #if defined(ENABLE_LSRA)
365 src = bptr->invars[len];
366 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
367 if (bptr->type == BBTYPE_EXH) {
368 /* d = reg_of_var(rd, src, REG_ITMP1); */
369 if (!IS_INMEMORY(src->flags))
373 M_INTMOVE(REG_ITMP1, d);
374 emit_store(jd, NULL, src, d);
384 var = VAR(bptr->invars[len]);
385 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
386 if (bptr->type == BBTYPE_EXH) {
387 d = codegen_reg_of_var(0, var, REG_ITMP1);
388 M_INTMOVE(REG_ITMP1, d);
389 emit_store(jd, NULL, var, d);
393 assert((var->flags & INOUT));
396 #if defined(ENABLE_LSRA)
399 /* walk through all instructions */
404 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
405 if (iptr->line != currentline) {
406 dseg_addlinenumber(cd, iptr->line);
407 currentline = iptr->line;
410 MCODECHECK(1024); /* 1KB should be enough */
413 case ICMD_NOP: /* ... ==> ... */
414 case ICMD_POP: /* ..., value ==> ... */
415 case ICMD_POP2: /* ..., value, value ==> ... */
418 case ICMD_INLINE_START:
420 REPLACEMENT_POINT_INLINE_START(cd, iptr);
423 case ICMD_INLINE_BODY:
425 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
426 dseg_addlinenumber_inline_start(cd, iptr);
427 dseg_addlinenumber(cd, iptr->line);
430 case ICMD_INLINE_END:
432 dseg_addlinenumber_inline_end(cd, iptr);
433 dseg_addlinenumber(cd, iptr->line);
436 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
439 emit_nullpointer_check(cd, iptr, s1);
442 /* constant operations ************************************************/
444 case ICMD_ICONST: /* ... ==> ..., constant */
446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
447 ICONST(d, iptr->sx.val.i);
448 emit_store_dst(jd, iptr, d);
451 case ICMD_LCONST: /* ... ==> ..., constant */
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454 LCONST(d, iptr->sx.val.l);
455 emit_store_dst(jd, iptr, d);
458 case ICMD_FCONST: /* ... ==> ..., constant */
460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
461 disp = dseg_add_float(cd, iptr->sx.val.f);
462 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
463 emit_store_dst(jd, iptr, d);
466 case ICMD_DCONST: /* ... ==> ..., constant */
468 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
469 disp = dseg_add_double(cd, iptr->sx.val.d);
470 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
471 emit_store_dst(jd, iptr, d);
474 case ICMD_ACONST: /* ... ==> ..., constant */
476 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
478 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
479 cr = iptr->sx.val.c.ref;
480 disp = dseg_add_unique_address(cd, cr);
482 /* PROFILE_CYCLE_STOP; */
484 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
487 /* PROFILE_CYCLE_START; */
492 if (iptr->sx.val.anyptr == 0) {
496 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
500 emit_store_dst(jd, iptr, d);
504 /* load/store/copy/move operations ************************************/
506 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
507 case ICMD_ALOAD: /* s1 = local variable */
511 case ICMD_ISTORE: /* ..., value ==> ... */
522 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
526 /* integer operations *************************************************/
528 case ICMD_INEG: /* ..., value ==> ..., - value */
530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
534 emit_store_dst(jd, iptr, d);
537 case ICMD_LNEG: /* ..., value ==> ..., - value */
539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
540 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
543 emit_store_dst(jd, iptr, d);
546 case ICMD_I2L: /* ..., value ==> ..., value */
548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_L2I: /* ..., value ==> ..., value */
556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
559 emit_store_dst(jd, iptr, d);
562 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
567 emit_store_dst(jd, iptr, d);
570 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
573 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
575 emit_store_dst(jd, iptr, d);
578 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
583 emit_store_dst(jd, iptr, d);
587 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
590 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598 emit_store_dst(jd, iptr, d);
602 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
603 /* sx.val.i = constant */
605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
608 /* Using inc and dec is not faster than add (tested with
612 M_IADD_IMM(iptr->sx.val.i, d);
613 emit_store_dst(jd, iptr, d);
616 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 emit_store_dst(jd, iptr, d);
630 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
631 /* sx.val.l = constant */
633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
636 if (IS_IMM32(iptr->sx.val.l))
637 M_LADD_IMM(iptr->sx.val.l, d);
639 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
640 M_LADD(REG_ITMP2, d);
642 emit_store_dst(jd, iptr, d);
645 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
651 M_INTMOVE(s1, REG_ITMP1);
652 M_ISUB(s2, REG_ITMP1);
653 M_INTMOVE(REG_ITMP1, d);
658 emit_store_dst(jd, iptr, d);
661 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
662 /* sx.val.i = constant */
664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
667 M_ISUB_IMM(iptr->sx.val.i, d);
668 emit_store_dst(jd, iptr, d);
671 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 M_INTMOVE(s1, REG_ITMP1);
678 M_LSUB(s2, REG_ITMP1);
679 M_INTMOVE(REG_ITMP1, d);
684 emit_store_dst(jd, iptr, d);
687 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
688 /* sx.val.l = constant */
690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
693 if (IS_IMM32(iptr->sx.val.l))
694 M_LSUB_IMM(iptr->sx.val.l, d);
696 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
697 M_LSUB(REG_ITMP2, d);
699 emit_store_dst(jd, iptr, d);
702 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
713 emit_store_dst(jd, iptr, d);
716 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
717 /* sx.val.i = constant */
719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
721 if (iptr->sx.val.i == 2) {
725 M_IMUL_IMM(s1, iptr->sx.val.i, d);
726 emit_store_dst(jd, iptr, d);
729 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
740 emit_store_dst(jd, iptr, d);
743 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
744 /* sx.val.l = constant */
746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
747 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
748 if (IS_IMM32(iptr->sx.val.l))
749 M_LMUL_IMM(s1, iptr->sx.val.l, d);
751 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
753 M_LMUL(REG_ITMP2, d);
755 emit_store_dst(jd, iptr, d);
758 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
760 s1 = emit_load_s1(jd, iptr, RAX);
761 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
762 d = codegen_reg_of_dst(jd, iptr, RAX);
765 M_INTMOVE(s2, REG_ITMP3);
766 emit_arithmetic_check(cd, iptr, REG_ITMP3);
768 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
770 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
772 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
773 M_BEQ(1 + 3); /* 6 bytes */
775 emit_cltd(cd); /* 1 byte */
776 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
779 emit_store_dst(jd, iptr, d);
780 dst = VAROP(iptr->dst);
781 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
782 M_MOV(REG_ITMP2, RDX); /* restore RDX */
785 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
787 s1 = emit_load_s1(jd, iptr, RAX);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
789 d = codegen_reg_of_dst(jd, iptr, RDX);
792 M_INTMOVE(s2, REG_ITMP3);
793 emit_arithmetic_check(cd, iptr, REG_ITMP3);
795 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
797 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
799 M_CLR(RDX); /* 3 bytes */
800 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
801 M_BEQ(1 + 3); /* 6 bytes */
803 emit_cltd(cd); /* 1 byte */
804 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
807 emit_store_dst(jd, iptr, d);
808 dst = VAROP(iptr->dst);
809 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
810 M_MOV(REG_ITMP2, RDX); /* restore RDX */
813 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
814 /* sx.val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
818 M_INTMOVE(s1, REG_ITMP1);
819 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
820 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
821 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
822 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
823 emit_mov_reg_reg(cd, REG_ITMP1, d);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
828 /* sx.val.i = constant */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
832 M_INTMOVE(s1, REG_ITMP1);
833 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
834 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
835 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
836 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
837 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
838 emit_mov_reg_reg(cd, REG_ITMP1, d);
839 emit_store_dst(jd, iptr, d);
843 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
845 s1 = emit_load_s1(jd, iptr, RAX);
846 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
847 d = codegen_reg_of_dst(jd, iptr, RAX);
850 M_INTMOVE(s2, REG_ITMP3);
851 emit_arithmetic_check(cd, iptr, REG_ITMP3);
853 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
855 /* check as described in jvm spec */
856 disp = dseg_add_s8(cd, 0x8000000000000000LL);
857 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
859 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
860 M_BEQ(2 + 3); /* 6 bytes */
862 emit_cqto(cd); /* 2 bytes */
863 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
866 emit_store_dst(jd, iptr, d);
867 dst = VAROP(iptr->dst);
868 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
869 M_MOV(REG_ITMP2, RDX); /* restore RDX */
872 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
874 s1 = emit_load_s1(jd, iptr, RAX);
875 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
876 d = codegen_reg_of_dst(jd, iptr, RDX);
879 M_INTMOVE(s2, REG_ITMP3);
880 emit_arithmetic_check(cd, iptr, REG_ITMP3);
882 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
884 /* check as described in jvm spec */
885 disp = dseg_add_s8(cd, 0x8000000000000000LL);
886 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
888 M_LXOR(RDX, RDX); /* 3 bytes */
889 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
890 M_BEQ(2 + 3); /* 6 bytes */
892 emit_cqto(cd); /* 2 bytes */
893 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
896 emit_store_dst(jd, iptr, d);
897 dst = VAROP(iptr->dst);
898 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
899 M_MOV(REG_ITMP2, RDX); /* restore RDX */
902 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
903 /* sx.val.i = constant */
905 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
906 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
907 M_INTMOVE(s1, REG_ITMP1);
908 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
909 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
910 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
911 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
912 emit_mov_reg_reg(cd, REG_ITMP1, d);
913 emit_store_dst(jd, iptr, d);
916 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
917 /* sx.val.l = constant */
919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
920 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
921 M_INTMOVE(s1, REG_ITMP1);
922 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
923 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
924 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
925 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
926 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
927 emit_mov_reg_reg(cd, REG_ITMP1, d);
928 emit_store_dst(jd, iptr, d);
931 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
933 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
934 emit_ishift(jd, SHIFT_SHL, iptr);
937 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
938 /* sx.val.i = constant */
940 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
943 M_ISLL_IMM(iptr->sx.val.i, d);
944 emit_store_dst(jd, iptr, d);
947 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
949 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
950 emit_ishift(jd, SHIFT_SAR, iptr);
953 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
954 /* sx.val.i = constant */
956 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
959 M_ISRA_IMM(iptr->sx.val.i, d);
960 emit_store_dst(jd, iptr, d);
963 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
965 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
966 emit_ishift(jd, SHIFT_SHR, iptr);
969 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
970 /* sx.val.i = constant */
972 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975 M_ISRL_IMM(iptr->sx.val.i, d);
976 emit_store_dst(jd, iptr, d);
979 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
981 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
982 emit_lshift(jd, SHIFT_SHL, iptr);
985 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
986 /* sx.val.i = constant */
988 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
989 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
991 M_LSLL_IMM(iptr->sx.val.i, d);
992 emit_store_dst(jd, iptr, d);
995 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
997 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
998 emit_lshift(jd, SHIFT_SAR, iptr);
1001 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1002 /* sx.val.i = constant */
1004 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1005 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1007 M_LSRA_IMM(iptr->sx.val.i, d);
1008 emit_store_dst(jd, iptr, d);
1011 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1013 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1014 emit_lshift(jd, SHIFT_SHR, iptr);
1017 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1018 /* sx.val.l = constant */
1020 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1021 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1023 M_LSRL_IMM(iptr->sx.val.i, d);
1024 emit_store_dst(jd, iptr, d);
1027 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1030 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1031 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1038 emit_store_dst(jd, iptr, d);
1041 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1042 /* sx.val.i = constant */
1044 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1045 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1047 M_IAND_IMM(iptr->sx.val.i, d);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1062 emit_store_dst(jd, iptr, d);
1065 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1066 /* sx.val.l = constant */
1068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1069 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1071 if (IS_IMM32(iptr->sx.val.l))
1072 M_LAND_IMM(iptr->sx.val.l, d);
1074 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1075 M_LAND(REG_ITMP2, d);
1077 emit_store_dst(jd, iptr, d);
1080 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1082 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1083 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1084 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1091 emit_store_dst(jd, iptr, d);
1094 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1095 /* sx.val.i = constant */
1097 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1098 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1100 M_IOR_IMM(iptr->sx.val.i, d);
1101 emit_store_dst(jd, iptr, d);
1104 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1107 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1108 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1115 emit_store_dst(jd, iptr, d);
1118 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1119 /* sx.val.l = constant */
1121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1122 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1124 if (IS_IMM32(iptr->sx.val.l))
1125 M_LOR_IMM(iptr->sx.val.l, d);
1127 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1128 M_LOR(REG_ITMP2, d);
1130 emit_store_dst(jd, iptr, d);
1133 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1136 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1137 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1144 emit_store_dst(jd, iptr, d);
1147 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1148 /* sx.val.i = constant */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1153 M_IXOR_IMM(iptr->sx.val.i, d);
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1160 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1172 /* sx.val.l = constant */
1174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1175 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1177 if (IS_IMM32(iptr->sx.val.l))
1178 M_LXOR_IMM(iptr->sx.val.l, d);
1180 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1181 M_LXOR(REG_ITMP2, d);
1183 emit_store_dst(jd, iptr, d);
1187 /* floating operations ************************************************/
1189 case ICMD_FNEG: /* ..., value ==> ..., - value */
1191 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1193 disp = dseg_add_s4(cd, 0x80000000);
1195 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1196 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1197 emit_store_dst(jd, iptr, d);
1200 case ICMD_DNEG: /* ..., value ==> ..., - value */
1202 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1203 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 disp = dseg_add_s8(cd, 0x8000000000000000);
1206 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1207 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1213 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1214 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1215 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1222 emit_store_dst(jd, iptr, d);
1225 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1227 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1228 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1229 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1236 emit_store_dst(jd, iptr, d);
1239 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1241 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1242 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1243 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1245 M_FLTMOVE(s2, REG_FTMP2);
1250 emit_store_dst(jd, iptr, d);
1253 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1255 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1256 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1257 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1259 M_FLTMOVE(s2, REG_FTMP2);
1264 emit_store_dst(jd, iptr, d);
1267 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1269 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1270 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1271 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1278 emit_store_dst(jd, iptr, d);
1281 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1283 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1284 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1285 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1292 emit_store_dst(jd, iptr, d);
1295 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1297 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1298 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1299 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1301 M_FLTMOVE(s2, REG_FTMP2);
1306 emit_store_dst(jd, iptr, d);
1309 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1311 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1312 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1313 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1315 M_FLTMOVE(s2, REG_FTMP2);
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1326 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1328 emit_store_dst(jd, iptr, d);
1331 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1334 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1336 emit_store_dst(jd, iptr, d);
1339 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1341 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1342 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1352 emit_store_dst(jd, iptr, d);
1355 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1357 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1358 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1360 M_ICMP_IMM(0x80000000, d); /* corner cases */
1361 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1362 ((REG_RESULT == d) ? 0 : 3);
1364 M_FLTMOVE(s1, REG_FTMP1);
1365 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1367 M_INTMOVE(REG_RESULT, d);
1368 emit_store_dst(jd, iptr, d);
1371 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1373 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1376 M_ICMP_IMM(0x80000000, d); /* corner cases */
1377 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1378 ((REG_RESULT == d) ? 0 : 3);
1380 M_FLTMOVE(s1, REG_FTMP1);
1381 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1383 M_INTMOVE(REG_RESULT, d);
1384 emit_store_dst(jd, iptr, d);
1387 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1389 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1392 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1393 M_LCMP(REG_ITMP2, d); /* corner cases */
1394 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1395 ((REG_RESULT == d) ? 0 : 3);
1397 M_FLTMOVE(s1, REG_FTMP1);
1398 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1400 M_INTMOVE(REG_RESULT, d);
1401 emit_store_dst(jd, iptr, d);
1404 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1406 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1407 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1409 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1410 M_LCMP(REG_ITMP2, d); /* corner cases */
1411 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1412 ((REG_RESULT == d) ? 0 : 3);
1414 M_FLTMOVE(s1, REG_FTMP1);
1415 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1417 M_INTMOVE(REG_RESULT, d);
1418 emit_store_dst(jd, iptr, d);
1421 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1423 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1424 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1431 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1432 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1438 /* == => 0, < => 1, > => -1 */
1440 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1441 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1444 M_MOV_IMM(1, REG_ITMP1);
1445 M_MOV_IMM(-1, REG_ITMP2);
1446 emit_ucomiss_reg_reg(cd, s1, s2);
1447 M_CMOVULT(REG_ITMP1, d);
1448 M_CMOVUGT(REG_ITMP2, d);
1449 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1450 emit_store_dst(jd, iptr, d);
1453 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1454 /* == => 0, < => 1, > => -1 */
1456 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1460 M_MOV_IMM(1, REG_ITMP1);
1461 M_MOV_IMM(-1, REG_ITMP2);
1462 emit_ucomiss_reg_reg(cd, s1, s2);
1463 M_CMOVULT(REG_ITMP1, d);
1464 M_CMOVUGT(REG_ITMP2, d);
1465 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1466 emit_store_dst(jd, iptr, d);
1469 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1470 /* == => 0, < => 1, > => -1 */
1472 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1473 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1474 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1476 M_MOV_IMM(1, REG_ITMP1);
1477 M_MOV_IMM(-1, REG_ITMP2);
1478 emit_ucomisd_reg_reg(cd, s1, s2);
1479 M_CMOVULT(REG_ITMP1, d);
1480 M_CMOVUGT(REG_ITMP2, d);
1481 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1482 emit_store_dst(jd, iptr, d);
1485 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1486 /* == => 0, < => 1, > => -1 */
1488 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1489 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1490 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1492 M_MOV_IMM(1, REG_ITMP1);
1493 M_MOV_IMM(-1, REG_ITMP2);
1494 emit_ucomisd_reg_reg(cd, s1, s2);
1495 M_CMOVULT(REG_ITMP1, d);
1496 M_CMOVUGT(REG_ITMP2, d);
1497 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1498 emit_store_dst(jd, iptr, d);
1502 /* memory operations **************************************************/
1504 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1508 /* implicit null-pointer check */
1509 M_ILD(d, s1, OFFSET(java_array_t, size));
1510 emit_store_dst(jd, iptr, d);
1513 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1518 /* implicit null-pointer check */
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1521 emit_store_dst(jd, iptr, d);
1524 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1527 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1528 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1529 /* implicit null-pointer check */
1530 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1531 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1532 emit_store_dst(jd, iptr, d);
1535 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1538 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1540 /* implicit null-pointer check */
1541 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1542 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1543 emit_store_dst(jd, iptr, d);
1546 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1551 /* implicit null-pointer check */
1552 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1553 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1554 emit_store_dst(jd, iptr, d);
1557 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1562 /* implicit null-pointer check */
1563 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1564 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1565 emit_store_dst(jd, iptr, d);
1568 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1571 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1572 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1573 /* implicit null-pointer check */
1574 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1575 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1576 emit_store_dst(jd, iptr, d);
1579 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1583 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1584 /* implicit null-pointer check */
1585 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1586 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1587 emit_store_dst(jd, iptr, d);
1590 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1595 /* implicit null-pointer check */
1596 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1597 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1598 emit_store_dst(jd, iptr, d);
1602 case ICMD_BASTORE: /* ..., 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_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1612 case ICMD_CASTORE: /* ..., 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_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1622 case ICMD_SASTORE: /* ..., 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_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1632 case ICMD_IASTORE: /* ..., 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_ITMP3);
1639 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1642 case ICMD_LASTORE: /* ..., 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_ITMP3);
1649 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1652 case ICMD_FASTORE: /* ..., 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_FTMP3);
1659 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1662 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666 /* implicit null-pointer check */
1667 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1668 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1669 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1672 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1675 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1676 /* implicit null-pointer check */
1677 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1678 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1682 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1684 emit_arraystore_check(cd, iptr);
1686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1688 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1689 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1693 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 /* implicit null-pointer check */
1698 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1699 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1702 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1706 /* implicit null-pointer check */
1707 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1708 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1711 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1713 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1714 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1715 /* implicit null-pointer check */
1716 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1717 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1720 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1724 /* implicit null-pointer check */
1725 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1726 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1729 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1733 /* implicit null-pointer check */
1734 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1736 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1737 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1740 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1741 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1745 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1748 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1749 /* implicit null-pointer check */
1750 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1751 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1755 case ICMD_GETSTATIC: /* ... ==> ..., value */
1757 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1758 uf = iptr->sx.s23.s3.uf;
1759 fieldtype = uf->fieldref->parseddesc.fd->type;
1760 disp = dseg_add_unique_address(cd, uf);
1762 /* PROFILE_CYCLE_STOP; */
1764 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1766 /* PROFILE_CYCLE_START; */
1769 fi = iptr->sx.s23.s3.fmiref->p.field;
1770 fieldtype = fi->type;
1771 disp = dseg_add_address(cd, fi->value);
1773 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1776 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1779 PROFILE_CYCLE_START;
1783 /* This approach is much faster than moving the field
1784 address inline into a register. */
1786 M_ALD(REG_ITMP1, RIP, disp);
1788 switch (fieldtype) {
1790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1791 M_ILD(d, REG_ITMP1, 0);
1795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1796 M_LLD(d, REG_ITMP1, 0);
1799 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1800 M_FLD(d, REG_ITMP1, 0);
1803 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1804 M_DLD(d, REG_ITMP1, 0);
1807 emit_store_dst(jd, iptr, d);
1810 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1812 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1813 uf = iptr->sx.s23.s3.uf;
1814 fieldtype = uf->fieldref->parseddesc.fd->type;
1815 disp = dseg_add_unique_address(cd, uf);
1817 /* PROFILE_CYCLE_STOP; */
1819 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1821 /* PROFILE_CYCLE_START; */
1824 fi = iptr->sx.s23.s3.fmiref->p.field;
1825 fieldtype = fi->type;
1826 disp = dseg_add_address(cd, fi->value);
1828 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1831 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1834 PROFILE_CYCLE_START;
1838 /* This approach is much faster than moving the field
1839 address inline into a register. */
1841 M_ALD(REG_ITMP1, RIP, disp);
1843 switch (fieldtype) {
1845 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1846 M_IST(s1, REG_ITMP1, 0);
1850 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1851 M_LST(s1, REG_ITMP1, 0);
1854 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1855 M_FST(s1, REG_ITMP1, 0);
1858 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1859 M_DST(s1, REG_ITMP1, 0);
1864 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1865 /* val = value (in current instruction) */
1866 /* following NOP) */
1868 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1869 uf = iptr->sx.s23.s3.uf;
1870 fieldtype = uf->fieldref->parseddesc.fd->type;
1871 disp = dseg_add_unique_address(cd, uf);
1873 /* PROFILE_CYCLE_STOP; */
1875 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1877 /* PROFILE_CYCLE_START; */
1880 fi = iptr->sx.s23.s3.fmiref->p.field;
1881 fieldtype = fi->type;
1882 disp = dseg_add_address(cd, fi->value);
1884 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1887 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1890 PROFILE_CYCLE_START;
1894 /* This approach is much faster than moving the field
1895 address inline into a register. */
1897 M_ALD(REG_ITMP1, RIP, disp);
1899 switch (fieldtype) {
1902 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1907 if (IS_IMM32(iptr->sx.s23.s2.constval))
1908 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1910 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1911 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1917 case ICMD_GETFIELD: /* ... ==> ..., value */
1919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1921 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1922 uf = iptr->sx.s23.s3.uf;
1923 fieldtype = uf->fieldref->parseddesc.fd->type;
1926 /* PROFILE_CYCLE_STOP; */
1928 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1930 /* PROFILE_CYCLE_START; */
1933 fi = iptr->sx.s23.s3.fmiref->p.field;
1934 fieldtype = fi->type;
1938 /* implicit null-pointer check */
1939 switch (fieldtype) {
1941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1942 M_ILD32(d, s1, disp);
1946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1947 M_LLD32(d, s1, disp);
1950 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1951 M_FLD32(d, s1, disp);
1954 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1955 M_DLD32(d, s1, disp);
1958 emit_store_dst(jd, iptr, d);
1961 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1964 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1966 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1967 uf = iptr->sx.s23.s3.uf;
1968 fieldtype = uf->fieldref->parseddesc.fd->type;
1971 /* PROFILE_CYCLE_STOP; */
1973 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1975 /* PROFILE_CYCLE_START; */
1978 fi = iptr->sx.s23.s3.fmiref->p.field;
1979 fieldtype = fi->type;
1983 /* implicit null-pointer check */
1984 switch (fieldtype) {
1986 M_IST32(s2, s1, disp);
1990 M_LST32(s2, s1, disp);
1993 M_FST32(s2, s1, disp);
1996 M_DST32(s2, s1, disp);
2001 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2002 /* val = value (in current instruction) */
2003 /* following NOP) */
2005 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2007 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2008 uf = iptr->sx.s23.s3.uf;
2009 fieldtype = uf->fieldref->parseddesc.fd->type;
2012 /* PROFILE_CYCLE_STOP; */
2014 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
2016 /* PROFILE_CYCLE_START; */
2019 fi = iptr->sx.s23.s3.fmiref->p.field;
2020 fieldtype = fi->type;
2024 /* implicit null-pointer check */
2025 switch (fieldtype) {
2028 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2033 /* XXX why no check for IS_IMM32? */
2034 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2035 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2041 /* branch operations **************************************************/
2043 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2046 M_INTMOVE(s1, REG_ITMP1_XPTR);
2050 #ifdef ENABLE_VERIFIER
2051 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2052 uc = iptr->sx.s23.s2.uc;
2054 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2056 #endif /* ENABLE_VERIFIER */
2058 M_CALL_IMM(0); /* passing exception pc */
2059 M_POP(REG_ITMP2_XPC);
2061 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2065 case ICMD_GOTO: /* ... ==> ... */
2068 emit_br(cd, iptr->dst.block);
2072 case ICMD_JSR: /* ... ==> ... */
2074 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2078 case ICMD_IFNULL: /* ..., value ==> ... */
2079 case ICMD_IFNONNULL:
2081 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2083 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2086 case ICMD_IFEQ: /* ..., value ==> ... */
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094 M_ICMP_IMM(iptr->sx.val.i, s1);
2095 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2098 case ICMD_IF_LEQ: /* ..., value ==> ... */
2105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2106 if (IS_IMM32(iptr->sx.val.l))
2107 M_LCMP_IMM(iptr->sx.val.l, s1);
2109 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2110 M_LCMP(REG_ITMP2, s1);
2112 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2115 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2116 case ICMD_IF_ICMPNE:
2117 case ICMD_IF_ICMPLT:
2118 case ICMD_IF_ICMPGE:
2119 case ICMD_IF_ICMPGT:
2120 case ICMD_IF_ICMPLE:
2122 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2123 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2125 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2128 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2129 case ICMD_IF_ACMPNE:
2131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2134 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2137 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2138 case ICMD_IF_LCMPNE:
2139 case ICMD_IF_LCMPLT:
2140 case ICMD_IF_LCMPGE:
2141 case ICMD_IF_LCMPGT:
2142 case ICMD_IF_LCMPLE:
2144 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2145 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2147 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2150 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2153 REPLACEMENT_POINT_RETURN(cd, iptr);
2154 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2155 M_INTMOVE(s1, REG_RESULT);
2156 goto nowperformreturn;
2158 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2160 REPLACEMENT_POINT_RETURN(cd, iptr);
2161 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2162 M_INTMOVE(s1, REG_RESULT);
2164 #ifdef ENABLE_VERIFIER
2165 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2166 uc = iptr->sx.s23.s2.uc;
2170 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2172 PROFILE_CYCLE_START;
2174 #endif /* ENABLE_VERIFIER */
2175 goto nowperformreturn;
2177 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2180 REPLACEMENT_POINT_RETURN(cd, iptr);
2181 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2182 M_FLTMOVE(s1, REG_FRESULT);
2183 goto nowperformreturn;
2185 case ICMD_RETURN: /* ... ==> ... */
2187 REPLACEMENT_POINT_RETURN(cd, iptr);
2193 p = cd->stackframesize;
2195 #if !defined(NDEBUG)
2196 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2197 emit_verbosecall_exit(jd);
2198 #endif /* !defined(NDEBUG) */
2200 #if defined(ENABLE_THREADS)
2201 if (checksync && code_is_synchronized(code)) {
2202 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2204 /* we need to save the proper return value */
2205 switch (iptr->opc) {
2209 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2213 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2217 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2220 /* and now restore the proper return value */
2221 switch (iptr->opc) {
2225 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2229 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2235 /* restore saved registers */
2237 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2238 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2240 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2241 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2244 /* deallocate stack */
2246 if (cd->stackframesize)
2247 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2249 /* generate method profiling code */
2258 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2261 branch_target_t *table;
2263 table = iptr->dst.table;
2265 l = iptr->sx.s23.s2.tablelow;
2266 i = iptr->sx.s23.s3.tablehigh;
2268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 M_INTMOVE(s1, REG_ITMP1);
2272 M_ISUB_IMM(l, REG_ITMP1);
2274 /* number of targets */
2279 M_ICMP_IMM(i - 1, REG_ITMP1);
2280 emit_bugt(cd, table[0].block);
2282 /* build jump table top down and use address of lowest entry */
2287 dseg_add_target(cd, table->block);
2291 /* length of dataseg after last dseg_add_target is used
2294 M_MOV_IMM(0, REG_ITMP2);
2296 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2302 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2305 lookup_target_t *lookup;
2307 lookup = iptr->dst.lookup;
2309 i = iptr->sx.s23.s2.lookupcount;
2311 MCODECHECK(8 + ((7 + 6) * i) + 5);
2312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2315 M_ICMP_IMM(lookup->value, s1);
2316 emit_beq(cd, lookup->target.block);
2320 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2326 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2328 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2330 bte = iptr->sx.s23.s3.bte;
2334 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2336 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2337 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2338 case ICMD_INVOKEINTERFACE:
2340 REPLACEMENT_POINT_INVOKE(cd, iptr);
2342 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2344 um = iptr->sx.s23.s3.um;
2345 md = um->methodref->parseddesc.md;
2348 lm = iptr->sx.s23.s3.fmiref->p.method;
2350 md = lm->parseddesc;
2354 s3 = md->paramcount;
2356 MCODECHECK((20 * s3) + 128);
2358 /* copy arguments to registers or stack location */
2360 for (s3 = s3 - 1; s3 >= 0; s3--) {
2361 var = VAR(iptr->sx.s23.s2.args[s3]);
2362 d = md->params[s3].regoff;
2364 /* already preallocated (ARGVAR)? */
2366 if (var->flags & PREALLOC)
2369 if (IS_INT_LNG_TYPE(var->type)) {
2370 if (!md->params[s3].inmemory) {
2371 s1 = emit_load(jd, iptr, var, d);
2375 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2376 M_LST(s1, REG_SP, d);
2380 if (!md->params[s3].inmemory) {
2381 s1 = emit_load(jd, iptr, var, d);
2385 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2387 if (IS_2_WORD_TYPE(var->type))
2388 M_DST(s1, REG_SP, d);
2390 M_FST(s1, REG_SP, d);
2395 /* generate method profiling code */
2399 switch (iptr->opc) {
2401 if (bte->stub == NULL) {
2402 M_MOV_IMM(bte->fp, REG_ITMP1);
2405 M_MOV_IMM(bte->stub, REG_ITMP1);
2410 case ICMD_INVOKESPECIAL:
2411 emit_nullpointer_check(cd, iptr, REG_A0);
2414 case ICMD_INVOKESTATIC:
2416 disp = dseg_add_unique_address(cd, um);
2418 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2422 disp = dseg_add_functionptr(cd, lm->stubroutine);
2425 M_ALD(REG_ITMP2, RIP, disp);
2429 case ICMD_INVOKEVIRTUAL:
2431 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2436 s1 = OFFSET(vftbl_t, table[0]) +
2437 sizeof(methodptr) * lm->vftblindex;
2440 /* implicit null-pointer check */
2441 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2442 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2446 case ICMD_INVOKEINTERFACE:
2448 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2454 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2455 sizeof(methodptr) * lm->class->index;
2457 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2460 /* implicit null-pointer check */
2461 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2462 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2463 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2468 /* generate method profiling code */
2470 PROFILE_CYCLE_START;
2472 /* store size of call code in replacement point */
2474 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2475 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2477 /* store return value */
2479 switch (md->returntype.type) {
2483 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2484 M_INTMOVE(REG_RESULT, s1);
2485 emit_store_dst(jd, iptr, s1);
2489 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2490 M_FLTMOVE(REG_FRESULT, s1);
2491 emit_store_dst(jd, iptr, s1);
2500 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2502 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2503 /* object type cast-check */
2508 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2513 super = iptr->sx.s23.s3.c.cls;
2514 superindex = super->index;
2517 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2518 CODEGEN_CRITICAL_SECTION_NEW;
2520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2522 /* if class is not resolved, check which code to call */
2524 if (super == NULL) {
2526 emit_label_beq(cd, BRANCH_LABEL_1);
2528 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2529 iptr->sx.s23.s3.c.ref, 0);
2531 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2532 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2533 emit_label_beq(cd, BRANCH_LABEL_2);
2536 /* interface checkcast code */
2538 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2539 if (super != NULL) {
2541 emit_label_beq(cd, BRANCH_LABEL_3);
2544 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2546 if (super == NULL) {
2547 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2548 iptr->sx.s23.s3.c.ref,
2553 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2554 M_ICMP_IMM32(superindex, REG_ITMP3);
2555 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2557 M_ALD32(REG_ITMP3, REG_ITMP2,
2558 OFFSET(vftbl_t, interfacetable[0]) -
2559 superindex * sizeof(methodptr*));
2561 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2564 emit_label_br(cd, BRANCH_LABEL_4);
2566 emit_label(cd, BRANCH_LABEL_3);
2569 /* class checkcast code */
2571 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2572 if (super == NULL) {
2573 emit_label(cd, BRANCH_LABEL_2);
2575 cr = iptr->sx.s23.s3.c.ref;
2576 disp = dseg_add_unique_address(cd, cr);
2578 patcher_add_patch_ref(jd,
2579 PATCHER_resolve_classref_to_vftbl,
2584 emit_label_beq(cd, BRANCH_LABEL_5);
2586 disp = dseg_add_address(cd, super->vftbl);
2589 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2590 M_ALD(REG_ITMP3, RIP, disp);
2592 CODEGEN_CRITICAL_SECTION_START;
2594 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2596 /* if (s1 != REG_ITMP1) { */
2597 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2598 /* OFFSET(vftbl_t, baseval), */
2600 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2601 /* OFFSET(vftbl_t, diffval), */
2603 /* #if defined(ENABLE_THREADS) */
2604 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2606 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2610 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2611 M_ISUB(REG_ITMP3, REG_ITMP2);
2612 M_ALD(REG_ITMP3, RIP, disp);
2613 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2616 CODEGEN_CRITICAL_SECTION_END;
2618 M_ICMP(REG_ITMP3, REG_ITMP2);
2619 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2622 emit_label(cd, BRANCH_LABEL_5);
2625 if (super == NULL) {
2626 emit_label(cd, BRANCH_LABEL_1);
2627 emit_label(cd, BRANCH_LABEL_4);
2630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2633 /* array type cast-check */
2635 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2636 M_INTMOVE(s1, REG_A0);
2638 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2639 cr = iptr->sx.s23.s3.c.ref;
2640 disp = dseg_add_unique_address(cd, cr);
2642 patcher_add_patch_ref(jd,
2643 PATCHER_resolve_classref_to_classinfo,
2647 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2650 M_ALD(REG_A1, RIP, disp);
2651 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2654 /* s1 may have been destroyed over the function call */
2655 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2657 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2663 emit_store_dst(jd, iptr, d);
2666 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2672 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2677 super = iptr->sx.s23.s3.c.cls;
2678 superindex = super->index;
2681 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2682 CODEGEN_CRITICAL_SECTION_NEW;
2684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2688 M_INTMOVE(s1, REG_ITMP1);
2694 /* if class is not resolved, check which code to call */
2696 if (super == NULL) {
2698 emit_label_beq(cd, BRANCH_LABEL_1);
2700 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2701 iptr->sx.s23.s3.c.ref, 0);
2703 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2704 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2705 emit_label_beq(cd, BRANCH_LABEL_2);
2708 /* interface instanceof code */
2710 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2711 if (super != NULL) {
2713 emit_label_beq(cd, BRANCH_LABEL_3);
2716 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2718 if (super == NULL) {
2719 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2720 iptr->sx.s23.s3.c.ref, 0);
2724 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2725 M_ICMP_IMM32(superindex, REG_ITMP3);
2727 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2730 M_ALD32(REG_ITMP1, REG_ITMP1,
2731 OFFSET(vftbl_t, interfacetable[0]) -
2732 superindex * sizeof(methodptr*));
2737 emit_label_br(cd, BRANCH_LABEL_4);
2739 emit_label(cd, BRANCH_LABEL_3);
2742 /* class instanceof code */
2744 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2745 if (super == NULL) {
2746 emit_label(cd, BRANCH_LABEL_2);
2748 cr = iptr->sx.s23.s3.c.ref;
2749 disp = dseg_add_unique_address(cd, cr);
2751 patcher_add_patch_ref(jd,
2752 PATCHER_resolve_classref_to_vftbl,
2757 emit_label_beq(cd, BRANCH_LABEL_5);
2759 disp = dseg_add_address(cd, super->vftbl);
2762 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2763 M_ALD(REG_ITMP2, RIP, disp);
2765 CODEGEN_CRITICAL_SECTION_START;
2767 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2768 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2769 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2771 CODEGEN_CRITICAL_SECTION_END;
2773 M_ISUB(REG_ITMP2, REG_ITMP1);
2774 M_CLR(d); /* may be REG_ITMP2 */
2775 M_ICMP(REG_ITMP3, REG_ITMP1);
2779 emit_label(cd, BRANCH_LABEL_5);
2782 if (super == NULL) {
2783 emit_label(cd, BRANCH_LABEL_1);
2784 emit_label(cd, BRANCH_LABEL_4);
2787 emit_store_dst(jd, iptr, d);
2791 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2793 /* check for negative sizes and copy sizes to stack if necessary */
2795 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2797 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2799 /* copy SAVEDVAR sizes to stack */
2800 var = VAR(iptr->sx.s23.s2.args[s1]);
2802 /* Already Preallocated? */
2803 if (!(var->flags & PREALLOC)) {
2804 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2805 M_LST(s2, REG_SP, s1 * 8);
2809 /* a0 = dimension count */
2811 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2813 /* is a patcher function set? */
2815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2816 cr = iptr->sx.s23.s3.c.ref;
2817 disp = dseg_add_unique_address(cd, cr);
2819 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2823 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2826 /* a1 = classinfo */
2828 M_ALD(REG_A1, RIP, disp);
2830 /* a2 = pointer to dimensions = stack pointer */
2832 M_MOV(REG_SP, REG_A2);
2834 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2837 /* check for exception before result assignment */
2839 emit_exception_check(cd, iptr);
2841 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2842 M_INTMOVE(REG_RESULT, s1);
2843 emit_store_dst(jd, iptr, s1);
2847 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2852 } /* for instruction */
2854 MCODECHECK(512); /* XXX require a lower number? */
2856 /* At the end of a basic block we may have to append some nops,
2857 because the patcher stub calling code might be longer than the
2858 actual instruction. So codepatching does not change the
2859 following block unintentionally. */
2861 if (cd->mcodeptr < cd->lastmcodeptr) {
2862 while (cd->mcodeptr < cd->lastmcodeptr) {
2867 } /* if (bptr -> flags >= BBREACHED) */
2868 } /* for basic block */
2870 dseg_createlinenumbertable(cd);
2872 /* Generate patcher traps. */
2874 emit_patcher_traps(jd);
2876 /* everything's ok */
2882 /* codegen_emit_stub_native ****************************************************
2884 Emits a stub routine which calls a native method.
2886 *******************************************************************************/
2888 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2902 /* Get required compiler data. */
2908 /* initialize variables */
2912 /* calculate stack frame size */
2914 cd->stackframesize =
2915 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2916 sizeof(localref_table) / SIZEOF_VOID_P +
2918 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2921 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2923 /* create method header */
2925 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2926 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2927 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2928 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2929 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2930 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2931 (void) dseg_addlinenumbertablesize(cd);
2932 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2934 #if defined(ENABLE_PROFILING)
2935 /* generate native method profiling code */
2937 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2938 /* count frequency */
2940 M_MOV_IMM(code, REG_ITMP3);
2941 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2945 /* generate stub code */
2947 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2949 #if defined(ENABLE_GC_CACAO)
2950 /* Save callee saved integer registers in stackframeinfo (GC may
2951 need to recover them during a collection). */
2953 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2954 OFFSET(stackframeinfo_t, intregs);
2956 for (i = 0; i < INT_SAV_CNT; i++)
2957 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2960 /* save integer and float argument registers */
2962 for (i = 0; i < md->paramcount; i++) {
2963 if (!md->params[i].inmemory) {
2964 s1 = md->params[i].regoff;
2966 switch (md->paramtypes[i].type) {
2970 M_LST(s1, REG_SP, i * 8);
2974 M_DST(s1, REG_SP, i * 8);
2980 /* create dynamic stack info */
2982 M_MOV(REG_SP, REG_A0);
2983 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2984 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2987 /* remember class argument */
2989 if (m->flags & ACC_STATIC)
2990 M_MOV(REG_RESULT, REG_ITMP2);
2992 /* restore integer and float argument registers */
2994 for (i = 0; i < md->paramcount; i++) {
2995 if (!md->params[i].inmemory) {
2996 s1 = md->params[i].regoff;
2998 switch (md->paramtypes[i].type) {
3002 M_LLD(s1, REG_SP, i * 8);
3006 M_DLD(s1, REG_SP, i * 8);
3012 /* Copy or spill arguments to new locations. */
3014 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3015 s2 = nmd->params[j].regoff;
3017 switch (md->paramtypes[i].type) {
3021 if (!md->params[i].inmemory) {
3022 s1 = md->params[i].regoff;
3024 if (!nmd->params[j].inmemory)
3027 M_LST(s1, REG_SP, s2);
3030 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3031 M_LLD(REG_ITMP1, REG_SP, s1);
3032 M_LST(REG_ITMP1, REG_SP, s2);
3036 /* We only copy spilled float arguments, as the float
3037 argument registers keep unchanged. */
3039 if (md->params[i].inmemory) {
3040 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3042 M_FLD(REG_FTMP1, REG_SP, s1);
3043 M_FST(REG_FTMP1, REG_SP, s2);
3047 if (md->params[i].inmemory) {
3048 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3049 M_DLD(REG_FTMP1, REG_SP, s1);
3050 M_DST(REG_FTMP1, REG_SP, s2);
3056 /* Handle native Java methods. */
3058 if (m->flags & ACC_NATIVE) {
3059 /* put class into second argument register */
3061 if (m->flags & ACC_STATIC)
3062 M_MOV(REG_ITMP2, REG_A1);
3064 /* put env into first argument register */
3066 M_MOV_IMM(_Jv_env, REG_A0);
3069 /* Call the native function. */
3071 disp = dseg_add_functionptr(cd, f);
3072 M_ALD(REG_ITMP1, RIP, disp);
3075 /* save return value */
3077 switch (md->returntype.type) {
3081 M_LST(REG_RESULT, REG_SP, 0 * 8);
3085 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3091 /* remove native stackframe info */
3093 M_MOV(REG_SP, REG_A0);
3094 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3095 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3097 M_MOV(REG_RESULT, REG_ITMP3);
3099 /* restore return value */
3101 switch (md->returntype.type) {
3105 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3109 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3115 #if defined(ENABLE_GC_CACAO)
3116 /* Restore callee saved integer registers from stackframeinfo (GC
3117 might have modified them during a collection). */
3119 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3120 OFFSET(stackframeinfo_t, intregs);
3122 for (i = 0; i < INT_SAV_CNT; i++)
3123 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3126 /* remove stackframe */
3128 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3130 /* test for exception */
3136 /* handle exception */
3138 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3139 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3140 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3142 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3148 * These are local overrides for various environment variables in Emacs.
3149 * Please do not remove this and leave it at the end of the file, where
3150 * Emacs will automagically detect them.
3151 * ---------------------------------------------------------------------
3154 * indent-tabs-mode: t
3158 * vim:noexpandtab:sw=4:ts=4: