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
25 $Id: codegen.c 7733 2007-04-16 22:56:37Z twisti $
39 #include "vm/jit/x86_64/arch.h"
40 #include "vm/jit/x86_64/codegen.h"
41 #include "vm/jit/x86_64/emit.h"
43 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
47 #if defined(ENABLE_THREADS)
48 # include "threads/native/lock.h"
51 #include "vm/builtin.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/stringlocal.h"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/asmpart.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.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 && (m->flags & ACC_SYNCHRONIZED))
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 (!jd->isleafmethod || 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 #if defined(ENABLE_THREADS)
156 /* IsSync contains the offset relative to the stack pointer for the
157 argument of monitor_exit used in the exception handler. Since the
158 offset could be zero and give a wrong meaning of the flag it is
162 if (checksync && (m->flags & ACC_SYNCHRONIZED))
163 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
166 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
168 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* 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 * 8);
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 + s1) * 8 + 8);
245 var->vv.regoff = cd->stackframesize + s1 + 1;
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 * 8);
255 else { /* stack arguments */
256 if (!IS_INMEMORY(var->flags))
257 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
259 var->vv.regoff = cd->stackframesize + s1 + 1;
264 /* save monitorenter argument */
266 #if defined(ENABLE_THREADS)
267 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
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;
481 /* PROFILE_CYCLE_STOP; */
483 codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
485 /* PROFILE_CYCLE_START; */
490 if (iptr->sx.val.anyptr == 0)
493 M_MOV_IMM(iptr->sx.val.anyptr, d);
495 emit_store_dst(jd, iptr, d);
499 /* load/store/copy/move operations ************************************/
501 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
502 case ICMD_ALOAD: /* s1 = local variable */
506 case ICMD_ISTORE: /* ..., value ==> ... */
513 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
517 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
518 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
521 /* integer operations *************************************************/
523 case ICMD_INEG: /* ..., value ==> ..., - value */
525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_LNEG: /* ..., value ==> ..., - value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
538 emit_store_dst(jd, iptr, d);
541 case ICMD_I2L: /* ..., value ==> ..., value */
543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
546 emit_store_dst(jd, iptr, d);
549 case ICMD_L2I: /* ..., value ==> ..., value */
551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
562 emit_store_dst(jd, iptr, d);
565 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
578 emit_store_dst(jd, iptr, d);
582 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
593 emit_store_dst(jd, iptr, d);
597 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
598 /* sx.val.i = constant */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
603 /* Using inc and dec is not faster than add (tested with
607 M_IADD_IMM(iptr->sx.val.i, d);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
626 /* sx.val.l = constant */
628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
631 if (IS_IMM32(iptr->sx.val.l))
632 M_LADD_IMM(iptr->sx.val.l, d);
634 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
635 M_LADD(REG_ITMP2, d);
637 emit_store_dst(jd, iptr, d);
640 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
646 M_INTMOVE(s1, REG_ITMP1);
647 M_ISUB(s2, REG_ITMP1);
648 M_INTMOVE(REG_ITMP1, d);
653 emit_store_dst(jd, iptr, d);
656 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
657 /* sx.val.i = constant */
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
662 M_ISUB_IMM(iptr->sx.val.i, d);
663 emit_store_dst(jd, iptr, d);
666 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672 M_INTMOVE(s1, REG_ITMP1);
673 M_LSUB(s2, REG_ITMP1);
674 M_INTMOVE(REG_ITMP1, d);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
683 /* sx.val.l = constant */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
688 if (IS_IMM32(iptr->sx.val.l))
689 M_LSUB_IMM(iptr->sx.val.l, d);
691 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
692 M_LSUB(REG_ITMP2, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
708 emit_store_dst(jd, iptr, d);
711 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
712 /* sx.val.i = constant */
714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
715 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
716 if (iptr->sx.val.i == 2) {
720 M_IMUL_IMM(s1, iptr->sx.val.i, d);
721 emit_store_dst(jd, iptr, d);
724 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
728 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
735 emit_store_dst(jd, iptr, d);
738 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
739 /* sx.val.l = constant */
741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
743 if (IS_IMM32(iptr->sx.val.l))
744 M_LMUL_IMM(s1, iptr->sx.val.l, d);
746 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
748 M_LMUL(REG_ITMP2, d);
750 emit_store_dst(jd, iptr, d);
753 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
755 s1 = emit_load_s1(jd, iptr, RAX);
756 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
757 d = codegen_reg_of_dst(jd, iptr, RAX);
760 M_INTMOVE(s2, REG_ITMP3);
761 emit_arithmetic_check(cd, iptr, REG_ITMP3);
763 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
765 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
767 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
768 M_BEQ(1 + 3); /* 6 bytes */
770 emit_cltd(cd); /* 1 byte */
771 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
774 emit_store_dst(jd, iptr, d);
775 dst = VAROP(iptr->dst);
776 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
777 M_MOV(REG_ITMP2, RDX); /* restore RDX */
780 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
782 s1 = emit_load_s1(jd, iptr, RAX);
783 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
784 d = codegen_reg_of_dst(jd, iptr, RDX);
787 M_INTMOVE(s2, REG_ITMP3);
788 emit_arithmetic_check(cd, iptr, REG_ITMP3);
790 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
792 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
794 M_CLR(RDX); /* 3 bytes */
795 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
796 M_BEQ(1 + 3); /* 6 bytes */
798 emit_cltd(cd); /* 1 byte */
799 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
802 emit_store_dst(jd, iptr, d);
803 dst = VAROP(iptr->dst);
804 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
805 M_MOV(REG_ITMP2, RDX); /* restore RDX */
808 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
809 /* sx.val.i = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
813 M_INTMOVE(s1, REG_ITMP1);
814 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
815 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
816 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
817 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
818 emit_mov_reg_reg(cd, REG_ITMP1, d);
819 emit_store_dst(jd, iptr, d);
822 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
823 /* sx.val.i = constant */
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
827 M_INTMOVE(s1, REG_ITMP1);
828 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
829 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
830 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
831 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
832 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
833 emit_mov_reg_reg(cd, REG_ITMP1, d);
834 emit_store_dst(jd, iptr, d);
838 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
840 s1 = emit_load_s1(jd, iptr, RAX);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
842 d = codegen_reg_of_dst(jd, iptr, RAX);
845 M_INTMOVE(s2, REG_ITMP3);
846 emit_arithmetic_check(cd, iptr, REG_ITMP3);
848 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
850 /* check as described in jvm spec */
851 disp = dseg_add_s8(cd, 0x8000000000000000LL);
852 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
854 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
855 M_BEQ(2 + 3); /* 6 bytes */
857 emit_cqto(cd); /* 2 bytes */
858 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
861 emit_store_dst(jd, iptr, d);
862 dst = VAROP(iptr->dst);
863 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
864 M_MOV(REG_ITMP2, RDX); /* restore RDX */
867 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
869 s1 = emit_load_s1(jd, iptr, RAX);
870 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
871 d = codegen_reg_of_dst(jd, iptr, RDX);
874 M_INTMOVE(s2, REG_ITMP3);
875 emit_arithmetic_check(cd, iptr, REG_ITMP3);
877 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
879 /* check as described in jvm spec */
880 disp = dseg_add_s8(cd, 0x8000000000000000LL);
881 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
883 M_LXOR(RDX, RDX); /* 3 bytes */
884 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
885 M_BEQ(2 + 3); /* 6 bytes */
887 emit_cqto(cd); /* 2 bytes */
888 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
891 emit_store_dst(jd, iptr, d);
892 dst = VAROP(iptr->dst);
893 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
894 M_MOV(REG_ITMP2, RDX); /* restore RDX */
897 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
898 /* sx.val.i = constant */
900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
901 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
902 M_INTMOVE(s1, REG_ITMP1);
903 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
904 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
905 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
906 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
907 emit_mov_reg_reg(cd, REG_ITMP1, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
912 /* sx.val.l = constant */
914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
915 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
916 M_INTMOVE(s1, REG_ITMP1);
917 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
918 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
919 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
920 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
921 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
922 emit_mov_reg_reg(cd, REG_ITMP1, d);
923 emit_store_dst(jd, iptr, d);
926 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
928 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
929 emit_ishift(jd, SHIFT_SHL, iptr);
932 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
933 /* sx.val.i = constant */
935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
936 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
938 M_ISLL_IMM(iptr->sx.val.i, d);
939 emit_store_dst(jd, iptr, d);
942 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
944 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
945 emit_ishift(jd, SHIFT_SAR, iptr);
948 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
949 /* sx.val.i = constant */
951 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
952 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
954 M_ISRA_IMM(iptr->sx.val.i, d);
955 emit_store_dst(jd, iptr, d);
958 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
960 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
961 emit_ishift(jd, SHIFT_SHR, iptr);
964 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
965 /* sx.val.i = constant */
967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
968 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
970 M_ISRL_IMM(iptr->sx.val.i, d);
971 emit_store_dst(jd, iptr, d);
974 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
976 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
977 emit_lshift(jd, SHIFT_SHL, iptr);
980 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
981 /* sx.val.i = constant */
983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
984 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
986 M_LSLL_IMM(iptr->sx.val.i, d);
987 emit_store_dst(jd, iptr, d);
990 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
992 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
993 emit_lshift(jd, SHIFT_SAR, iptr);
996 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
997 /* sx.val.i = constant */
999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1000 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1002 M_LSRA_IMM(iptr->sx.val.i, d);
1003 emit_store_dst(jd, iptr, d);
1006 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1008 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1009 emit_lshift(jd, SHIFT_SHR, iptr);
1012 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1013 /* sx.val.l = constant */
1015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 M_LSRL_IMM(iptr->sx.val.i, d);
1019 emit_store_dst(jd, iptr, d);
1022 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1037 /* sx.val.i = constant */
1039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1042 M_IAND_IMM(iptr->sx.val.i, d);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1061 /* sx.val.l = constant */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1066 if (IS_IMM32(iptr->sx.val.l))
1067 M_LAND_IMM(iptr->sx.val.l, d);
1069 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1070 M_LAND(REG_ITMP2, d);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1090 /* sx.val.i = constant */
1092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1095 M_IOR_IMM(iptr->sx.val.i, d);
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1114 /* sx.val.l = constant */
1116 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1119 if (IS_IMM32(iptr->sx.val.l))
1120 M_LOR_IMM(iptr->sx.val.l, d);
1122 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1123 M_LOR(REG_ITMP2, d);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1139 emit_store_dst(jd, iptr, d);
1142 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1143 /* sx.val.i = constant */
1145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1148 M_IXOR_IMM(iptr->sx.val.i, d);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1155 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1156 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1163 emit_store_dst(jd, iptr, d);
1166 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1167 /* sx.val.l = constant */
1169 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1170 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1172 if (IS_IMM32(iptr->sx.val.l))
1173 M_LXOR_IMM(iptr->sx.val.l, d);
1175 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1176 M_LXOR(REG_ITMP2, d);
1178 emit_store_dst(jd, iptr, d);
1182 /* floating operations ************************************************/
1184 case ICMD_FNEG: /* ..., value ==> ..., - value */
1186 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1188 disp = dseg_add_s4(cd, 0x80000000);
1190 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1191 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1192 emit_store_dst(jd, iptr, d);
1195 case ICMD_DNEG: /* ..., value ==> ..., - value */
1197 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1198 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1199 disp = dseg_add_s8(cd, 0x8000000000000000);
1201 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1202 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1208 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1209 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1210 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1222 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1224 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1231 emit_store_dst(jd, iptr, d);
1234 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1236 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1237 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1238 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1240 M_FLTMOVE(s2, REG_FTMP2);
1245 emit_store_dst(jd, iptr, d);
1248 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1250 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1251 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1254 M_FLTMOVE(s2, REG_FTMP2);
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1264 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1265 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1266 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1278 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1279 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1280 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1287 emit_store_dst(jd, iptr, d);
1290 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1292 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 M_FLTMOVE(s2, REG_FTMP2);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1306 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1307 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1308 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1310 M_FLTMOVE(s2, REG_FTMP2);
1315 emit_store_dst(jd, iptr, d);
1318 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1321 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1328 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1329 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1331 emit_store_dst(jd, iptr, d);
1334 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1337 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1352 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1355 M_ICMP_IMM(0x80000000, d); /* corner cases */
1356 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1357 ((REG_RESULT == d) ? 0 : 3);
1359 M_FLTMOVE(s1, REG_FTMP1);
1360 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1362 M_INTMOVE(REG_RESULT, d);
1363 emit_store_dst(jd, iptr, d);
1366 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1368 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1371 M_ICMP_IMM(0x80000000, d); /* corner cases */
1372 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1373 ((REG_RESULT == d) ? 0 : 3);
1375 M_FLTMOVE(s1, REG_FTMP1);
1376 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1378 M_INTMOVE(REG_RESULT, d);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1384 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1387 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1388 M_LCMP(REG_ITMP2, d); /* corner cases */
1389 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1390 ((REG_RESULT == d) ? 0 : 3);
1392 M_FLTMOVE(s1, REG_FTMP1);
1393 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1395 M_INTMOVE(REG_RESULT, d);
1396 emit_store_dst(jd, iptr, d);
1399 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1401 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1404 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1405 M_LCMP(REG_ITMP2, d); /* corner cases */
1406 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1407 ((REG_RESULT == d) ? 0 : 3);
1409 M_FLTMOVE(s1, REG_FTMP1);
1410 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1412 M_INTMOVE(REG_RESULT, d);
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1418 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1419 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1421 emit_store_dst(jd, iptr, d);
1424 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1426 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1427 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1429 emit_store_dst(jd, iptr, d);
1432 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1433 /* == => 0, < => 1, > => -1 */
1435 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1436 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1437 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1439 M_MOV_IMM(1, REG_ITMP1);
1440 M_MOV_IMM(-1, REG_ITMP2);
1441 emit_ucomiss_reg_reg(cd, s1, s2);
1442 M_CMOVULT(REG_ITMP1, d);
1443 M_CMOVUGT(REG_ITMP2, d);
1444 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1445 emit_store_dst(jd, iptr, d);
1448 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1449 /* == => 0, < => 1, > => -1 */
1451 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1452 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1455 M_MOV_IMM(1, REG_ITMP1);
1456 M_MOV_IMM(-1, REG_ITMP2);
1457 emit_ucomiss_reg_reg(cd, s1, s2);
1458 M_CMOVULT(REG_ITMP1, d);
1459 M_CMOVUGT(REG_ITMP2, d);
1460 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1461 emit_store_dst(jd, iptr, d);
1464 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1465 /* == => 0, < => 1, > => -1 */
1467 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1471 M_MOV_IMM(1, REG_ITMP1);
1472 M_MOV_IMM(-1, REG_ITMP2);
1473 emit_ucomisd_reg_reg(cd, s1, s2);
1474 M_CMOVULT(REG_ITMP1, d);
1475 M_CMOVUGT(REG_ITMP2, d);
1476 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1477 emit_store_dst(jd, iptr, d);
1480 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1481 /* == => 0, < => 1, > => -1 */
1483 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1487 M_MOV_IMM(1, REG_ITMP1);
1488 M_MOV_IMM(-1, REG_ITMP2);
1489 emit_ucomisd_reg_reg(cd, s1, s2);
1490 M_CMOVULT(REG_ITMP1, d);
1491 M_CMOVUGT(REG_ITMP2, d);
1492 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1493 emit_store_dst(jd, iptr, d);
1497 /* memory operations **************************************************/
1499 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1502 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1503 /* implicit null-pointer check */
1504 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1505 emit_store_dst(jd, iptr, d);
1508 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1513 /* implicit null-pointer check */
1514 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1515 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1524 /* implicit null-pointer check */
1525 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1526 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1527 emit_store_dst(jd, iptr, d);
1530 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1533 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1535 /* implicit null-pointer check */
1536 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1537 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1538 emit_store_dst(jd, iptr, d);
1541 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1546 /* implicit null-pointer check */
1547 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1548 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1549 emit_store_dst(jd, iptr, d);
1552 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1557 /* implicit null-pointer check */
1558 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1559 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1560 emit_store_dst(jd, iptr, d);
1563 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1566 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1567 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1568 /* implicit null-pointer check */
1569 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1570 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1571 emit_store_dst(jd, iptr, d);
1574 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1578 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1579 /* implicit null-pointer check */
1580 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1581 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1582 emit_store_dst(jd, iptr, d);
1585 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1588 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1590 /* implicit null-pointer check */
1591 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1592 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1593 emit_store_dst(jd, iptr, d);
1597 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1601 /* implicit null-pointer check */
1602 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1603 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1604 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1607 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1611 /* implicit null-pointer check */
1612 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1613 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1614 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1617 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621 /* implicit null-pointer check */
1622 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1623 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1624 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1627 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1631 /* implicit null-pointer check */
1632 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1633 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1634 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1637 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1641 /* implicit null-pointer check */
1642 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1643 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1644 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1647 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1651 /* implicit null-pointer check */
1652 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1653 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1654 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1657 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1660 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1661 /* implicit null-pointer check */
1662 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1663 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1664 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1667 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1671 /* implicit null-pointer check */
1672 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1673 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1677 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1679 emit_exception_check(cd, iptr);
1681 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1682 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1683 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1684 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1688 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1692 /* implicit null-pointer check */
1693 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1694 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1697 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1701 /* implicit null-pointer check */
1702 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1703 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1706 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1710 /* implicit null-pointer check */
1711 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1712 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1715 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1719 /* implicit null-pointer check */
1720 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1721 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1724 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1727 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1728 /* implicit null-pointer check */
1729 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1731 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1732 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1735 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1736 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1740 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1744 /* implicit null-pointer check */
1745 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1746 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1750 case ICMD_GETSTATIC: /* ... ==> ..., value */
1752 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1753 uf = iptr->sx.s23.s3.uf;
1754 fieldtype = uf->fieldref->parseddesc.fd->type;
1755 disp = dseg_add_unique_address(cd, NULL);
1756 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1758 /* must be calculated before codegen_add_patch_ref */
1761 disp -= PATCHER_CALL_SIZE;
1763 /* PROFILE_CYCLE_STOP; */
1765 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1767 /* PROFILE_CYCLE_START; */
1770 fi = iptr->sx.s23.s3.fmiref->p.field;
1771 fieldtype = fi->type;
1772 disp = dseg_add_address(cd, &(fi->value));
1773 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1775 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1778 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1780 PROFILE_CYCLE_START;
1783 disp -= PATCHER_CALL_SIZE;
1787 /* This approach is much faster than moving the field
1788 address inline into a register. */
1790 M_ALD(REG_ITMP1, RIP, disp);
1792 switch (fieldtype) {
1794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1795 M_ILD(d, REG_ITMP1, 0);
1799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1800 M_LLD(d, REG_ITMP1, 0);
1803 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1804 M_FLD(d, REG_ITMP1, 0);
1807 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1808 M_DLD(d, REG_ITMP1, 0);
1811 emit_store_dst(jd, iptr, d);
1814 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1816 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1817 uf = iptr->sx.s23.s3.uf;
1818 fieldtype = uf->fieldref->parseddesc.fd->type;
1819 disp = dseg_add_unique_address(cd, NULL);
1820 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1822 /* must be calculated before codegen_add_patch_ref */
1825 disp -= PATCHER_CALL_SIZE;
1827 /* PROFILE_CYCLE_STOP; */
1829 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1831 /* PROFILE_CYCLE_START; */
1834 fi = iptr->sx.s23.s3.fmiref->p.field;
1835 fieldtype = fi->type;
1836 disp = dseg_add_address(cd, &(fi->value));
1837 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1839 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1842 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1844 PROFILE_CYCLE_START;
1847 disp -= PATCHER_CALL_SIZE;
1851 /* This approach is much faster than moving the field
1852 address inline into a register. */
1854 M_ALD(REG_ITMP1, RIP, disp);
1856 switch (fieldtype) {
1858 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1859 M_IST(s1, REG_ITMP1, 0);
1863 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1864 M_LST(s1, REG_ITMP1, 0);
1867 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1868 M_FST(s1, REG_ITMP1, 0);
1871 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1872 M_DST(s1, REG_ITMP1, 0);
1877 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1878 /* val = value (in current instruction) */
1879 /* following NOP) */
1881 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1882 uf = iptr->sx.s23.s3.uf;
1883 fieldtype = uf->fieldref->parseddesc.fd->type;
1884 disp = dseg_add_unique_address(cd, NULL);
1885 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1887 /* must be calculated before codegen_add_patch_ref */
1890 disp -= PATCHER_CALL_SIZE;
1892 /* PROFILE_CYCLE_STOP; */
1894 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1896 /* PROFILE_CYCLE_START; */
1899 fi = iptr->sx.s23.s3.fmiref->p.field;
1900 fieldtype = fi->type;
1901 disp = dseg_add_address(cd, &(fi->value));
1902 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1904 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1907 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1909 PROFILE_CYCLE_START;
1912 disp -= PATCHER_CALL_SIZE;
1916 /* This approach is much faster than moving the field
1917 address inline into a register. */
1919 M_ALD(REG_ITMP1, RIP, disp);
1921 switch (fieldtype) {
1924 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1929 if (IS_IMM32(iptr->sx.s23.s2.constval))
1930 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1932 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1933 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1939 case ICMD_GETFIELD: /* ... ==> ..., value */
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1943 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1944 uf = iptr->sx.s23.s3.uf;
1945 fieldtype = uf->fieldref->parseddesc.fd->type;
1948 /* PROFILE_CYCLE_STOP; */
1950 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1952 /* PROFILE_CYCLE_START; */
1955 fi = iptr->sx.s23.s3.fmiref->p.field;
1956 fieldtype = fi->type;
1960 /* implicit null-pointer check */
1961 switch (fieldtype) {
1963 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1964 M_ILD32(d, s1, disp);
1968 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1969 M_LLD32(d, s1, disp);
1972 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1973 M_FLD32(d, s1, disp);
1976 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1977 M_DLD32(d, s1, disp);
1980 emit_store_dst(jd, iptr, d);
1983 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1986 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1988 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1989 uf = iptr->sx.s23.s3.uf;
1990 fieldtype = uf->fieldref->parseddesc.fd->type;
1993 /* PROFILE_CYCLE_STOP; */
1995 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1997 /* PROFILE_CYCLE_START; */
2000 fi = iptr->sx.s23.s3.fmiref->p.field;
2001 fieldtype = fi->type;
2005 /* implicit null-pointer check */
2006 switch (fieldtype) {
2008 M_IST32(s2, s1, disp);
2012 M_LST32(s2, s1, disp);
2015 M_FST32(s2, s1, disp);
2018 M_DST32(s2, s1, disp);
2023 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2024 /* val = value (in current instruction) */
2025 /* following NOP) */
2027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2029 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2030 uf = iptr->sx.s23.s3.uf;
2031 fieldtype = uf->fieldref->parseddesc.fd->type;
2034 /* PROFILE_CYCLE_STOP; */
2036 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2038 /* PROFILE_CYCLE_START; */
2041 fi = iptr->sx.s23.s3.fmiref->p.field;
2042 fieldtype = fi->type;
2046 /* implicit null-pointer check */
2047 switch (fieldtype) {
2050 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2055 /* XXX why no check for IS_IMM32? */
2056 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2057 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2063 /* branch operations **************************************************/
2065 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2068 M_INTMOVE(s1, REG_ITMP1_XPTR);
2072 #ifdef ENABLE_VERIFIER
2073 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2074 uc = iptr->sx.s23.s2.uc;
2076 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2078 #endif /* ENABLE_VERIFIER */
2080 M_CALL_IMM(0); /* passing exception pc */
2081 M_POP(REG_ITMP2_XPC);
2083 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2087 case ICMD_GOTO: /* ... ==> ... */
2090 emit_br(cd, iptr->dst.block);
2094 case ICMD_JSR: /* ... ==> ... */
2096 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2100 case ICMD_IFNULL: /* ..., value ==> ... */
2101 case ICMD_IFNONNULL:
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2105 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2108 case ICMD_IFEQ: /* ..., value ==> ... */
2115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2116 M_ICMP_IMM(iptr->sx.val.i, s1);
2117 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2120 case ICMD_IF_LEQ: /* ..., value ==> ... */
2127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2128 if (IS_IMM32(iptr->sx.val.l))
2129 M_LCMP_IMM(iptr->sx.val.l, s1);
2131 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2132 M_LCMP(REG_ITMP2, s1);
2134 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2137 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2138 case ICMD_IF_ICMPNE:
2139 case ICMD_IF_ICMPLT:
2140 case ICMD_IF_ICMPGE:
2141 case ICMD_IF_ICMPGT:
2142 case ICMD_IF_ICMPLE:
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_ICMPEQ, BRANCH_OPT_NONE);
2150 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2151 case ICMD_IF_ACMPNE:
2153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2156 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2159 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2160 case ICMD_IF_LCMPNE:
2161 case ICMD_IF_LCMPLT:
2162 case ICMD_IF_LCMPGE:
2163 case ICMD_IF_LCMPGT:
2164 case ICMD_IF_LCMPLE:
2166 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2167 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2169 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2172 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2175 REPLACEMENT_POINT_RETURN(cd, iptr);
2176 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2177 M_INTMOVE(s1, REG_RESULT);
2178 goto nowperformreturn;
2180 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2182 REPLACEMENT_POINT_RETURN(cd, iptr);
2183 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2184 M_INTMOVE(s1, REG_RESULT);
2186 #ifdef ENABLE_VERIFIER
2187 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2188 uc = iptr->sx.s23.s2.uc;
2192 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2194 PROFILE_CYCLE_START;
2196 #endif /* ENABLE_VERIFIER */
2197 goto nowperformreturn;
2199 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2202 REPLACEMENT_POINT_RETURN(cd, iptr);
2203 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2204 M_FLTMOVE(s1, REG_FRESULT);
2205 goto nowperformreturn;
2207 case ICMD_RETURN: /* ... ==> ... */
2209 REPLACEMENT_POINT_RETURN(cd, iptr);
2215 p = cd->stackframesize;
2217 #if !defined(NDEBUG)
2218 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2219 emit_verbosecall_exit(jd);
2220 #endif /* !defined(NDEBUG) */
2222 #if defined(ENABLE_THREADS)
2223 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2224 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2226 /* we need to save the proper return value */
2227 switch (iptr->opc) {
2231 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2235 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2239 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2242 /* and now restore the proper return value */
2243 switch (iptr->opc) {
2247 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2251 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2257 /* restore saved registers */
2259 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2260 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2262 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2263 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2266 /* deallocate stack */
2268 if (cd->stackframesize)
2269 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2271 /* generate method profiling code */
2280 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2283 branch_target_t *table;
2285 table = iptr->dst.table;
2287 l = iptr->sx.s23.s2.tablelow;
2288 i = iptr->sx.s23.s3.tablehigh;
2290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2291 M_INTMOVE(s1, REG_ITMP1);
2294 M_ISUB_IMM(l, REG_ITMP1);
2296 /* number of targets */
2301 M_ICMP_IMM(i - 1, REG_ITMP1);
2302 emit_bugt(cd, table[0].block);
2304 /* build jump table top down and use address of lowest entry */
2309 dseg_add_target(cd, table->block);
2313 /* length of dataseg after last dseg_add_target is used
2316 M_MOV_IMM(0, REG_ITMP2);
2318 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2324 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2327 lookup_target_t *lookup;
2329 lookup = iptr->dst.lookup;
2331 i = iptr->sx.s23.s2.lookupcount;
2333 MCODECHECK(8 + ((7 + 6) * i) + 5);
2334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 M_ICMP_IMM(lookup->value, s1);
2338 emit_beq(cd, lookup->target.block);
2342 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2348 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
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 * 8);
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 * 8);
2410 M_FST(s1, REG_SP, d * 8);
2415 /* generate method profiling code */
2419 switch (iptr->opc) {
2421 M_MOV_IMM(bte->fp, REG_ITMP1);
2424 emit_exception_check(cd, iptr);
2427 case ICMD_INVOKESPECIAL:
2428 emit_nullpointer_check(cd, iptr, REG_A0);
2431 case ICMD_INVOKESTATIC:
2433 disp = dseg_add_unique_address(cd, NULL);
2434 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2436 /* must be calculated before codegen_add_patch_ref */
2439 disp -= PATCHER_CALL_SIZE;
2441 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2447 disp = dseg_add_functionptr(cd, lm->stubroutine);
2448 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2450 /* a = (ptrint) lm->stubroutine; */
2453 /* M_MOV_IMM(a, REG_ITMP2); */
2454 M_ALD(REG_ITMP2, RIP, disp);
2458 case ICMD_INVOKEVIRTUAL:
2460 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2465 s1 = OFFSET(vftbl_t, table[0]) +
2466 sizeof(methodptr) * lm->vftblindex;
2469 /* implicit null-pointer check */
2470 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2471 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2475 case ICMD_INVOKEINTERFACE:
2477 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2483 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2484 sizeof(methodptr) * lm->class->index;
2486 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2489 /* implicit null-pointer check */
2490 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2491 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2492 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2497 /* generate method profiling code */
2499 PROFILE_CYCLE_START;
2501 /* store size of call code in replacement point */
2503 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2505 /* store return value */
2507 switch (md->returntype.type) {
2511 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2512 M_INTMOVE(REG_RESULT, s1);
2513 emit_store_dst(jd, iptr, s1);
2517 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2518 M_FLTMOVE(REG_FRESULT, s1);
2519 emit_store_dst(jd, iptr, s1);
2528 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2530 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2531 /* object type cast-check */
2534 vftbl_t *supervftbl;
2537 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2543 super = iptr->sx.s23.s3.c.cls;
2544 superindex = super->index;
2545 supervftbl = super->vftbl;
2548 #if defined(ENABLE_THREADS)
2549 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2553 /* if class is not resolved, check which code to call */
2555 if (super == NULL) {
2557 emit_label_beq(cd, BRANCH_LABEL_1);
2559 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2560 iptr->sx.s23.s3.c.ref, 0);
2562 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2563 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2564 emit_label_beq(cd, BRANCH_LABEL_2);
2567 /* interface checkcast code */
2569 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2570 if (super != NULL) {
2572 emit_label_beq(cd, BRANCH_LABEL_3);
2575 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2577 if (super == NULL) {
2578 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2579 iptr->sx.s23.s3.c.ref,
2584 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2585 M_ICMP_IMM32(superindex, REG_ITMP3);
2586 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2588 M_ALD32(REG_ITMP3, REG_ITMP2,
2589 OFFSET(vftbl_t, interfacetable[0]) -
2590 superindex * sizeof(methodptr*));
2592 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2595 emit_label_br(cd, BRANCH_LABEL_4);
2597 emit_label(cd, BRANCH_LABEL_3);
2600 /* class checkcast code */
2602 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2603 if (super == NULL) {
2604 emit_label(cd, BRANCH_LABEL_2);
2608 emit_label_beq(cd, BRANCH_LABEL_5);
2611 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2613 if (super == NULL) {
2614 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
2615 iptr->sx.s23.s3.c.ref,
2619 M_MOV_IMM(supervftbl, REG_ITMP3);
2620 #if defined(ENABLE_THREADS)
2621 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2623 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2625 /* if (s1 != REG_ITMP1) { */
2626 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2627 /* OFFSET(vftbl_t, baseval), */
2629 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2630 /* OFFSET(vftbl_t, diffval), */
2632 /* #if defined(ENABLE_THREADS) */
2633 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2635 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2639 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2640 M_ISUB(REG_ITMP3, REG_ITMP2);
2641 M_MOV_IMM(supervftbl, REG_ITMP3);
2642 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2644 #if defined(ENABLE_THREADS)
2645 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2647 M_ICMP(REG_ITMP3, REG_ITMP2);
2648 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2651 emit_label(cd, BRANCH_LABEL_5);
2654 if (super == NULL) {
2655 emit_label(cd, BRANCH_LABEL_1);
2656 emit_label(cd, BRANCH_LABEL_4);
2659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2662 /* array type cast-check */
2664 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2665 M_INTMOVE(s1, REG_A0);
2667 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2668 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2669 iptr->sx.s23.s3.c.ref, 0);
2672 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2673 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2676 /* s1 may have been destroyed over the function call */
2677 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2679 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2685 emit_store_dst(jd, iptr, d);
2688 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2692 vftbl_t *supervftbl;
2695 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2701 super = iptr->sx.s23.s3.c.cls;
2702 superindex = super->index;
2703 supervftbl = super->vftbl;
2706 #if defined(ENABLE_THREADS)
2707 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2714 M_INTMOVE(s1, REG_ITMP1);
2720 /* if class is not resolved, check which code to call */
2722 if (super == NULL) {
2724 emit_label_beq(cd, BRANCH_LABEL_1);
2726 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2727 iptr->sx.s23.s3.c.ref, 0);
2729 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2730 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2731 emit_label_beq(cd, BRANCH_LABEL_2);
2734 /* interface instanceof code */
2736 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2737 if (super != NULL) {
2739 emit_label_beq(cd, BRANCH_LABEL_3);
2742 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2744 if (super == NULL) {
2745 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2746 iptr->sx.s23.s3.c.ref, 0);
2750 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2751 M_ICMP_IMM32(superindex, REG_ITMP3);
2753 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2756 M_ALD32(REG_ITMP1, REG_ITMP1,
2757 OFFSET(vftbl_t, interfacetable[0]) -
2758 superindex * sizeof(methodptr*));
2763 emit_label_br(cd, BRANCH_LABEL_4);
2765 emit_label(cd, BRANCH_LABEL_3);
2768 /* class instanceof code */
2770 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2771 if (super == NULL) {
2772 emit_label(cd, BRANCH_LABEL_2);
2776 emit_label_beq(cd, BRANCH_LABEL_5);
2779 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2781 if (super == NULL) {
2782 codegen_add_patch_ref(cd, PATCHER_instanceof_class,
2783 iptr->sx.s23.s3.c.ref, 0);
2786 M_MOV_IMM(supervftbl, REG_ITMP2);
2788 #if defined(ENABLE_THREADS)
2789 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2792 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2793 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2794 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2796 #if defined(ENABLE_THREADS)
2797 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
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);
2896 REPLACEMENT_EMIT_STUBS(jd);
2898 /* everything's ok */
2904 /* codegen_emit_stub_compiler **************************************************
2906 Emit a stub routine which calls the compiler.
2908 *******************************************************************************/
2910 void codegen_emit_stub_compiler(jitdata *jd)
2915 /* get required compiler data */
2920 /* code for the stub */
2922 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
2923 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
2928 /* codegen_emit_stub_native ****************************************************
2930 Emits a stub routine which calls a native method.
2932 *******************************************************************************/
2934 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2945 /* get required compiler data */
2951 /* initialize variables */
2954 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2956 /* calculate stack frame size */
2958 cd->stackframesize =
2959 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2960 sizeof(localref_table) / SIZEOF_VOID_P +
2961 INT_ARG_CNT + FLT_ARG_CNT +
2962 1 + /* functionptr, TODO: store in data segment */
2965 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
2967 /* create method header */
2969 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2970 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2971 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2972 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2973 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2974 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2975 (void) dseg_addlinenumbertablesize(cd);
2976 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2978 #if defined(ENABLE_PROFILING)
2979 /* generate native method profiling code */
2981 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2982 /* count frequency */
2984 M_MOV_IMM(code, REG_ITMP3);
2985 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2989 /* generate stub code */
2991 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2993 #if !defined(NDEBUG)
2994 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2995 emit_verbosecall_enter(jd);
2998 /* get function address (this must happen before the stackframeinfo) */
3000 #if !defined(WITH_STATIC_CLASSPATH)
3002 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3005 M_MOV_IMM(f, REG_ITMP3);
3008 /* save integer and float argument registers */
3010 for (i = 0, j = 0; i < md->paramcount; i++) {
3011 if (!md->params[i].inmemory) {
3012 s1 = md->params[i].regoff;
3014 switch (md->paramtypes[i].type) {
3018 M_LST(s1, REG_SP, j * 8);
3022 M_DST(s1, REG_SP, j * 8);
3030 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3032 /* create dynamic stack info */
3034 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3035 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3036 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3037 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3038 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3041 /* restore integer and float argument registers */
3043 for (i = 0, j = 0; i < md->paramcount; i++) {
3044 if (!md->params[i].inmemory) {
3045 s1 = md->params[i].regoff;
3047 switch (md->paramtypes[i].type) {
3051 M_LLD(s1, REG_SP, j * 8);
3055 M_DLD(s1, REG_SP, j * 8);
3063 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3066 /* copy or spill arguments to new locations */
3068 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3069 t = md->paramtypes[i].type;
3070 s2 = nmd->params[j].regoff;
3072 if (IS_INT_LNG_TYPE(t)) {
3073 if (!md->params[i].inmemory) {
3074 s1 = md->params[i].regoff;
3076 if (!nmd->params[j].inmemory)
3079 M_LST(s1, REG_SP, s2 * 8);
3082 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3083 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3084 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3088 /* We only copy spilled float arguments, as the float
3089 argument registers keep unchanged. */
3091 if (md->params[i].inmemory) {
3092 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3094 if (IS_2_WORD_TYPE(t)) {
3095 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3096 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3099 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3100 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3106 /* put class into second argument register */
3108 if (m->flags & ACC_STATIC)
3109 M_MOV_IMM(m->class, REG_A1);
3111 /* put env into first argument register */
3113 M_MOV_IMM(_Jv_env, REG_A0);
3115 /* do the native function call */
3119 /* save return value */
3121 switch (md->returntype.type) {
3125 M_LST(REG_RESULT, REG_SP, 0 * 8);
3129 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3135 #if !defined(NDEBUG)
3136 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3137 emit_verbosecall_exit(jd);
3140 /* remove native stackframe info */
3142 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3143 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3145 M_MOV(REG_RESULT, REG_ITMP3);
3147 /* restore return value */
3149 switch (md->returntype.type) {
3153 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3157 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3163 /* remove stackframe */
3165 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3167 /* test for exception */
3173 /* handle exception */
3175 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3176 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3177 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3179 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3182 /* generate patcher stubs */
3184 emit_patcher_stubs(jd);
3189 * These are local overrides for various environment variables in Emacs.
3190 * Please do not remove this and leave it at the end of the file, where
3191 * Emacs will automagically detect them.
3192 * ---------------------------------------------------------------------
3195 * indent-tabs-mode: t
3199 * vim:noexpandtab:sw=4:ts=4: