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
37 #include "vm/jit/x86_64/arch.h"
38 #include "vm/jit/x86_64/codegen.h"
39 #include "vm/jit/x86_64/emit.h"
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/localref.h"
45 #include "native/native.h"
47 #include "threads/lock-common.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit/abi.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen-common.h"
58 #include "vm/jit/dseg.h"
59 #include "vm/jit/emit-common.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/methodheader.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.h"
66 #include "vm/jit/stacktrace.h"
68 #if defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
72 #include "vmcore/loader.h"
73 #include "vmcore/options.h"
74 #include "vmcore/statistics.h"
77 /* codegen_emit ****************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen_emit(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
96 constant_classref *cr;
98 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
99 unresolved_method *um;
100 builtintable_entry *bte;
103 unresolved_field *uf;
107 /* get required compiler data */
114 /* prevent compiler warnings */
127 /* space to save used callee saved registers */
129 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
130 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
132 cd->stackframesize = rd->memuse + savedregs_num;
134 #if defined(ENABLE_THREADS)
135 /* space to save argument of monitor_enter */
137 if (checksync && (m->flags & ACC_SYNCHRONIZED))
138 cd->stackframesize++;
141 /* Keep stack of non-leaf functions 16-byte aligned for calls into
142 native code e.g. libc or jni (alignment problems with
145 if (!jd->isleafmethod || opt_verbosecall)
146 cd->stackframesize |= 0x1;
148 /* create method header */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
166 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
167 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
168 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 (void) dseg_addlinenumbertablesize(cd);
172 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_add_target(cd, ex->start);
178 dseg_add_target(cd, ex->end);
179 dseg_add_target(cd, ex->handler);
180 (void) dseg_add_unique_address(cd, ex->catchtype.any);
183 #if defined(ENABLE_PROFILING)
184 /* generate method profiling code */
186 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
187 /* count frequency */
189 M_MOV_IMM(code, REG_ITMP3);
190 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
196 /* create stack frame (if necessary) */
198 if (cd->stackframesize)
199 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
201 /* save used callee saved registers */
203 p = cd->stackframesize;
204 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
205 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
207 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
208 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
211 /* take arguments out of register or stack frame */
215 for (p = 0, l = 0; p < md->paramcount; p++) {
216 t = md->paramtypes[p].type;
218 varindex = jd->local_map[l * 5 + t];
221 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
224 if (varindex == UNUSED)
229 s1 = md->params[p].regoff;
231 if (IS_INT_LNG_TYPE(t)) { /* integer args */
232 if (!md->params[p].inmemory) { /* register arguments */
233 if (!IS_INMEMORY(var->flags))
234 M_INTMOVE(s1, var->vv.regoff);
236 M_LST(s1, REG_SP, var->vv.regoff);
238 else { /* stack arguments */
239 if (!IS_INMEMORY(var->flags))
240 /* + 8 for return address */
241 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
243 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
246 else { /* floating args */
247 if (!md->params[p].inmemory) { /* register arguments */
248 if (!IS_INMEMORY(var->flags))
249 M_FLTMOVE(s1, var->vv.regoff);
251 M_DST(s1, REG_SP, var->vv.regoff);
253 else { /* stack arguments */
254 if (!IS_INMEMORY(var->flags))
255 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
257 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
262 /* save monitorenter argument */
264 #if defined(ENABLE_THREADS)
265 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
266 /* stack offset for monitor argument */
270 if (opt_verbosecall) {
271 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
273 for (p = 0; p < INT_ARG_CNT; p++)
274 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
276 for (p = 0; p < FLT_ARG_CNT; p++)
277 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
279 s1 += INT_ARG_CNT + FLT_ARG_CNT;
282 /* decide which monitor enter function to call */
284 if (m->flags & ACC_STATIC) {
285 M_MOV_IMM(&m->class->object.header, REG_A0);
290 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
293 M_AST(REG_A0, REG_SP, s1 * 8);
294 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
297 if (opt_verbosecall) {
298 for (p = 0; p < INT_ARG_CNT; p++)
299 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
301 for (p = 0; p < FLT_ARG_CNT; p++)
302 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
304 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
310 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
311 emit_verbosecall_enter(jd);
312 #endif /* !defined(NDEBUG) */
316 /* end of header generation */
318 /* create replacement points */
320 REPLACEMENT_POINTS_INIT(cd, jd);
322 /* walk through all basic blocks */
324 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
326 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
328 if (bptr->flags >= BBREACHED) {
330 /* branch resolving */
332 codegen_resolve_branchrefs(cd, bptr);
334 /* handle replacement points */
336 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
338 /* copy interface registers to their destination */
343 #if defined(ENABLE_PROFILING)
344 /* generate basicblock profiling code */
346 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
347 /* count frequency */
349 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
350 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
352 /* if this is an exception handler, start profiling again */
354 if (bptr->type == BBTYPE_EXH)
359 #if defined(ENABLE_LSRA)
363 src = bptr->invars[len];
364 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
365 if (bptr->type == BBTYPE_EXH) {
366 /* d = reg_of_var(rd, src, REG_ITMP1); */
367 if (!IS_INMEMORY(src->flags))
371 M_INTMOVE(REG_ITMP1, d);
372 emit_store(jd, NULL, src, d);
382 var = VAR(bptr->invars[len]);
383 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
384 if (bptr->type == BBTYPE_EXH) {
385 d = codegen_reg_of_var(0, var, REG_ITMP1);
386 M_INTMOVE(REG_ITMP1, d);
387 emit_store(jd, NULL, var, d);
391 assert((var->flags & INOUT));
394 #if defined(ENABLE_LSRA)
397 /* walk through all instructions */
402 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
403 if (iptr->line != currentline) {
404 dseg_addlinenumber(cd, iptr->line);
405 currentline = iptr->line;
408 MCODECHECK(1024); /* 1KB should be enough */
411 case ICMD_NOP: /* ... ==> ... */
412 case ICMD_POP: /* ..., value ==> ... */
413 case ICMD_POP2: /* ..., value, value ==> ... */
416 case ICMD_INLINE_START:
418 REPLACEMENT_POINT_INLINE_START(cd, iptr);
421 case ICMD_INLINE_BODY:
423 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
424 dseg_addlinenumber_inline_start(cd, iptr);
425 dseg_addlinenumber(cd, iptr->line);
428 case ICMD_INLINE_END:
430 dseg_addlinenumber_inline_end(cd, iptr);
431 dseg_addlinenumber(cd, iptr->line);
434 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
437 emit_nullpointer_check(cd, iptr, s1);
440 /* constant operations ************************************************/
442 case ICMD_ICONST: /* ... ==> ..., constant */
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
445 ICONST(d, iptr->sx.val.i);
446 emit_store_dst(jd, iptr, d);
449 case ICMD_LCONST: /* ... ==> ..., constant */
451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
452 LCONST(d, iptr->sx.val.l);
453 emit_store_dst(jd, iptr, d);
456 case ICMD_FCONST: /* ... ==> ..., constant */
458 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
459 disp = dseg_add_float(cd, iptr->sx.val.f);
460 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
461 emit_store_dst(jd, iptr, d);
464 case ICMD_DCONST: /* ... ==> ..., constant */
466 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
467 disp = dseg_add_double(cd, iptr->sx.val.d);
468 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
469 emit_store_dst(jd, iptr, d);
472 case ICMD_ACONST: /* ... ==> ..., constant */
474 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
476 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
477 cr = iptr->sx.val.c.ref;
479 /* PROFILE_CYCLE_STOP; */
481 codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
483 /* PROFILE_CYCLE_START; */
488 if (iptr->sx.val.anyptr == 0)
491 M_MOV_IMM(iptr->sx.val.anyptr, d);
493 emit_store_dst(jd, iptr, d);
497 /* load/store/copy/move operations ************************************/
499 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
500 case ICMD_ALOAD: /* s1 = local variable */
504 case ICMD_ISTORE: /* ..., value ==> ... */
515 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
519 /* integer operations *************************************************/
521 case ICMD_INEG: /* ..., value ==> ..., - value */
523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
527 emit_store_dst(jd, iptr, d);
530 case ICMD_LNEG: /* ..., value ==> ..., - value */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
536 emit_store_dst(jd, iptr, d);
539 case ICMD_I2L: /* ..., value ==> ..., value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
544 emit_store_dst(jd, iptr, d);
547 case ICMD_L2I: /* ..., value ==> ..., value */
549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
552 emit_store_dst(jd, iptr, d);
555 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
560 emit_store_dst(jd, iptr, d);
563 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
568 emit_store_dst(jd, iptr, d);
571 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
576 emit_store_dst(jd, iptr, d);
580 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
583 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
591 emit_store_dst(jd, iptr, d);
595 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
596 /* sx.val.i = constant */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
601 /* Using inc and dec is not faster than add (tested with
605 M_IADD_IMM(iptr->sx.val.i, d);
606 emit_store_dst(jd, iptr, d);
609 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
613 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 emit_store_dst(jd, iptr, d);
623 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
624 /* sx.val.l = constant */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
629 if (IS_IMM32(iptr->sx.val.l))
630 M_LADD_IMM(iptr->sx.val.l, d);
632 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
633 M_LADD(REG_ITMP2, d);
635 emit_store_dst(jd, iptr, d);
638 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
641 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 M_INTMOVE(s1, REG_ITMP1);
645 M_ISUB(s2, REG_ITMP1);
646 M_INTMOVE(REG_ITMP1, d);
651 emit_store_dst(jd, iptr, d);
654 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
655 /* sx.val.i = constant */
657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
660 M_ISUB_IMM(iptr->sx.val.i, d);
661 emit_store_dst(jd, iptr, d);
664 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
667 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
670 M_INTMOVE(s1, REG_ITMP1);
671 M_LSUB(s2, REG_ITMP1);
672 M_INTMOVE(REG_ITMP1, d);
677 emit_store_dst(jd, iptr, d);
680 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
681 /* sx.val.l = constant */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
686 if (IS_IMM32(iptr->sx.val.l))
687 M_LSUB_IMM(iptr->sx.val.l, d);
689 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
690 M_LSUB(REG_ITMP2, d);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
710 /* sx.val.i = constant */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
714 if (iptr->sx.val.i == 2) {
718 M_IMUL_IMM(s1, iptr->sx.val.i, d);
719 emit_store_dst(jd, iptr, d);
722 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
733 emit_store_dst(jd, iptr, d);
736 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
737 /* sx.val.l = constant */
739 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
741 if (IS_IMM32(iptr->sx.val.l))
742 M_LMUL_IMM(s1, iptr->sx.val.l, d);
744 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
746 M_LMUL(REG_ITMP2, d);
748 emit_store_dst(jd, iptr, d);
751 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
753 s1 = emit_load_s1(jd, iptr, RAX);
754 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
755 d = codegen_reg_of_dst(jd, iptr, RAX);
758 M_INTMOVE(s2, REG_ITMP3);
759 emit_arithmetic_check(cd, iptr, REG_ITMP3);
761 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
763 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
765 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
766 M_BEQ(1 + 3); /* 6 bytes */
768 emit_cltd(cd); /* 1 byte */
769 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
772 emit_store_dst(jd, iptr, d);
773 dst = VAROP(iptr->dst);
774 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
775 M_MOV(REG_ITMP2, RDX); /* restore RDX */
778 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
780 s1 = emit_load_s1(jd, iptr, RAX);
781 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
782 d = codegen_reg_of_dst(jd, iptr, RDX);
785 M_INTMOVE(s2, REG_ITMP3);
786 emit_arithmetic_check(cd, iptr, REG_ITMP3);
788 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
790 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
792 M_CLR(RDX); /* 3 bytes */
793 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
794 M_BEQ(1 + 3); /* 6 bytes */
796 emit_cltd(cd); /* 1 byte */
797 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
800 emit_store_dst(jd, iptr, d);
801 dst = VAROP(iptr->dst);
802 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
803 M_MOV(REG_ITMP2, RDX); /* restore RDX */
806 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
807 /* sx.val.i = constant */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
811 M_INTMOVE(s1, REG_ITMP1);
812 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
813 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
814 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
815 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
816 emit_mov_reg_reg(cd, REG_ITMP1, d);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
821 /* sx.val.i = constant */
823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
825 M_INTMOVE(s1, REG_ITMP1);
826 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
827 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
828 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
829 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
830 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
831 emit_mov_reg_reg(cd, REG_ITMP1, d);
832 emit_store_dst(jd, iptr, d);
836 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
838 s1 = emit_load_s1(jd, iptr, RAX);
839 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
840 d = codegen_reg_of_dst(jd, iptr, RAX);
843 M_INTMOVE(s2, REG_ITMP3);
844 emit_arithmetic_check(cd, iptr, REG_ITMP3);
846 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
848 /* check as described in jvm spec */
849 disp = dseg_add_s8(cd, 0x8000000000000000LL);
850 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
852 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
853 M_BEQ(2 + 3); /* 6 bytes */
855 emit_cqto(cd); /* 2 bytes */
856 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
859 emit_store_dst(jd, iptr, d);
860 dst = VAROP(iptr->dst);
861 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
862 M_MOV(REG_ITMP2, RDX); /* restore RDX */
865 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
867 s1 = emit_load_s1(jd, iptr, RAX);
868 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
869 d = codegen_reg_of_dst(jd, iptr, RDX);
872 M_INTMOVE(s2, REG_ITMP3);
873 emit_arithmetic_check(cd, iptr, REG_ITMP3);
875 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
877 /* check as described in jvm spec */
878 disp = dseg_add_s8(cd, 0x8000000000000000LL);
879 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
881 M_LXOR(RDX, RDX); /* 3 bytes */
882 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
883 M_BEQ(2 + 3); /* 6 bytes */
885 emit_cqto(cd); /* 2 bytes */
886 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
889 emit_store_dst(jd, iptr, d);
890 dst = VAROP(iptr->dst);
891 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
892 M_MOV(REG_ITMP2, RDX); /* restore RDX */
895 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
896 /* sx.val.i = constant */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
900 M_INTMOVE(s1, REG_ITMP1);
901 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
902 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
903 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
904 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
905 emit_mov_reg_reg(cd, REG_ITMP1, d);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
910 /* sx.val.l = constant */
912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
914 M_INTMOVE(s1, REG_ITMP1);
915 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
916 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
917 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
918 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
919 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
920 emit_mov_reg_reg(cd, REG_ITMP1, d);
921 emit_store_dst(jd, iptr, d);
924 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
926 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
927 emit_ishift(jd, SHIFT_SHL, iptr);
930 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
931 /* sx.val.i = constant */
933 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
934 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
936 M_ISLL_IMM(iptr->sx.val.i, d);
937 emit_store_dst(jd, iptr, d);
940 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
942 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
943 emit_ishift(jd, SHIFT_SAR, iptr);
946 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
947 /* sx.val.i = constant */
949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
952 M_ISRA_IMM(iptr->sx.val.i, d);
953 emit_store_dst(jd, iptr, d);
956 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
958 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
959 emit_ishift(jd, SHIFT_SHR, iptr);
962 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
963 /* sx.val.i = constant */
965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
966 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
968 M_ISRL_IMM(iptr->sx.val.i, d);
969 emit_store_dst(jd, iptr, d);
972 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
974 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
975 emit_lshift(jd, SHIFT_SHL, iptr);
978 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
979 /* sx.val.i = constant */
981 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
982 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
984 M_LSLL_IMM(iptr->sx.val.i, d);
985 emit_store_dst(jd, iptr, d);
988 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
990 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
991 emit_lshift(jd, SHIFT_SAR, iptr);
994 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
995 /* sx.val.i = constant */
997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
998 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1000 M_LSRA_IMM(iptr->sx.val.i, d);
1001 emit_store_dst(jd, iptr, d);
1004 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1006 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1007 emit_lshift(jd, SHIFT_SHR, iptr);
1010 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1011 /* sx.val.l = constant */
1013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1014 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 M_LSRL_IMM(iptr->sx.val.i, d);
1017 emit_store_dst(jd, iptr, d);
1020 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1024 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1031 emit_store_dst(jd, iptr, d);
1034 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1035 /* sx.val.i = constant */
1037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1038 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1040 M_IAND_IMM(iptr->sx.val.i, d);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1047 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1048 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1055 emit_store_dst(jd, iptr, d);
1058 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1059 /* sx.val.l = constant */
1061 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1064 if (IS_IMM32(iptr->sx.val.l))
1065 M_LAND_IMM(iptr->sx.val.l, d);
1067 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1068 M_LAND(REG_ITMP2, d);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1088 /* sx.val.i = constant */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1093 M_IOR_IMM(iptr->sx.val.i, d);
1094 emit_store_dst(jd, iptr, d);
1097 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1100 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1112 /* sx.val.l = constant */
1114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1115 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1117 if (IS_IMM32(iptr->sx.val.l))
1118 M_LOR_IMM(iptr->sx.val.l, d);
1120 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1121 M_LOR(REG_ITMP2, d);
1123 emit_store_dst(jd, iptr, d);
1126 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1128 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1129 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1137 emit_store_dst(jd, iptr, d);
1140 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1141 /* sx.val.i = constant */
1143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1144 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1146 M_IXOR_IMM(iptr->sx.val.i, d);
1147 emit_store_dst(jd, iptr, d);
1150 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1152 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1153 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1165 /* sx.val.l = constant */
1167 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1168 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1170 if (IS_IMM32(iptr->sx.val.l))
1171 M_LXOR_IMM(iptr->sx.val.l, d);
1173 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1174 M_LXOR(REG_ITMP2, d);
1176 emit_store_dst(jd, iptr, d);
1180 /* floating operations ************************************************/
1182 case ICMD_FNEG: /* ..., value ==> ..., - value */
1184 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1185 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1186 disp = dseg_add_s4(cd, 0x80000000);
1188 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1189 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_DNEG: /* ..., value ==> ..., - value */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1197 disp = dseg_add_s8(cd, 0x8000000000000000);
1199 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1200 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1201 emit_store_dst(jd, iptr, d);
1204 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1207 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1208 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1215 emit_store_dst(jd, iptr, d);
1218 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1220 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1221 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1222 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1229 emit_store_dst(jd, iptr, d);
1232 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1234 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1235 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1236 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1238 M_FLTMOVE(s2, REG_FTMP2);
1243 emit_store_dst(jd, iptr, d);
1246 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1248 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1249 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1250 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1252 M_FLTMOVE(s2, REG_FTMP2);
1257 emit_store_dst(jd, iptr, d);
1260 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1262 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1263 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1264 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1271 emit_store_dst(jd, iptr, d);
1274 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1276 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1277 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1278 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1285 emit_store_dst(jd, iptr, d);
1288 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1290 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1291 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1292 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1294 M_FLTMOVE(s2, REG_FTMP2);
1299 emit_store_dst(jd, iptr, d);
1302 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1304 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1305 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1306 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1308 M_FLTMOVE(s2, REG_FTMP2);
1313 emit_store_dst(jd, iptr, d);
1316 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1319 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1321 emit_store_dst(jd, iptr, d);
1324 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1326 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1327 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1329 emit_store_dst(jd, iptr, d);
1332 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1335 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1337 emit_store_dst(jd, iptr, d);
1340 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1343 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1345 emit_store_dst(jd, iptr, d);
1348 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1350 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1351 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1353 M_ICMP_IMM(0x80000000, d); /* corner cases */
1354 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1355 ((REG_RESULT == d) ? 0 : 3);
1357 M_FLTMOVE(s1, REG_FTMP1);
1358 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1360 M_INTMOVE(REG_RESULT, d);
1361 emit_store_dst(jd, iptr, d);
1364 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1366 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1369 M_ICMP_IMM(0x80000000, d); /* corner cases */
1370 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1371 ((REG_RESULT == d) ? 0 : 3);
1373 M_FLTMOVE(s1, REG_FTMP1);
1374 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1376 M_INTMOVE(REG_RESULT, d);
1377 emit_store_dst(jd, iptr, d);
1380 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1382 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1383 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1385 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1386 M_LCMP(REG_ITMP2, d); /* corner cases */
1387 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1388 ((REG_RESULT == d) ? 0 : 3);
1390 M_FLTMOVE(s1, REG_FTMP1);
1391 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1393 M_INTMOVE(REG_RESULT, d);
1394 emit_store_dst(jd, iptr, d);
1397 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1399 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1402 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1403 M_LCMP(REG_ITMP2, d); /* corner cases */
1404 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1405 ((REG_RESULT == d) ? 0 : 3);
1407 M_FLTMOVE(s1, REG_FTMP1);
1408 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1410 M_INTMOVE(REG_RESULT, d);
1411 emit_store_dst(jd, iptr, d);
1414 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1416 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1417 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1419 emit_store_dst(jd, iptr, d);
1422 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1424 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1425 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1427 emit_store_dst(jd, iptr, d);
1430 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1431 /* == => 0, < => 1, > => -1 */
1433 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1434 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1437 M_MOV_IMM(1, REG_ITMP1);
1438 M_MOV_IMM(-1, REG_ITMP2);
1439 emit_ucomiss_reg_reg(cd, s1, s2);
1440 M_CMOVULT(REG_ITMP1, d);
1441 M_CMOVUGT(REG_ITMP2, d);
1442 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1443 emit_store_dst(jd, iptr, d);
1446 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1447 /* == => 0, < => 1, > => -1 */
1449 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1453 M_MOV_IMM(1, REG_ITMP1);
1454 M_MOV_IMM(-1, REG_ITMP2);
1455 emit_ucomiss_reg_reg(cd, s1, s2);
1456 M_CMOVULT(REG_ITMP1, d);
1457 M_CMOVUGT(REG_ITMP2, d);
1458 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1459 emit_store_dst(jd, iptr, d);
1462 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1463 /* == => 0, < => 1, > => -1 */
1465 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1469 M_MOV_IMM(1, REG_ITMP1);
1470 M_MOV_IMM(-1, REG_ITMP2);
1471 emit_ucomisd_reg_reg(cd, s1, s2);
1472 M_CMOVULT(REG_ITMP1, d);
1473 M_CMOVUGT(REG_ITMP2, d);
1474 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1475 emit_store_dst(jd, iptr, d);
1478 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1479 /* == => 0, < => 1, > => -1 */
1481 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1482 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1483 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1485 M_MOV_IMM(1, REG_ITMP1);
1486 M_MOV_IMM(-1, REG_ITMP2);
1487 emit_ucomisd_reg_reg(cd, s1, s2);
1488 M_CMOVULT(REG_ITMP1, d);
1489 M_CMOVUGT(REG_ITMP2, d);
1490 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1491 emit_store_dst(jd, iptr, d);
1495 /* memory operations **************************************************/
1497 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1501 /* implicit null-pointer check */
1502 M_ILD(d, s1, OFFSET(java_array_t, size));
1503 emit_store_dst(jd, iptr, d);
1506 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1509 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1511 /* implicit null-pointer check */
1512 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1513 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1520 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1522 /* implicit null-pointer check */
1523 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1524 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1525 emit_store_dst(jd, iptr, d);
1528 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1533 /* implicit null-pointer check */
1534 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1535 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1536 emit_store_dst(jd, iptr, d);
1539 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1544 /* implicit null-pointer check */
1545 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1546 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1547 emit_store_dst(jd, iptr, d);
1550 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1555 /* implicit null-pointer check */
1556 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1557 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1558 emit_store_dst(jd, iptr, d);
1561 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1565 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1566 /* implicit null-pointer check */
1567 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1568 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1569 emit_store_dst(jd, iptr, d);
1572 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1575 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1576 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1577 /* implicit null-pointer check */
1578 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1579 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1580 emit_store_dst(jd, iptr, d);
1583 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1586 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1588 /* implicit null-pointer check */
1589 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1590 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1591 emit_store_dst(jd, iptr, d);
1595 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1597 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1598 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1599 /* implicit null-pointer check */
1600 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1601 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1602 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1605 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1608 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1609 /* implicit null-pointer check */
1610 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1611 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1612 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1615 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1618 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1619 /* implicit null-pointer check */
1620 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1621 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1622 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1625 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1629 /* implicit null-pointer check */
1630 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1631 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1632 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1635 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1639 /* implicit null-pointer check */
1640 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1645 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1649 /* implicit null-pointer check */
1650 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1651 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1652 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1655 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1659 /* implicit null-pointer check */
1660 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1661 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1662 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1665 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1669 /* implicit null-pointer check */
1670 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1671 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1675 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1677 emit_exception_check(cd, iptr);
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1681 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1682 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1686 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1690 /* implicit null-pointer check */
1691 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1692 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1695 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1699 /* implicit null-pointer check */
1700 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1701 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1704 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1707 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1708 /* implicit null-pointer check */
1709 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1710 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1713 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1716 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1717 /* implicit null-pointer check */
1718 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1719 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1722 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1726 /* implicit null-pointer check */
1727 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1729 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1730 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1733 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1734 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1738 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1741 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1742 /* implicit null-pointer check */
1743 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1744 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1748 case ICMD_GETSTATIC: /* ... ==> ..., value */
1750 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1751 uf = iptr->sx.s23.s3.uf;
1752 fieldtype = uf->fieldref->parseddesc.fd->type;
1753 disp = dseg_add_unique_address(cd, NULL);
1754 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1756 /* must be calculated before codegen_add_patch_ref */
1759 disp -= PATCHER_CALL_SIZE;
1761 /* PROFILE_CYCLE_STOP; */
1763 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1765 /* PROFILE_CYCLE_START; */
1768 fi = iptr->sx.s23.s3.fmiref->p.field;
1769 fieldtype = fi->type;
1770 disp = dseg_add_address(cd, fi->value);
1771 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1773 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1776 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1778 PROFILE_CYCLE_START;
1781 disp -= PATCHER_CALL_SIZE;
1785 /* This approach is much faster than moving the field
1786 address inline into a register. */
1788 M_ALD(REG_ITMP1, RIP, disp);
1790 switch (fieldtype) {
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1793 M_ILD(d, REG_ITMP1, 0);
1797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1798 M_LLD(d, REG_ITMP1, 0);
1801 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1802 M_FLD(d, REG_ITMP1, 0);
1805 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1806 M_DLD(d, REG_ITMP1, 0);
1809 emit_store_dst(jd, iptr, d);
1812 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1814 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1815 uf = iptr->sx.s23.s3.uf;
1816 fieldtype = uf->fieldref->parseddesc.fd->type;
1817 disp = dseg_add_unique_address(cd, NULL);
1818 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1820 /* must be calculated before codegen_add_patch_ref */
1823 disp -= PATCHER_CALL_SIZE;
1825 /* PROFILE_CYCLE_STOP; */
1827 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1829 /* PROFILE_CYCLE_START; */
1832 fi = iptr->sx.s23.s3.fmiref->p.field;
1833 fieldtype = fi->type;
1834 disp = dseg_add_address(cd, fi->value);
1835 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1837 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1840 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1842 PROFILE_CYCLE_START;
1845 disp -= PATCHER_CALL_SIZE;
1849 /* This approach is much faster than moving the field
1850 address inline into a register. */
1852 M_ALD(REG_ITMP1, RIP, disp);
1854 switch (fieldtype) {
1856 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1857 M_IST(s1, REG_ITMP1, 0);
1861 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1862 M_LST(s1, REG_ITMP1, 0);
1865 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1866 M_FST(s1, REG_ITMP1, 0);
1869 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1870 M_DST(s1, REG_ITMP1, 0);
1875 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1876 /* val = value (in current instruction) */
1877 /* following NOP) */
1879 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1880 uf = iptr->sx.s23.s3.uf;
1881 fieldtype = uf->fieldref->parseddesc.fd->type;
1882 disp = dseg_add_unique_address(cd, NULL);
1883 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1885 /* must be calculated before codegen_add_patch_ref */
1888 disp -= PATCHER_CALL_SIZE;
1890 /* PROFILE_CYCLE_STOP; */
1892 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1894 /* PROFILE_CYCLE_START; */
1897 fi = iptr->sx.s23.s3.fmiref->p.field;
1898 fieldtype = fi->type;
1899 disp = dseg_add_address(cd, fi->value);
1900 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1902 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1905 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1907 PROFILE_CYCLE_START;
1910 disp -= PATCHER_CALL_SIZE;
1914 /* This approach is much faster than moving the field
1915 address inline into a register. */
1917 M_ALD(REG_ITMP1, RIP, disp);
1919 switch (fieldtype) {
1922 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1927 if (IS_IMM32(iptr->sx.s23.s2.constval))
1928 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1930 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1931 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1937 case ICMD_GETFIELD: /* ... ==> ..., value */
1939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1941 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1942 uf = iptr->sx.s23.s3.uf;
1943 fieldtype = uf->fieldref->parseddesc.fd->type;
1946 /* PROFILE_CYCLE_STOP; */
1948 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1950 /* PROFILE_CYCLE_START; */
1953 fi = iptr->sx.s23.s3.fmiref->p.field;
1954 fieldtype = fi->type;
1958 /* implicit null-pointer check */
1959 switch (fieldtype) {
1961 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1962 M_ILD32(d, s1, disp);
1966 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1967 M_LLD32(d, s1, disp);
1970 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1971 M_FLD32(d, s1, disp);
1974 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1975 M_DLD32(d, s1, disp);
1978 emit_store_dst(jd, iptr, d);
1981 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1984 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1986 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1987 uf = iptr->sx.s23.s3.uf;
1988 fieldtype = uf->fieldref->parseddesc.fd->type;
1991 /* PROFILE_CYCLE_STOP; */
1993 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1995 /* PROFILE_CYCLE_START; */
1998 fi = iptr->sx.s23.s3.fmiref->p.field;
1999 fieldtype = fi->type;
2003 /* implicit null-pointer check */
2004 switch (fieldtype) {
2006 M_IST32(s2, s1, disp);
2010 M_LST32(s2, s1, disp);
2013 M_FST32(s2, s1, disp);
2016 M_DST32(s2, s1, disp);
2021 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2022 /* val = value (in current instruction) */
2023 /* following NOP) */
2025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2028 uf = iptr->sx.s23.s3.uf;
2029 fieldtype = uf->fieldref->parseddesc.fd->type;
2032 /* PROFILE_CYCLE_STOP; */
2034 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2036 /* PROFILE_CYCLE_START; */
2039 fi = iptr->sx.s23.s3.fmiref->p.field;
2040 fieldtype = fi->type;
2044 /* implicit null-pointer check */
2045 switch (fieldtype) {
2048 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2053 /* XXX why no check for IS_IMM32? */
2054 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2055 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2061 /* branch operations **************************************************/
2063 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2066 M_INTMOVE(s1, REG_ITMP1_XPTR);
2070 #ifdef ENABLE_VERIFIER
2071 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2072 uc = iptr->sx.s23.s2.uc;
2074 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2076 #endif /* ENABLE_VERIFIER */
2078 M_CALL_IMM(0); /* passing exception pc */
2079 M_POP(REG_ITMP2_XPC);
2081 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2085 case ICMD_GOTO: /* ... ==> ... */
2088 emit_br(cd, iptr->dst.block);
2092 case ICMD_JSR: /* ... ==> ... */
2094 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2098 case ICMD_IFNULL: /* ..., value ==> ... */
2099 case ICMD_IFNONNULL:
2101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2106 case ICMD_IFEQ: /* ..., value ==> ... */
2113 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2114 M_ICMP_IMM(iptr->sx.val.i, s1);
2115 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2118 case ICMD_IF_LEQ: /* ..., value ==> ... */
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 if (IS_IMM32(iptr->sx.val.l))
2127 M_LCMP_IMM(iptr->sx.val.l, s1);
2129 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2130 M_LCMP(REG_ITMP2, s1);
2132 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2135 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2136 case ICMD_IF_ICMPNE:
2137 case ICMD_IF_ICMPLT:
2138 case ICMD_IF_ICMPGE:
2139 case ICMD_IF_ICMPGT:
2140 case ICMD_IF_ICMPLE:
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2143 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2145 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2148 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2149 case ICMD_IF_ACMPNE:
2151 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2152 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2154 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2157 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2158 case ICMD_IF_LCMPNE:
2159 case ICMD_IF_LCMPLT:
2160 case ICMD_IF_LCMPGE:
2161 case ICMD_IF_LCMPGT:
2162 case ICMD_IF_LCMPLE:
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2167 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2170 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2173 REPLACEMENT_POINT_RETURN(cd, iptr);
2174 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2175 M_INTMOVE(s1, REG_RESULT);
2176 goto nowperformreturn;
2178 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2180 REPLACEMENT_POINT_RETURN(cd, iptr);
2181 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2182 M_INTMOVE(s1, REG_RESULT);
2184 #ifdef ENABLE_VERIFIER
2185 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2186 uc = iptr->sx.s23.s2.uc;
2190 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2192 PROFILE_CYCLE_START;
2194 #endif /* ENABLE_VERIFIER */
2195 goto nowperformreturn;
2197 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2200 REPLACEMENT_POINT_RETURN(cd, iptr);
2201 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2202 M_FLTMOVE(s1, REG_FRESULT);
2203 goto nowperformreturn;
2205 case ICMD_RETURN: /* ... ==> ... */
2207 REPLACEMENT_POINT_RETURN(cd, iptr);
2213 p = cd->stackframesize;
2215 #if !defined(NDEBUG)
2216 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2217 emit_verbosecall_exit(jd);
2218 #endif /* !defined(NDEBUG) */
2220 #if defined(ENABLE_THREADS)
2221 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2222 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2224 /* we need to save the proper return value */
2225 switch (iptr->opc) {
2229 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2233 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2237 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2240 /* and now restore the proper return value */
2241 switch (iptr->opc) {
2245 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2249 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2255 /* restore saved registers */
2257 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2258 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2260 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2261 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2264 /* deallocate stack */
2266 if (cd->stackframesize)
2267 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2269 /* generate method profiling code */
2278 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2281 branch_target_t *table;
2283 table = iptr->dst.table;
2285 l = iptr->sx.s23.s2.tablelow;
2286 i = iptr->sx.s23.s3.tablehigh;
2288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2289 M_INTMOVE(s1, REG_ITMP1);
2292 M_ISUB_IMM(l, REG_ITMP1);
2294 /* number of targets */
2299 M_ICMP_IMM(i - 1, REG_ITMP1);
2300 emit_bugt(cd, table[0].block);
2302 /* build jump table top down and use address of lowest entry */
2307 dseg_add_target(cd, table->block);
2311 /* length of dataseg after last dseg_add_target is used
2314 M_MOV_IMM(0, REG_ITMP2);
2316 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2322 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2325 lookup_target_t *lookup;
2327 lookup = iptr->dst.lookup;
2329 i = iptr->sx.s23.s2.lookupcount;
2331 MCODECHECK(8 + ((7 + 6) * i) + 5);
2332 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2335 M_ICMP_IMM(lookup->value, s1);
2336 emit_beq(cd, lookup->target.block);
2340 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2346 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2348 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2350 bte = iptr->sx.s23.s3.bte;
2354 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2356 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2357 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2358 case ICMD_INVOKEINTERFACE:
2360 REPLACEMENT_POINT_INVOKE(cd, iptr);
2362 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2364 um = iptr->sx.s23.s3.um;
2365 md = um->methodref->parseddesc.md;
2368 lm = iptr->sx.s23.s3.fmiref->p.method;
2370 md = lm->parseddesc;
2374 s3 = md->paramcount;
2376 MCODECHECK((20 * s3) + 128);
2378 /* copy arguments to registers or stack location */
2380 for (s3 = s3 - 1; s3 >= 0; s3--) {
2381 var = VAR(iptr->sx.s23.s2.args[s3]);
2382 d = md->params[s3].regoff;
2384 /* already preallocated (ARGVAR)? */
2386 if (var->flags & PREALLOC)
2389 if (IS_INT_LNG_TYPE(var->type)) {
2390 if (!md->params[s3].inmemory) {
2391 s1 = emit_load(jd, iptr, var, d);
2395 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2396 M_LST(s1, REG_SP, d);
2400 if (!md->params[s3].inmemory) {
2401 s1 = emit_load(jd, iptr, var, d);
2405 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2407 if (IS_2_WORD_TYPE(var->type))
2408 M_DST(s1, REG_SP, d);
2410 M_FST(s1, REG_SP, d);
2415 /* generate method profiling code */
2419 switch (iptr->opc) {
2421 if (bte->stub == NULL) {
2422 M_MOV_IMM(bte->fp, REG_ITMP1);
2424 M_MOV_IMM(bte->stub, REG_ITMP1);
2428 emit_exception_check(cd, iptr);
2431 case ICMD_INVOKESPECIAL:
2432 emit_nullpointer_check(cd, iptr, REG_A0);
2435 case ICMD_INVOKESTATIC:
2437 disp = dseg_add_unique_address(cd, NULL);
2438 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2440 /* must be calculated before codegen_add_patch_ref */
2443 disp -= PATCHER_CALL_SIZE;
2445 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2451 disp = dseg_add_functionptr(cd, lm->stubroutine);
2452 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2454 /* a = (ptrint) lm->stubroutine; */
2457 /* M_MOV_IMM(a, REG_ITMP2); */
2458 M_ALD(REG_ITMP2, RIP, disp);
2462 case ICMD_INVOKEVIRTUAL:
2464 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2469 s1 = OFFSET(vftbl_t, table[0]) +
2470 sizeof(methodptr) * lm->vftblindex;
2473 /* implicit null-pointer check */
2474 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2475 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2479 case ICMD_INVOKEINTERFACE:
2481 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2487 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2488 sizeof(methodptr) * lm->class->index;
2490 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2493 /* implicit null-pointer check */
2494 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2495 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2496 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2501 /* generate method profiling code */
2503 PROFILE_CYCLE_START;
2505 /* store size of call code in replacement point */
2507 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2508 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2510 /* store return value */
2512 switch (md->returntype.type) {
2516 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2517 M_INTMOVE(REG_RESULT, s1);
2518 emit_store_dst(jd, iptr, s1);
2522 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2523 M_FLTMOVE(REG_FRESULT, s1);
2524 emit_store_dst(jd, iptr, s1);
2533 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2535 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2536 /* object type cast-check */
2539 vftbl_t *supervftbl;
2542 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2548 super = iptr->sx.s23.s3.c.cls;
2549 superindex = super->index;
2550 supervftbl = super->vftbl;
2553 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2554 CODEGEN_CRITICAL_SECTION_NEW;
2556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2558 /* if class is not resolved, check which code to call */
2560 if (super == NULL) {
2562 emit_label_beq(cd, BRANCH_LABEL_1);
2564 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2565 iptr->sx.s23.s3.c.ref, 0);
2567 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2568 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2569 emit_label_beq(cd, BRANCH_LABEL_2);
2572 /* interface checkcast code */
2574 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2575 if (super != NULL) {
2577 emit_label_beq(cd, BRANCH_LABEL_3);
2580 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2582 if (super == NULL) {
2583 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2584 iptr->sx.s23.s3.c.ref,
2589 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2590 M_ICMP_IMM32(superindex, REG_ITMP3);
2591 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2593 M_ALD32(REG_ITMP3, REG_ITMP2,
2594 OFFSET(vftbl_t, interfacetable[0]) -
2595 superindex * sizeof(methodptr*));
2597 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2600 emit_label_br(cd, BRANCH_LABEL_4);
2602 emit_label(cd, BRANCH_LABEL_3);
2605 /* class checkcast code */
2607 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2608 if (super == NULL) {
2609 emit_label(cd, BRANCH_LABEL_2);
2613 emit_label_beq(cd, BRANCH_LABEL_5);
2616 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2618 if (super == NULL) {
2619 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
2620 iptr->sx.s23.s3.c.ref,
2624 M_MOV_IMM(supervftbl, REG_ITMP3);
2626 CODEGEN_CRITICAL_SECTION_START;
2628 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2630 /* if (s1 != REG_ITMP1) { */
2631 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2632 /* OFFSET(vftbl_t, baseval), */
2634 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2635 /* OFFSET(vftbl_t, diffval), */
2637 /* #if defined(ENABLE_THREADS) */
2638 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2640 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2644 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2645 M_ISUB(REG_ITMP3, REG_ITMP2);
2646 M_MOV_IMM(supervftbl, REG_ITMP3);
2647 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2650 CODEGEN_CRITICAL_SECTION_END;
2652 M_ICMP(REG_ITMP3, REG_ITMP2);
2653 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2656 emit_label(cd, BRANCH_LABEL_5);
2659 if (super == NULL) {
2660 emit_label(cd, BRANCH_LABEL_1);
2661 emit_label(cd, BRANCH_LABEL_4);
2664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2667 /* array type cast-check */
2669 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2670 M_INTMOVE(s1, REG_A0);
2672 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2673 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2674 iptr->sx.s23.s3.c.ref, 0);
2677 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2678 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2681 /* s1 may have been destroyed over the function call */
2682 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2684 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2690 emit_store_dst(jd, iptr, d);
2693 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2697 vftbl_t *supervftbl;
2700 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2706 super = iptr->sx.s23.s3.c.cls;
2707 superindex = super->index;
2708 supervftbl = super->vftbl;
2711 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2712 CODEGEN_CRITICAL_SECTION_NEW;
2714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2715 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2718 M_INTMOVE(s1, REG_ITMP1);
2724 /* if class is not resolved, check which code to call */
2726 if (super == NULL) {
2728 emit_label_beq(cd, BRANCH_LABEL_1);
2730 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2731 iptr->sx.s23.s3.c.ref, 0);
2733 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2734 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2735 emit_label_beq(cd, BRANCH_LABEL_2);
2738 /* interface instanceof code */
2740 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2741 if (super != NULL) {
2743 emit_label_beq(cd, BRANCH_LABEL_3);
2746 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2748 if (super == NULL) {
2749 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2750 iptr->sx.s23.s3.c.ref, 0);
2754 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2755 M_ICMP_IMM32(superindex, REG_ITMP3);
2757 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2760 M_ALD32(REG_ITMP1, REG_ITMP1,
2761 OFFSET(vftbl_t, interfacetable[0]) -
2762 superindex * sizeof(methodptr*));
2767 emit_label_br(cd, BRANCH_LABEL_4);
2769 emit_label(cd, BRANCH_LABEL_3);
2772 /* class instanceof code */
2774 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2775 if (super == NULL) {
2776 emit_label(cd, BRANCH_LABEL_2);
2780 emit_label_beq(cd, BRANCH_LABEL_5);
2783 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2785 if (super == NULL) {
2786 codegen_add_patch_ref(cd, PATCHER_instanceof_class,
2787 iptr->sx.s23.s3.c.ref, 0);
2790 M_MOV_IMM(supervftbl, REG_ITMP2);
2792 CODEGEN_CRITICAL_SECTION_START;
2794 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2795 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2796 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2798 CODEGEN_CRITICAL_SECTION_END;
2800 M_ISUB(REG_ITMP2, REG_ITMP1);
2801 M_CLR(d); /* may be REG_ITMP2 */
2802 M_ICMP(REG_ITMP3, REG_ITMP1);
2806 emit_label(cd, BRANCH_LABEL_5);
2809 if (super == NULL) {
2810 emit_label(cd, BRANCH_LABEL_1);
2811 emit_label(cd, BRANCH_LABEL_4);
2814 emit_store_dst(jd, iptr, d);
2818 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2820 /* check for negative sizes and copy sizes to stack if necessary */
2822 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2824 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2826 /* copy SAVEDVAR sizes to stack */
2827 var = VAR(iptr->sx.s23.s2.args[s1]);
2829 /* Already Preallocated? */
2830 if (!(var->flags & PREALLOC)) {
2831 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2832 M_LST(s2, REG_SP, s1 * 8);
2836 /* is a patcher function set? */
2838 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2839 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2840 iptr->sx.s23.s3.c.ref, 0);
2843 /* a0 = dimension count */
2845 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2847 /* a1 = classinfo */
2849 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2851 /* a2 = pointer to dimensions = stack pointer */
2853 M_MOV(REG_SP, REG_A2);
2855 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2858 /* check for exception before result assignment */
2860 emit_exception_check(cd, iptr);
2862 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2863 M_INTMOVE(REG_RESULT, s1);
2864 emit_store_dst(jd, iptr, s1);
2868 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2873 } /* for instruction */
2875 MCODECHECK(512); /* XXX require a lower number? */
2877 /* At the end of a basic block we may have to append some nops,
2878 because the patcher stub calling code might be longer than the
2879 actual instruction. So codepatching does not change the
2880 following block unintentionally. */
2882 if (cd->mcodeptr < cd->lastmcodeptr) {
2883 while (cd->mcodeptr < cd->lastmcodeptr) {
2888 } /* if (bptr -> flags >= BBREACHED) */
2889 } /* for basic block */
2891 dseg_createlinenumbertable(cd);
2893 /* generate stubs */
2895 emit_patcher_stubs(jd);
2897 /* everything's ok */
2903 /* codegen_emit_stub_compiler **************************************************
2905 Emit a stub routine which calls the compiler.
2907 *******************************************************************************/
2909 void codegen_emit_stub_compiler(jitdata *jd)
2914 /* get required compiler data */
2919 /* code for the stub */
2921 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
2922 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
2927 /* codegen_emit_stub_builtin ***************************************************
2929 Creates a stub routine which calls a builtin function.
2931 *******************************************************************************/
2933 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
2941 /* get required compiler data */
2948 /* calculate stack frame size */
2950 cd->stackframesize =
2951 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2952 md->paramcount + /* saved argument registers */
2953 1; /* return value */
2955 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
2957 /* create method header */
2959 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2960 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2961 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2962 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2963 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2964 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2965 (void) dseg_addlinenumbertablesize(cd);
2966 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2968 /* generate stub code */
2970 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2972 #if defined(ENABLE_GC_CACAO)
2973 /* Save callee saved integer registers in stackframeinfo (GC may
2974 need to recover them during a collection). */
2976 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
2977 OFFSET(stackframeinfo, intregs);
2979 for (i = 0; i < INT_SAV_CNT; i++)
2980 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2983 /* save integer and float argument registers */
2985 for (i = 0, j = 0; i < md->paramcount; i++) {
2986 if (!md->params[i].inmemory) {
2987 s1 = md->params[i].regoff;
2989 switch (md->paramtypes[i].type) {
2993 M_LST(s1, REG_SP, j * 8);
2997 M_DST(s1, REG_SP, j * 8);
3005 /* create dynamic stack info */
3007 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3008 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3009 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3010 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3011 M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
3014 /* restore integer and float argument registers */
3016 for (i = 0, j = 0; i < md->paramcount; i++) {
3017 if (!md->params[i].inmemory) {
3018 s1 = md->params[i].regoff;
3020 switch (md->paramtypes[i].type) {
3024 M_LLD(s1, REG_SP, j * 8);
3028 M_DLD(s1, REG_SP, j * 8);
3036 /* call the builtin function */
3038 M_MOV_IMM(bte->fp, REG_ITMP3);
3041 /* save return value */
3043 switch (md->returntype.type) {
3047 M_LST(REG_RESULT, REG_SP, 0 * 8);
3051 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3057 /* remove native stackframe info */
3059 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3060 M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
3063 /* restore return value */
3065 switch (md->returntype.type) {
3069 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3073 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3079 #if defined(ENABLE_GC_CACAO)
3080 /* Restore callee saved integer registers from stackframeinfo (GC
3081 might have modified them during a collection). */
3083 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3084 OFFSET(stackframeinfo, intregs);
3086 for (i = 0; i < INT_SAV_CNT; i++)
3087 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3090 /* remove stackframe */
3092 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3097 /* codegen_emit_stub_native ****************************************************
3099 Emits a stub routine which calls a native method.
3101 *******************************************************************************/
3103 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3114 /* get required compiler data */
3120 /* initialize variables */
3123 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3125 /* calculate stack frame size */
3127 cd->stackframesize =
3128 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3129 sizeof(localref_table) / SIZEOF_VOID_P +
3131 1 + /* functionptr, TODO: store in data segment */
3134 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3136 /* create method header */
3138 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3139 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3140 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3141 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3142 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3143 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3144 (void) dseg_addlinenumbertablesize(cd);
3145 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3147 #if defined(ENABLE_PROFILING)
3148 /* generate native method profiling code */
3150 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3151 /* count frequency */
3153 M_MOV_IMM(code, REG_ITMP3);
3154 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3158 /* generate stub code */
3160 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3162 #if !defined(NDEBUG)
3163 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3164 emit_verbosecall_enter(jd);
3167 /* get function address (this must happen before the stackframeinfo) */
3169 #if !defined(WITH_STATIC_CLASSPATH)
3171 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3174 M_MOV_IMM(f, REG_ITMP3);
3176 #if defined(ENABLE_GC_CACAO)
3177 /* Save callee saved integer registers in stackframeinfo (GC may
3178 need to recover them during a collection). */
3180 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3181 OFFSET(stackframeinfo, intregs);
3183 for (i = 0; i < INT_SAV_CNT; i++)
3184 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3187 /* save integer and float argument registers */
3189 for (i = 0; i < md->paramcount; i++) {
3190 if (!md->params[i].inmemory) {
3191 s1 = md->params[i].regoff;
3193 switch (md->paramtypes[i].type) {
3197 M_LST(s1, REG_SP, i * 8);
3201 M_DST(s1, REG_SP, i * 8);
3207 M_AST(REG_ITMP3, REG_SP, md->paramcount * 8);
3209 /* create dynamic stack info */
3211 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3212 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3213 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3214 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3215 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3218 /* restore integer and float argument registers */
3220 for (i = 0; i < md->paramcount; i++) {
3221 if (!md->params[i].inmemory) {
3222 s1 = md->params[i].regoff;
3224 switch (md->paramtypes[i].type) {
3228 M_LLD(s1, REG_SP, i * 8);
3232 M_DLD(s1, REG_SP, i * 8);
3238 M_ALD(REG_ITMP3, REG_SP, md->paramcount * 8);
3240 /* copy or spill arguments to new locations */
3242 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3243 t = md->paramtypes[i].type;
3244 s2 = nmd->params[j].regoff;
3246 if (IS_INT_LNG_TYPE(t)) {
3247 if (!md->params[i].inmemory) {
3248 s1 = md->params[i].regoff;
3250 if (!nmd->params[j].inmemory)
3253 M_LST(s1, REG_SP, s2);
3256 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3257 M_LLD(REG_ITMP1, REG_SP, s1);
3258 M_LST(REG_ITMP1, REG_SP, s2);
3262 /* We only copy spilled float arguments, as the float
3263 argument registers keep unchanged. */
3265 if (md->params[i].inmemory) {
3266 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3268 if (IS_2_WORD_TYPE(t)) {
3269 M_DLD(REG_FTMP1, REG_SP, s1);
3270 M_DST(REG_FTMP1, REG_SP, s2);
3273 M_FLD(REG_FTMP1, REG_SP, s1);
3274 M_FST(REG_FTMP1, REG_SP, s2);
3280 /* put class into second argument register */
3282 if (m->flags & ACC_STATIC)
3283 M_MOV_IMM(m->class, REG_A1);
3285 /* put env into first argument register */
3287 M_MOV_IMM(_Jv_env, REG_A0);
3289 /* do the native function call */
3293 /* save return value */
3295 switch (md->returntype.type) {
3299 M_LST(REG_RESULT, REG_SP, 0 * 8);
3303 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3309 #if !defined(NDEBUG)
3310 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3311 emit_verbosecall_exit(jd);
3314 /* remove native stackframe info */
3316 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3317 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3319 M_MOV(REG_RESULT, REG_ITMP3);
3321 /* restore return value */
3323 switch (md->returntype.type) {
3327 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3331 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3337 #if defined(ENABLE_GC_CACAO)
3338 /* Restore callee saved integer registers from stackframeinfo (GC
3339 might have modified them during a collection). */
3341 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3342 OFFSET(stackframeinfo, intregs);
3344 for (i = 0; i < INT_SAV_CNT; i++)
3345 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3348 /* remove stackframe */
3350 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3352 /* test for exception */
3358 /* handle exception */
3360 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3361 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3362 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3364 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3367 /* generate patcher stubs */
3369 emit_patcher_stubs(jd);
3374 * These are local overrides for various environment variables in Emacs.
3375 * Please do not remove this and leave it at the end of the file, where
3376 * Emacs will automagically detect them.
3377 * ---------------------------------------------------------------------
3380 * indent-tabs-mode: t
3384 * vim:noexpandtab:sw=4:ts=4: