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 7918 2007-05-20 20:42:18Z michi $
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"
45 #include "native/jni.h"
46 #include "native/native.h"
48 #include "threads/lock-common.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/stringlocal.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/methodheader.h"
63 #include "vm/jit/parse.h"
64 #include "vm/jit/patcher.h"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/replace.h"
67 #include "vm/jit/stacktrace.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
75 #include "vmcore/statistics.h"
78 /* codegen_emit ****************************************************************
80 Generates machine code.
82 *******************************************************************************/
84 bool codegen_emit(jitdata *jd)
90 s4 len, s1, s2, s3, d, disp;
97 constant_classref *cr;
99 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
100 unresolved_method *um;
101 builtintable_entry *bte;
104 unresolved_field *uf;
108 /* get required compiler data */
115 /* prevent compiler warnings */
128 /* space to save used callee saved registers */
130 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
131 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
133 cd->stackframesize = rd->memuse + savedregs_num;
135 #if defined(ENABLE_THREADS)
136 /* space to save argument of monitor_enter */
138 if (checksync && (m->flags & ACC_SYNCHRONIZED))
139 cd->stackframesize++;
142 /* Keep stack of non-leaf functions 16-byte aligned for calls into
143 native code e.g. libc or jni (alignment problems with
146 if (!jd->isleafmethod || opt_verbosecall)
147 cd->stackframesize |= 0x1;
149 /* create method header */
151 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
152 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
154 #if defined(ENABLE_THREADS)
155 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
161 if (checksync && (m->flags & ACC_SYNCHRONIZED))
162 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
165 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
167 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
168 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
169 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
171 (void) dseg_addlinenumbertablesize(cd);
173 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
175 /* create exception table */
177 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
178 dseg_add_target(cd, ex->start);
179 dseg_add_target(cd, ex->end);
180 dseg_add_target(cd, ex->handler);
181 (void) dseg_add_unique_address(cd, ex->catchtype.any);
184 #if defined(ENABLE_PROFILING)
185 /* generate method profiling code */
187 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
188 /* count frequency */
190 M_MOV_IMM(code, REG_ITMP3);
191 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
197 /* create stack frame (if necessary) */
199 if (cd->stackframesize)
200 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
202 /* save used callee saved registers */
204 p = cd->stackframesize;
205 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
206 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
208 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
209 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
212 /* take arguments out of register or stack frame */
216 for (p = 0, l = 0; p < md->paramcount; p++) {
217 t = md->paramtypes[p].type;
219 varindex = jd->local_map[l * 5 + t];
222 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
225 if (varindex == UNUSED)
230 s1 = md->params[p].regoff;
232 if (IS_INT_LNG_TYPE(t)) { /* integer args */
233 if (!md->params[p].inmemory) { /* register arguments */
234 if (!IS_INMEMORY(var->flags))
235 M_INTMOVE(s1, var->vv.regoff);
237 M_LST(s1, REG_SP, var->vv.regoff * 8);
239 else { /* stack arguments */
240 if (!IS_INMEMORY(var->flags))
241 /* + 8 for return address */
242 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
244 var->vv.regoff = cd->stackframesize + s1 + 1;
247 else { /* floating args */
248 if (!md->params[p].inmemory) { /* register arguments */
249 if (!IS_INMEMORY(var->flags))
250 M_FLTMOVE(s1, var->vv.regoff);
252 M_DST(s1, REG_SP, var->vv.regoff * 8);
254 else { /* stack arguments */
255 if (!IS_INMEMORY(var->flags))
256 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
258 var->vv.regoff = cd->stackframesize + s1 + 1;
263 /* save monitorenter argument */
265 #if defined(ENABLE_THREADS)
266 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
267 /* stack offset for monitor argument */
271 if (opt_verbosecall) {
272 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
274 for (p = 0; p < INT_ARG_CNT; p++)
275 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
277 for (p = 0; p < FLT_ARG_CNT; p++)
278 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
280 s1 += INT_ARG_CNT + FLT_ARG_CNT;
283 /* decide which monitor enter function to call */
285 if (m->flags & ACC_STATIC) {
286 M_MOV_IMM(&m->class->object.header, REG_A0);
291 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
294 M_AST(REG_A0, REG_SP, s1 * 8);
295 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
298 if (opt_verbosecall) {
299 for (p = 0; p < INT_ARG_CNT; p++)
300 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
302 for (p = 0; p < FLT_ARG_CNT; p++)
303 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
305 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
311 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
312 emit_verbosecall_enter(jd);
313 #endif /* !defined(NDEBUG) */
317 /* end of header generation */
319 /* create replacement points */
321 REPLACEMENT_POINTS_INIT(cd, jd);
323 /* walk through all basic blocks */
325 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
327 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
329 if (bptr->flags >= BBREACHED) {
331 /* branch resolving */
333 codegen_resolve_branchrefs(cd, bptr);
335 /* handle replacement points */
337 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
339 /* copy interface registers to their destination */
344 #if defined(ENABLE_PROFILING)
345 /* generate basicblock profiling code */
347 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
348 /* count frequency */
350 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
351 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
353 /* if this is an exception handler, start profiling again */
355 if (bptr->type == BBTYPE_EXH)
360 #if defined(ENABLE_LSRA)
364 src = bptr->invars[len];
365 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
366 if (bptr->type == BBTYPE_EXH) {
367 /* d = reg_of_var(rd, src, REG_ITMP1); */
368 if (!IS_INMEMORY(src->flags))
372 M_INTMOVE(REG_ITMP1, d);
373 emit_store(jd, NULL, src, d);
383 var = VAR(bptr->invars[len]);
384 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
385 if (bptr->type == BBTYPE_EXH) {
386 d = codegen_reg_of_var(0, var, REG_ITMP1);
387 M_INTMOVE(REG_ITMP1, d);
388 emit_store(jd, NULL, var, d);
392 assert((var->flags & INOUT));
395 #if defined(ENABLE_LSRA)
398 /* walk through all instructions */
403 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
404 if (iptr->line != currentline) {
405 dseg_addlinenumber(cd, iptr->line);
406 currentline = iptr->line;
409 MCODECHECK(1024); /* 1KB should be enough */
412 case ICMD_NOP: /* ... ==> ... */
413 case ICMD_POP: /* ..., value ==> ... */
414 case ICMD_POP2: /* ..., value, value ==> ... */
417 case ICMD_INLINE_START:
419 REPLACEMENT_POINT_INLINE_START(cd, iptr);
422 case ICMD_INLINE_BODY:
424 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
425 dseg_addlinenumber_inline_start(cd, iptr);
426 dseg_addlinenumber(cd, iptr->line);
429 case ICMD_INLINE_END:
431 dseg_addlinenumber_inline_end(cd, iptr);
432 dseg_addlinenumber(cd, iptr->line);
435 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
438 emit_nullpointer_check(cd, iptr, s1);
441 /* constant operations ************************************************/
443 case ICMD_ICONST: /* ... ==> ..., constant */
445 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
446 ICONST(d, iptr->sx.val.i);
447 emit_store_dst(jd, iptr, d);
450 case ICMD_LCONST: /* ... ==> ..., constant */
452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
453 LCONST(d, iptr->sx.val.l);
454 emit_store_dst(jd, iptr, d);
457 case ICMD_FCONST: /* ... ==> ..., constant */
459 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
460 disp = dseg_add_float(cd, iptr->sx.val.f);
461 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
462 emit_store_dst(jd, iptr, d);
465 case ICMD_DCONST: /* ... ==> ..., constant */
467 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
468 disp = dseg_add_double(cd, iptr->sx.val.d);
469 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
470 emit_store_dst(jd, iptr, d);
473 case ICMD_ACONST: /* ... ==> ..., constant */
475 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
477 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
478 cr = iptr->sx.val.c.ref;
480 /* PROFILE_CYCLE_STOP; */
482 codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
484 /* PROFILE_CYCLE_START; */
489 if (iptr->sx.val.anyptr == 0)
492 M_MOV_IMM(iptr->sx.val.anyptr, d);
494 emit_store_dst(jd, iptr, d);
498 /* load/store/copy/move operations ************************************/
500 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
501 case ICMD_ALOAD: /* s1 = local variable */
505 case ICMD_ISTORE: /* ..., value ==> ... */
516 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
520 /* integer operations *************************************************/
522 case ICMD_INEG: /* ..., value ==> ..., - value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528 emit_store_dst(jd, iptr, d);
531 case ICMD_LNEG: /* ..., value ==> ..., - value */
533 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
537 emit_store_dst(jd, iptr, d);
540 case ICMD_I2L: /* ..., value ==> ..., value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
545 emit_store_dst(jd, iptr, d);
548 case ICMD_L2I: /* ..., value ==> ..., value */
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
553 emit_store_dst(jd, iptr, d);
556 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
561 emit_store_dst(jd, iptr, d);
564 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
569 emit_store_dst(jd, iptr, d);
572 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
575 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
577 emit_store_dst(jd, iptr, d);
581 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
592 emit_store_dst(jd, iptr, d);
596 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
597 /* sx.val.i = constant */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
602 /* Using inc and dec is not faster than add (tested with
606 M_IADD_IMM(iptr->sx.val.i, d);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
625 /* sx.val.l = constant */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
630 if (IS_IMM32(iptr->sx.val.l))
631 M_LADD_IMM(iptr->sx.val.l, d);
633 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
634 M_LADD(REG_ITMP2, d);
636 emit_store_dst(jd, iptr, d);
639 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
645 M_INTMOVE(s1, REG_ITMP1);
646 M_ISUB(s2, REG_ITMP1);
647 M_INTMOVE(REG_ITMP1, d);
652 emit_store_dst(jd, iptr, d);
655 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
656 /* sx.val.i = constant */
658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
661 M_ISUB_IMM(iptr->sx.val.i, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
671 M_INTMOVE(s1, REG_ITMP1);
672 M_LSUB(s2, REG_ITMP1);
673 M_INTMOVE(REG_ITMP1, d);
678 emit_store_dst(jd, iptr, d);
681 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
682 /* sx.val.l = constant */
684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
687 if (IS_IMM32(iptr->sx.val.l))
688 M_LSUB_IMM(iptr->sx.val.l, d);
690 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
691 M_LSUB(REG_ITMP2, d);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
707 emit_store_dst(jd, iptr, d);
710 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
711 /* sx.val.i = constant */
713 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
715 if (iptr->sx.val.i == 2) {
719 M_IMUL_IMM(s1, iptr->sx.val.i, d);
720 emit_store_dst(jd, iptr, d);
723 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
734 emit_store_dst(jd, iptr, d);
737 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
738 /* sx.val.l = constant */
740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
741 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
742 if (IS_IMM32(iptr->sx.val.l))
743 M_LMUL_IMM(s1, iptr->sx.val.l, d);
745 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
747 M_LMUL(REG_ITMP2, d);
749 emit_store_dst(jd, iptr, d);
752 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
754 s1 = emit_load_s1(jd, iptr, RAX);
755 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
756 d = codegen_reg_of_dst(jd, iptr, RAX);
759 M_INTMOVE(s2, REG_ITMP3);
760 emit_arithmetic_check(cd, iptr, REG_ITMP3);
762 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
764 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
766 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
767 M_BEQ(1 + 3); /* 6 bytes */
769 emit_cltd(cd); /* 1 byte */
770 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
773 emit_store_dst(jd, iptr, d);
774 dst = VAROP(iptr->dst);
775 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
776 M_MOV(REG_ITMP2, RDX); /* restore RDX */
779 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
781 s1 = emit_load_s1(jd, iptr, RAX);
782 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
783 d = codegen_reg_of_dst(jd, iptr, RDX);
786 M_INTMOVE(s2, REG_ITMP3);
787 emit_arithmetic_check(cd, iptr, REG_ITMP3);
789 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
791 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
793 M_CLR(RDX); /* 3 bytes */
794 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
795 M_BEQ(1 + 3); /* 6 bytes */
797 emit_cltd(cd); /* 1 byte */
798 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
801 emit_store_dst(jd, iptr, d);
802 dst = VAROP(iptr->dst);
803 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
804 M_MOV(REG_ITMP2, RDX); /* restore RDX */
807 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
808 /* sx.val.i = constant */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
812 M_INTMOVE(s1, REG_ITMP1);
813 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
814 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
815 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
816 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
817 emit_mov_reg_reg(cd, REG_ITMP1, d);
818 emit_store_dst(jd, iptr, d);
821 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
822 /* sx.val.i = constant */
824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
826 M_INTMOVE(s1, REG_ITMP1);
827 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
828 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
829 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
830 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
831 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
832 emit_mov_reg_reg(cd, REG_ITMP1, d);
833 emit_store_dst(jd, iptr, d);
837 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
839 s1 = emit_load_s1(jd, iptr, RAX);
840 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
841 d = codegen_reg_of_dst(jd, iptr, RAX);
844 M_INTMOVE(s2, REG_ITMP3);
845 emit_arithmetic_check(cd, iptr, REG_ITMP3);
847 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
849 /* check as described in jvm spec */
850 disp = dseg_add_s8(cd, 0x8000000000000000LL);
851 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
853 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
854 M_BEQ(2 + 3); /* 6 bytes */
856 emit_cqto(cd); /* 2 bytes */
857 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
860 emit_store_dst(jd, iptr, d);
861 dst = VAROP(iptr->dst);
862 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
863 M_MOV(REG_ITMP2, RDX); /* restore RDX */
866 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
868 s1 = emit_load_s1(jd, iptr, RAX);
869 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
870 d = codegen_reg_of_dst(jd, iptr, RDX);
873 M_INTMOVE(s2, REG_ITMP3);
874 emit_arithmetic_check(cd, iptr, REG_ITMP3);
876 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
878 /* check as described in jvm spec */
879 disp = dseg_add_s8(cd, 0x8000000000000000LL);
880 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
882 M_LXOR(RDX, RDX); /* 3 bytes */
883 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
884 M_BEQ(2 + 3); /* 6 bytes */
886 emit_cqto(cd); /* 2 bytes */
887 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
890 emit_store_dst(jd, iptr, d);
891 dst = VAROP(iptr->dst);
892 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
893 M_MOV(REG_ITMP2, RDX); /* restore RDX */
896 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
897 /* sx.val.i = constant */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
901 M_INTMOVE(s1, REG_ITMP1);
902 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
903 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
904 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
905 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
906 emit_mov_reg_reg(cd, REG_ITMP1, d);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
911 /* sx.val.l = constant */
913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
914 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
915 M_INTMOVE(s1, REG_ITMP1);
916 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
917 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
918 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
919 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
920 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
921 emit_mov_reg_reg(cd, REG_ITMP1, d);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
927 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
928 emit_ishift(jd, SHIFT_SHL, iptr);
931 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
932 /* sx.val.i = constant */
934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
935 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
937 M_ISLL_IMM(iptr->sx.val.i, d);
938 emit_store_dst(jd, iptr, d);
941 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
943 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
944 emit_ishift(jd, SHIFT_SAR, iptr);
947 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
948 /* sx.val.i = constant */
950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953 M_ISRA_IMM(iptr->sx.val.i, d);
954 emit_store_dst(jd, iptr, d);
957 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
959 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
960 emit_ishift(jd, SHIFT_SHR, iptr);
963 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
964 /* sx.val.i = constant */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
969 M_ISRL_IMM(iptr->sx.val.i, d);
970 emit_store_dst(jd, iptr, d);
973 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
975 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
976 emit_lshift(jd, SHIFT_SHL, iptr);
979 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
980 /* sx.val.i = constant */
982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
983 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
985 M_LSLL_IMM(iptr->sx.val.i, d);
986 emit_store_dst(jd, iptr, d);
989 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
991 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
992 emit_lshift(jd, SHIFT_SAR, iptr);
995 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
996 /* sx.val.i = constant */
998 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
999 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1001 M_LSRA_IMM(iptr->sx.val.i, d);
1002 emit_store_dst(jd, iptr, d);
1005 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1007 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1008 emit_lshift(jd, SHIFT_SHR, iptr);
1011 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1012 /* sx.val.l = constant */
1014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1017 M_LSRL_IMM(iptr->sx.val.i, d);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1024 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1036 /* sx.val.i = constant */
1038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1039 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1041 M_IAND_IMM(iptr->sx.val.i, d);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1048 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1060 /* sx.val.l = constant */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1065 if (IS_IMM32(iptr->sx.val.l))
1066 M_LAND_IMM(iptr->sx.val.l, d);
1068 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1069 M_LAND(REG_ITMP2, d);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1077 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1078 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1089 /* sx.val.i = constant */
1091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1094 M_IOR_IMM(iptr->sx.val.i, d);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1109 emit_store_dst(jd, iptr, d);
1112 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1113 /* sx.val.l = constant */
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1118 if (IS_IMM32(iptr->sx.val.l))
1119 M_LOR_IMM(iptr->sx.val.l, d);
1121 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1122 M_LOR(REG_ITMP2, d);
1124 emit_store_dst(jd, iptr, d);
1127 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1130 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1138 emit_store_dst(jd, iptr, d);
1141 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1142 /* sx.val.i = constant */
1144 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1145 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1147 M_IXOR_IMM(iptr->sx.val.i, d);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1162 emit_store_dst(jd, iptr, d);
1165 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1166 /* sx.val.l = constant */
1168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1169 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1171 if (IS_IMM32(iptr->sx.val.l))
1172 M_LXOR_IMM(iptr->sx.val.l, d);
1174 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1175 M_LXOR(REG_ITMP2, d);
1177 emit_store_dst(jd, iptr, d);
1181 /* floating operations ************************************************/
1183 case ICMD_FNEG: /* ..., value ==> ..., - value */
1185 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1186 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1187 disp = dseg_add_s4(cd, 0x80000000);
1189 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1190 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1191 emit_store_dst(jd, iptr, d);
1194 case ICMD_DNEG: /* ..., value ==> ..., - value */
1196 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1197 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1198 disp = dseg_add_s8(cd, 0x8000000000000000);
1200 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1201 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1207 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1208 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1221 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1222 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1223 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1237 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239 M_FLTMOVE(s2, REG_FTMP2);
1244 emit_store_dst(jd, iptr, d);
1247 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1251 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1253 M_FLTMOVE(s2, REG_FTMP2);
1258 emit_store_dst(jd, iptr, d);
1261 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1263 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1264 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1265 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1277 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1279 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1291 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1295 M_FLTMOVE(s2, REG_FTMP2);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1305 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1306 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1307 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1309 M_FLTMOVE(s2, REG_FTMP2);
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1328 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1330 emit_store_dst(jd, iptr, d);
1333 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1335 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1336 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1338 emit_store_dst(jd, iptr, d);
1341 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1351 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1352 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1354 M_ICMP_IMM(0x80000000, d); /* corner cases */
1355 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1356 ((REG_RESULT == d) ? 0 : 3);
1358 M_FLTMOVE(s1, REG_FTMP1);
1359 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1361 M_INTMOVE(REG_RESULT, d);
1362 emit_store_dst(jd, iptr, d);
1365 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1367 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1368 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1370 M_ICMP_IMM(0x80000000, d); /* corner cases */
1371 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1372 ((REG_RESULT == d) ? 0 : 3);
1374 M_FLTMOVE(s1, REG_FTMP1);
1375 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1377 M_INTMOVE(REG_RESULT, d);
1378 emit_store_dst(jd, iptr, d);
1381 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1383 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1384 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1386 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1387 M_LCMP(REG_ITMP2, d); /* corner cases */
1388 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1389 ((REG_RESULT == d) ? 0 : 3);
1391 M_FLTMOVE(s1, REG_FTMP1);
1392 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1394 M_INTMOVE(REG_RESULT, d);
1395 emit_store_dst(jd, iptr, d);
1398 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1400 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1403 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1404 M_LCMP(REG_ITMP2, d); /* corner cases */
1405 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1406 ((REG_RESULT == d) ? 0 : 3);
1408 M_FLTMOVE(s1, REG_FTMP1);
1409 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1411 M_INTMOVE(REG_RESULT, d);
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1417 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1418 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1420 emit_store_dst(jd, iptr, d);
1423 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1425 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1426 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1432 /* == => 0, < => 1, > => -1 */
1434 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1435 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1436 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1438 M_MOV_IMM(1, REG_ITMP1);
1439 M_MOV_IMM(-1, REG_ITMP2);
1440 emit_ucomiss_reg_reg(cd, s1, s2);
1441 M_CMOVULT(REG_ITMP1, d);
1442 M_CMOVUGT(REG_ITMP2, d);
1443 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1444 emit_store_dst(jd, iptr, d);
1447 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1448 /* == => 0, < => 1, > => -1 */
1450 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1454 M_MOV_IMM(1, REG_ITMP1);
1455 M_MOV_IMM(-1, REG_ITMP2);
1456 emit_ucomiss_reg_reg(cd, s1, s2);
1457 M_CMOVULT(REG_ITMP1, d);
1458 M_CMOVUGT(REG_ITMP2, d);
1459 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1460 emit_store_dst(jd, iptr, d);
1463 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1464 /* == => 0, < => 1, > => -1 */
1466 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1467 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1470 M_MOV_IMM(1, REG_ITMP1);
1471 M_MOV_IMM(-1, REG_ITMP2);
1472 emit_ucomisd_reg_reg(cd, s1, s2);
1473 M_CMOVULT(REG_ITMP1, d);
1474 M_CMOVUGT(REG_ITMP2, d);
1475 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1476 emit_store_dst(jd, iptr, d);
1479 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1480 /* == => 0, < => 1, > => -1 */
1482 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1483 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1484 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1486 M_MOV_IMM(1, REG_ITMP1);
1487 M_MOV_IMM(-1, REG_ITMP2);
1488 emit_ucomisd_reg_reg(cd, s1, s2);
1489 M_CMOVULT(REG_ITMP1, d);
1490 M_CMOVUGT(REG_ITMP2, d);
1491 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1492 emit_store_dst(jd, iptr, d);
1496 /* memory operations **************************************************/
1498 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1502 /* implicit null-pointer check */
1503 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1504 emit_store_dst(jd, iptr, d);
1507 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1510 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1512 /* implicit null-pointer check */
1513 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1514 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1515 emit_store_dst(jd, iptr, d);
1518 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1521 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1523 /* implicit null-pointer check */
1524 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1525 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1526 emit_store_dst(jd, iptr, d);
1529 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1534 /* implicit null-pointer check */
1535 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1536 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1537 emit_store_dst(jd, iptr, d);
1540 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1543 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1545 /* implicit null-pointer check */
1546 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1547 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1548 emit_store_dst(jd, iptr, d);
1551 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1554 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1556 /* implicit null-pointer check */
1557 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1558 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1559 emit_store_dst(jd, iptr, d);
1562 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1565 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1566 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1567 /* implicit null-pointer check */
1568 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1569 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1570 emit_store_dst(jd, iptr, d);
1573 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1578 /* implicit null-pointer check */
1579 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1580 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1581 emit_store_dst(jd, iptr, d);
1584 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1587 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1589 /* implicit null-pointer check */
1590 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1591 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1592 emit_store_dst(jd, iptr, d);
1596 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1600 /* implicit null-pointer check */
1601 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1602 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1603 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1606 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1609 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1610 /* implicit null-pointer check */
1611 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1612 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1613 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1616 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1620 /* implicit null-pointer check */
1621 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1622 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1623 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1626 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1629 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1630 /* implicit null-pointer check */
1631 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1632 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1633 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1636 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1639 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1640 /* implicit null-pointer check */
1641 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1642 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1643 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1646 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1649 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1650 /* implicit null-pointer check */
1651 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1652 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1653 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1656 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1659 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1660 /* implicit null-pointer check */
1661 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1662 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1663 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1666 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1670 /* implicit null-pointer check */
1671 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1672 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1676 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1678 emit_exception_check(cd, iptr);
1680 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1681 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1682 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1683 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1687 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691 /* implicit null-pointer check */
1692 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1693 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1696 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1700 /* implicit null-pointer check */
1701 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1702 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1705 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1708 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1709 /* implicit null-pointer check */
1710 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1711 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1714 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1717 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1718 /* implicit null-pointer check */
1719 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1720 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1723 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1727 /* implicit null-pointer check */
1728 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1730 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1731 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1734 emit_movl_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 >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1739 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1743 /* implicit null-pointer check */
1744 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1745 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1749 case ICMD_GETSTATIC: /* ... ==> ..., value */
1751 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1752 uf = iptr->sx.s23.s3.uf;
1753 fieldtype = uf->fieldref->parseddesc.fd->type;
1754 disp = dseg_add_unique_address(cd, NULL);
1755 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1757 /* must be calculated before codegen_add_patch_ref */
1760 disp -= PATCHER_CALL_SIZE;
1762 /* PROFILE_CYCLE_STOP; */
1764 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1766 /* PROFILE_CYCLE_START; */
1769 fi = iptr->sx.s23.s3.fmiref->p.field;
1770 fieldtype = fi->type;
1771 disp = dseg_add_address(cd, &(fi->value));
1772 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1774 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1777 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1779 PROFILE_CYCLE_START;
1782 disp -= PATCHER_CALL_SIZE;
1786 /* This approach is much faster than moving the field
1787 address inline into a register. */
1789 M_ALD(REG_ITMP1, RIP, disp);
1791 switch (fieldtype) {
1793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1794 M_ILD(d, REG_ITMP1, 0);
1798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1799 M_LLD(d, REG_ITMP1, 0);
1802 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1803 M_FLD(d, REG_ITMP1, 0);
1806 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1807 M_DLD(d, REG_ITMP1, 0);
1810 emit_store_dst(jd, iptr, d);
1813 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816 uf = iptr->sx.s23.s3.uf;
1817 fieldtype = uf->fieldref->parseddesc.fd->type;
1818 disp = dseg_add_unique_address(cd, NULL);
1819 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1821 /* must be calculated before codegen_add_patch_ref */
1824 disp -= PATCHER_CALL_SIZE;
1826 /* PROFILE_CYCLE_STOP; */
1828 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1830 /* PROFILE_CYCLE_START; */
1833 fi = iptr->sx.s23.s3.fmiref->p.field;
1834 fieldtype = fi->type;
1835 disp = dseg_add_address(cd, &(fi->value));
1836 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1838 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1841 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1843 PROFILE_CYCLE_START;
1846 disp -= PATCHER_CALL_SIZE;
1850 /* This approach is much faster than moving the field
1851 address inline into a register. */
1853 M_ALD(REG_ITMP1, RIP, disp);
1855 switch (fieldtype) {
1857 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1858 M_IST(s1, REG_ITMP1, 0);
1862 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1863 M_LST(s1, REG_ITMP1, 0);
1866 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1867 M_FST(s1, REG_ITMP1, 0);
1870 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1871 M_DST(s1, REG_ITMP1, 0);
1876 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1877 /* val = value (in current instruction) */
1878 /* following NOP) */
1880 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1881 uf = iptr->sx.s23.s3.uf;
1882 fieldtype = uf->fieldref->parseddesc.fd->type;
1883 disp = dseg_add_unique_address(cd, NULL);
1884 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1886 /* must be calculated before codegen_add_patch_ref */
1889 disp -= PATCHER_CALL_SIZE;
1891 /* PROFILE_CYCLE_STOP; */
1893 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1895 /* PROFILE_CYCLE_START; */
1898 fi = iptr->sx.s23.s3.fmiref->p.field;
1899 fieldtype = fi->type;
1900 disp = dseg_add_address(cd, &(fi->value));
1901 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1903 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1906 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1908 PROFILE_CYCLE_START;
1911 disp -= PATCHER_CALL_SIZE;
1915 /* This approach is much faster than moving the field
1916 address inline into a register. */
1918 M_ALD(REG_ITMP1, RIP, disp);
1920 switch (fieldtype) {
1923 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1928 if (IS_IMM32(iptr->sx.s23.s2.constval))
1929 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1931 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1932 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1938 case ICMD_GETFIELD: /* ... ==> ..., value */
1940 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1942 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1943 uf = iptr->sx.s23.s3.uf;
1944 fieldtype = uf->fieldref->parseddesc.fd->type;
1947 /* PROFILE_CYCLE_STOP; */
1949 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1951 /* PROFILE_CYCLE_START; */
1954 fi = iptr->sx.s23.s3.fmiref->p.field;
1955 fieldtype = fi->type;
1959 /* implicit null-pointer check */
1960 switch (fieldtype) {
1962 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1963 M_ILD32(d, s1, disp);
1967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1968 M_LLD32(d, s1, disp);
1971 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1972 M_FLD32(d, s1, disp);
1975 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1976 M_DLD32(d, s1, disp);
1979 emit_store_dst(jd, iptr, d);
1982 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1985 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1987 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1988 uf = iptr->sx.s23.s3.uf;
1989 fieldtype = uf->fieldref->parseddesc.fd->type;
1992 /* PROFILE_CYCLE_STOP; */
1994 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1996 /* PROFILE_CYCLE_START; */
1999 fi = iptr->sx.s23.s3.fmiref->p.field;
2000 fieldtype = fi->type;
2004 /* implicit null-pointer check */
2005 switch (fieldtype) {
2007 M_IST32(s2, s1, disp);
2011 M_LST32(s2, s1, disp);
2014 M_FST32(s2, s1, disp);
2017 M_DST32(s2, s1, disp);
2022 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2023 /* val = value (in current instruction) */
2024 /* following NOP) */
2026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2028 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2029 uf = iptr->sx.s23.s3.uf;
2030 fieldtype = uf->fieldref->parseddesc.fd->type;
2033 /* PROFILE_CYCLE_STOP; */
2035 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2037 /* PROFILE_CYCLE_START; */
2040 fi = iptr->sx.s23.s3.fmiref->p.field;
2041 fieldtype = fi->type;
2045 /* implicit null-pointer check */
2046 switch (fieldtype) {
2049 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2054 /* XXX why no check for IS_IMM32? */
2055 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2056 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2062 /* branch operations **************************************************/
2064 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2067 M_INTMOVE(s1, REG_ITMP1_XPTR);
2071 #ifdef ENABLE_VERIFIER
2072 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2073 uc = iptr->sx.s23.s2.uc;
2075 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2077 #endif /* ENABLE_VERIFIER */
2079 M_CALL_IMM(0); /* passing exception pc */
2080 M_POP(REG_ITMP2_XPC);
2082 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2086 case ICMD_GOTO: /* ... ==> ... */
2089 emit_br(cd, iptr->dst.block);
2093 case ICMD_JSR: /* ... ==> ... */
2095 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2099 case ICMD_IFNULL: /* ..., value ==> ... */
2100 case ICMD_IFNONNULL:
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2107 case ICMD_IFEQ: /* ..., value ==> ... */
2114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2115 M_ICMP_IMM(iptr->sx.val.i, s1);
2116 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2119 case ICMD_IF_LEQ: /* ..., value ==> ... */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 if (IS_IMM32(iptr->sx.val.l))
2128 M_LCMP_IMM(iptr->sx.val.l, s1);
2130 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2131 M_LCMP(REG_ITMP2, s1);
2133 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2136 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2137 case ICMD_IF_ICMPNE:
2138 case ICMD_IF_ICMPLT:
2139 case ICMD_IF_ICMPGE:
2140 case ICMD_IF_ICMPGT:
2141 case ICMD_IF_ICMPLE:
2143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2146 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2149 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2150 case ICMD_IF_ACMPNE:
2152 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2153 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2155 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2158 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2159 case ICMD_IF_LCMPNE:
2160 case ICMD_IF_LCMPLT:
2161 case ICMD_IF_LCMPGE:
2162 case ICMD_IF_LCMPGT:
2163 case ICMD_IF_LCMPLE:
2165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2166 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2168 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2171 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2174 REPLACEMENT_POINT_RETURN(cd, iptr);
2175 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2176 M_INTMOVE(s1, REG_RESULT);
2177 goto nowperformreturn;
2179 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2181 REPLACEMENT_POINT_RETURN(cd, iptr);
2182 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2183 M_INTMOVE(s1, REG_RESULT);
2185 #ifdef ENABLE_VERIFIER
2186 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2187 uc = iptr->sx.s23.s2.uc;
2191 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2193 PROFILE_CYCLE_START;
2195 #endif /* ENABLE_VERIFIER */
2196 goto nowperformreturn;
2198 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2201 REPLACEMENT_POINT_RETURN(cd, iptr);
2202 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2203 M_FLTMOVE(s1, REG_FRESULT);
2204 goto nowperformreturn;
2206 case ICMD_RETURN: /* ... ==> ... */
2208 REPLACEMENT_POINT_RETURN(cd, iptr);
2214 p = cd->stackframesize;
2216 #if !defined(NDEBUG)
2217 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2218 emit_verbosecall_exit(jd);
2219 #endif /* !defined(NDEBUG) */
2221 #if defined(ENABLE_THREADS)
2222 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2223 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2225 /* we need to save the proper return value */
2226 switch (iptr->opc) {
2230 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2234 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2238 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2241 /* and now restore the proper return value */
2242 switch (iptr->opc) {
2246 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2250 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2256 /* restore saved registers */
2258 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2259 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2261 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2262 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2265 /* deallocate stack */
2267 if (cd->stackframesize)
2268 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2270 /* generate method profiling code */
2279 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2282 branch_target_t *table;
2284 table = iptr->dst.table;
2286 l = iptr->sx.s23.s2.tablelow;
2287 i = iptr->sx.s23.s3.tablehigh;
2289 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2290 M_INTMOVE(s1, REG_ITMP1);
2293 M_ISUB_IMM(l, REG_ITMP1);
2295 /* number of targets */
2300 M_ICMP_IMM(i - 1, REG_ITMP1);
2301 emit_bugt(cd, table[0].block);
2303 /* build jump table top down and use address of lowest entry */
2308 dseg_add_target(cd, table->block);
2312 /* length of dataseg after last dseg_add_target is used
2315 M_MOV_IMM(0, REG_ITMP2);
2317 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2323 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2326 lookup_target_t *lookup;
2328 lookup = iptr->dst.lookup;
2330 i = iptr->sx.s23.s2.lookupcount;
2332 MCODECHECK(8 + ((7 + 6) * i) + 5);
2333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2336 M_ICMP_IMM(lookup->value, s1);
2337 emit_beq(cd, lookup->target.block);
2341 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2347 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2349 bte = iptr->sx.s23.s3.bte;
2353 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2355 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2356 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2357 case ICMD_INVOKEINTERFACE:
2359 REPLACEMENT_POINT_INVOKE(cd, iptr);
2361 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2363 um = iptr->sx.s23.s3.um;
2364 md = um->methodref->parseddesc.md;
2367 lm = iptr->sx.s23.s3.fmiref->p.method;
2369 md = lm->parseddesc;
2373 s3 = md->paramcount;
2375 MCODECHECK((20 * s3) + 128);
2377 /* copy arguments to registers or stack location */
2379 for (s3 = s3 - 1; s3 >= 0; s3--) {
2380 var = VAR(iptr->sx.s23.s2.args[s3]);
2381 d = md->params[s3].regoff;
2383 /* already preallocated (ARGVAR)? */
2385 if (var->flags & PREALLOC)
2388 if (IS_INT_LNG_TYPE(var->type)) {
2389 if (!md->params[s3].inmemory) {
2390 s1 = emit_load(jd, iptr, var, d);
2394 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2395 M_LST(s1, REG_SP, d * 8);
2399 if (!md->params[s3].inmemory) {
2400 s1 = emit_load(jd, iptr, var, d);
2404 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2406 if (IS_2_WORD_TYPE(var->type))
2407 M_DST(s1, REG_SP, d * 8);
2409 M_FST(s1, REG_SP, d * 8);
2414 /* generate method profiling code */
2418 switch (iptr->opc) {
2420 if (bte->stub == NULL) {
2421 M_MOV_IMM(bte->fp, REG_ITMP1);
2423 M_MOV_IMM(bte->stub, REG_ITMP1);
2427 emit_exception_check(cd, iptr);
2430 case ICMD_INVOKESPECIAL:
2431 emit_nullpointer_check(cd, iptr, REG_A0);
2434 case ICMD_INVOKESTATIC:
2436 disp = dseg_add_unique_address(cd, NULL);
2437 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2439 /* must be calculated before codegen_add_patch_ref */
2442 disp -= PATCHER_CALL_SIZE;
2444 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2450 disp = dseg_add_functionptr(cd, lm->stubroutine);
2451 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2453 /* a = (ptrint) lm->stubroutine; */
2456 /* M_MOV_IMM(a, REG_ITMP2); */
2457 M_ALD(REG_ITMP2, RIP, disp);
2461 case ICMD_INVOKEVIRTUAL:
2463 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2468 s1 = OFFSET(vftbl_t, table[0]) +
2469 sizeof(methodptr) * lm->vftblindex;
2472 /* implicit null-pointer check */
2473 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2474 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2478 case ICMD_INVOKEINTERFACE:
2480 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2486 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2487 sizeof(methodptr) * lm->class->index;
2489 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2492 /* implicit null-pointer check */
2493 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2494 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2495 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2500 /* generate method profiling code */
2502 PROFILE_CYCLE_START;
2504 /* store size of call code in replacement point */
2506 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2508 /* store return value */
2510 switch (md->returntype.type) {
2514 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2515 M_INTMOVE(REG_RESULT, s1);
2516 emit_store_dst(jd, iptr, s1);
2520 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2521 M_FLTMOVE(REG_FRESULT, s1);
2522 emit_store_dst(jd, iptr, s1);
2531 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2533 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2534 /* object type cast-check */
2537 vftbl_t *supervftbl;
2540 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2546 super = iptr->sx.s23.s3.c.cls;
2547 superindex = super->index;
2548 supervftbl = super->vftbl;
2551 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2552 CODEGEN_CRITICAL_SECTION_NEW;
2554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2556 /* if class is not resolved, check which code to call */
2558 if (super == NULL) {
2560 emit_label_beq(cd, BRANCH_LABEL_1);
2562 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2563 iptr->sx.s23.s3.c.ref, 0);
2565 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2566 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2567 emit_label_beq(cd, BRANCH_LABEL_2);
2570 /* interface checkcast code */
2572 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2573 if (super != NULL) {
2575 emit_label_beq(cd, BRANCH_LABEL_3);
2578 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2580 if (super == NULL) {
2581 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2582 iptr->sx.s23.s3.c.ref,
2587 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2588 M_ICMP_IMM32(superindex, REG_ITMP3);
2589 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2591 M_ALD32(REG_ITMP3, REG_ITMP2,
2592 OFFSET(vftbl_t, interfacetable[0]) -
2593 superindex * sizeof(methodptr*));
2595 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2598 emit_label_br(cd, BRANCH_LABEL_4);
2600 emit_label(cd, BRANCH_LABEL_3);
2603 /* class checkcast code */
2605 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2606 if (super == NULL) {
2607 emit_label(cd, BRANCH_LABEL_2);
2611 emit_label_beq(cd, BRANCH_LABEL_5);
2614 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2616 if (super == NULL) {
2617 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
2618 iptr->sx.s23.s3.c.ref,
2622 M_MOV_IMM(supervftbl, REG_ITMP3);
2624 CODEGEN_CRITICAL_SECTION_START;
2626 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2628 /* if (s1 != REG_ITMP1) { */
2629 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2630 /* OFFSET(vftbl_t, baseval), */
2632 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2633 /* OFFSET(vftbl_t, diffval), */
2635 /* #if defined(ENABLE_THREADS) */
2636 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2638 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2642 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2643 M_ISUB(REG_ITMP3, REG_ITMP2);
2644 M_MOV_IMM(supervftbl, REG_ITMP3);
2645 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2648 CODEGEN_CRITICAL_SECTION_END;
2650 M_ICMP(REG_ITMP3, REG_ITMP2);
2651 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2654 emit_label(cd, BRANCH_LABEL_5);
2657 if (super == NULL) {
2658 emit_label(cd, BRANCH_LABEL_1);
2659 emit_label(cd, BRANCH_LABEL_4);
2662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2665 /* array type cast-check */
2667 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2668 M_INTMOVE(s1, REG_A0);
2670 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2671 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2672 iptr->sx.s23.s3.c.ref, 0);
2675 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2676 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2679 /* s1 may have been destroyed over the function call */
2680 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2682 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2688 emit_store_dst(jd, iptr, d);
2691 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2695 vftbl_t *supervftbl;
2698 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2704 super = iptr->sx.s23.s3.c.cls;
2705 superindex = super->index;
2706 supervftbl = super->vftbl;
2709 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2710 CODEGEN_CRITICAL_SECTION_NEW;
2712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2716 M_INTMOVE(s1, REG_ITMP1);
2722 /* if class is not resolved, check which code to call */
2724 if (super == NULL) {
2726 emit_label_beq(cd, BRANCH_LABEL_1);
2728 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2729 iptr->sx.s23.s3.c.ref, 0);
2731 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2732 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2733 emit_label_beq(cd, BRANCH_LABEL_2);
2736 /* interface instanceof code */
2738 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2739 if (super != NULL) {
2741 emit_label_beq(cd, BRANCH_LABEL_3);
2744 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2746 if (super == NULL) {
2747 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2748 iptr->sx.s23.s3.c.ref, 0);
2752 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2753 M_ICMP_IMM32(superindex, REG_ITMP3);
2755 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2758 M_ALD32(REG_ITMP1, REG_ITMP1,
2759 OFFSET(vftbl_t, interfacetable[0]) -
2760 superindex * sizeof(methodptr*));
2765 emit_label_br(cd, BRANCH_LABEL_4);
2767 emit_label(cd, BRANCH_LABEL_3);
2770 /* class instanceof code */
2772 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2773 if (super == NULL) {
2774 emit_label(cd, BRANCH_LABEL_2);
2778 emit_label_beq(cd, BRANCH_LABEL_5);
2781 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2783 if (super == NULL) {
2784 codegen_add_patch_ref(cd, PATCHER_instanceof_class,
2785 iptr->sx.s23.s3.c.ref, 0);
2788 M_MOV_IMM(supervftbl, REG_ITMP2);
2790 CODEGEN_CRITICAL_SECTION_START;
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 CODEGEN_CRITICAL_SECTION_END;
2798 M_ISUB(REG_ITMP2, REG_ITMP1);
2799 M_CLR(d); /* may be REG_ITMP2 */
2800 M_ICMP(REG_ITMP3, REG_ITMP1);
2804 emit_label(cd, BRANCH_LABEL_5);
2807 if (super == NULL) {
2808 emit_label(cd, BRANCH_LABEL_1);
2809 emit_label(cd, BRANCH_LABEL_4);
2812 emit_store_dst(jd, iptr, d);
2816 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2818 /* check for negative sizes and copy sizes to stack if necessary */
2820 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2822 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2824 /* copy SAVEDVAR sizes to stack */
2825 var = VAR(iptr->sx.s23.s2.args[s1]);
2827 /* Already Preallocated? */
2828 if (!(var->flags & PREALLOC)) {
2829 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2830 M_LST(s2, REG_SP, s1 * 8);
2834 /* is a patcher function set? */
2836 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2837 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2838 iptr->sx.s23.s3.c.ref, 0);
2841 /* a0 = dimension count */
2843 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2845 /* a1 = classinfo */
2847 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2849 /* a2 = pointer to dimensions = stack pointer */
2851 M_MOV(REG_SP, REG_A2);
2853 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2856 /* check for exception before result assignment */
2858 emit_exception_check(cd, iptr);
2860 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2861 M_INTMOVE(REG_RESULT, s1);
2862 emit_store_dst(jd, iptr, s1);
2866 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2871 } /* for instruction */
2873 MCODECHECK(512); /* XXX require a lower number? */
2875 /* At the end of a basic block we may have to append some nops,
2876 because the patcher stub calling code might be longer than the
2877 actual instruction. So codepatching does not change the
2878 following block unintentionally. */
2880 if (cd->mcodeptr < cd->lastmcodeptr) {
2881 while (cd->mcodeptr < cd->lastmcodeptr) {
2886 } /* if (bptr -> flags >= BBREACHED) */
2887 } /* for basic block */
2889 dseg_createlinenumbertable(cd);
2891 /* generate stubs */
2893 emit_patcher_stubs(jd);
2894 REPLACEMENT_EMIT_STUBS(jd);
2896 /* everything's ok */
2902 /* codegen_emit_stub_compiler **************************************************
2904 Emit a stub routine which calls the compiler.
2906 *******************************************************************************/
2908 void codegen_emit_stub_compiler(jitdata *jd)
2913 /* get required compiler data */
2918 /* code for the stub */
2920 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
2921 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
2926 /* codegen_emit_stub_builtin ***************************************************
2928 Creates a stub routine which calls a builtin function.
2930 *******************************************************************************/
2932 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
2940 /* get required compiler data */
2947 /* calculate stack frame size */
2949 cd->stackframesize =
2950 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2951 1; /* return value */
2953 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
2955 /* create method header */
2957 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2958 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2959 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2960 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2961 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2962 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2963 (void) dseg_addlinenumbertablesize(cd);
2964 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2966 /* generate stub code */
2968 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2970 #if defined(ENABLE_GC_CACAO)
2971 /* Save callee saved integer registers in stackframeinfo (GC may
2972 need to recover them during a collection). */
2974 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
2975 OFFSET(stackframeinfo, intregs);
2977 for (i = 0; i < INT_SAV_CNT; i++)
2978 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2981 /* save integer and float argument registers */
2983 for (i = 0, j = 0; i < md->paramcount; i++) {
2984 if (!md->params[i].inmemory) {
2985 s1 = md->params[i].regoff;
2987 switch (md->paramtypes[i].type) {
2991 M_LST(s1, REG_SP, j * 8);
2995 M_DST(s1, REG_SP, j * 8);
3003 /* create dynamic stack info */
3005 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3006 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3007 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3008 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3009 M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
3012 /* restore integer and float argument registers */
3014 for (i = 0, j = 0; i < md->paramcount; i++) {
3015 if (!md->params[i].inmemory) {
3016 s1 = md->params[i].regoff;
3018 switch (md->paramtypes[i].type) {
3022 M_LLD(s1, REG_SP, j * 8);
3026 M_DLD(s1, REG_SP, j * 8);
3034 /* call the builtin function */
3036 M_MOV_IMM(bte->fp, REG_ITMP3);
3039 /* save return value */
3041 switch (md->returntype.type) {
3045 M_LST(REG_RESULT, REG_SP, 0 * 8);
3049 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3055 /* remove native stackframe info */
3057 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3058 M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
3061 /* restore return value */
3063 switch (md->returntype.type) {
3067 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3071 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3077 #if defined(ENABLE_GC_CACAO)
3078 /* Restore callee saved integer registers from stackframeinfo (GC
3079 might have modified them during a collection). */
3081 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3082 OFFSET(stackframeinfo, intregs);
3084 for (i = 0; i < INT_SAV_CNT; i++)
3085 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3088 /* remove stackframe */
3090 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3095 /* codegen_emit_stub_native ****************************************************
3097 Emits a stub routine which calls a native method.
3099 *******************************************************************************/
3101 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3112 /* get required compiler data */
3118 /* initialize variables */
3121 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3123 /* calculate stack frame size */
3125 cd->stackframesize =
3126 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3127 sizeof(localref_table) / SIZEOF_VOID_P +
3129 1 + /* functionptr, TODO: store in data segment */
3132 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3134 /* create method header */
3136 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3137 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3138 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3139 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3140 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3141 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3142 (void) dseg_addlinenumbertablesize(cd);
3143 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3145 #if defined(ENABLE_PROFILING)
3146 /* generate native method profiling code */
3148 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3149 /* count frequency */
3151 M_MOV_IMM(code, REG_ITMP3);
3152 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3156 /* generate stub code */
3158 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3160 #if !defined(NDEBUG)
3161 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3162 emit_verbosecall_enter(jd);
3165 /* get function address (this must happen before the stackframeinfo) */
3167 #if !defined(WITH_STATIC_CLASSPATH)
3169 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3172 M_MOV_IMM(f, REG_ITMP3);
3174 #if defined(ENABLE_GC_CACAO)
3175 /* Save callee saved integer registers in stackframeinfo (GC may
3176 need to recover them during a collection). */
3178 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3179 OFFSET(stackframeinfo, intregs);
3181 for (i = 0; i < INT_SAV_CNT; i++)
3182 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3185 /* save integer and float argument registers */
3187 for (i = 0; i < md->paramcount; i++) {
3188 if (!md->params[i].inmemory) {
3189 s1 = md->params[i].regoff;
3191 switch (md->paramtypes[i].type) {
3195 M_LST(s1, REG_SP, i * 8);
3199 M_DST(s1, REG_SP, i * 8);
3205 M_AST(REG_ITMP3, REG_SP, md->paramcount * 8);
3207 /* create dynamic stack info */
3209 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3210 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3211 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3212 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3213 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3216 /* restore integer and float argument registers */
3218 for (i = 0; i < md->paramcount; i++) {
3219 if (!md->params[i].inmemory) {
3220 s1 = md->params[i].regoff;
3222 switch (md->paramtypes[i].type) {
3226 M_LLD(s1, REG_SP, i * 8);
3230 M_DLD(s1, REG_SP, i * 8);
3236 M_ALD(REG_ITMP3, REG_SP, md->paramcount * 8);
3238 /* copy or spill arguments to new locations */
3240 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3241 t = md->paramtypes[i].type;
3242 s2 = nmd->params[j].regoff;
3244 if (IS_INT_LNG_TYPE(t)) {
3245 if (!md->params[i].inmemory) {
3246 s1 = md->params[i].regoff;
3248 if (!nmd->params[j].inmemory)
3251 M_LST(s1, REG_SP, s2 * 8);
3254 s1 = md->params[i].regoff + cd->stackframesize + 1;/* +1 (RA) */
3255 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3256 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3260 /* We only copy spilled float arguments, as the float
3261 argument registers keep unchanged. */
3263 if (md->params[i].inmemory) {
3264 s1 = md->params[i].regoff + cd->stackframesize + 1;/* +1 (RA) */
3266 if (IS_2_WORD_TYPE(t)) {
3267 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3268 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3271 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3272 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3278 /* put class into second argument register */
3280 if (m->flags & ACC_STATIC)
3281 M_MOV_IMM(m->class, REG_A1);
3283 /* put env into first argument register */
3285 M_MOV_IMM(_Jv_env, REG_A0);
3287 /* do the native function call */
3291 /* save return value */
3293 switch (md->returntype.type) {
3297 M_LST(REG_RESULT, REG_SP, 0 * 8);
3301 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3307 #if !defined(NDEBUG)
3308 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3309 emit_verbosecall_exit(jd);
3312 /* remove native stackframe info */
3314 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3315 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3317 M_MOV(REG_RESULT, REG_ITMP3);
3319 /* restore return value */
3321 switch (md->returntype.type) {
3325 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3329 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3335 #if defined(ENABLE_GC_CACAO)
3336 /* Restore callee saved integer registers from stackframeinfo (GC
3337 might have modified them during a collection). */
3339 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3340 OFFSET(stackframeinfo, intregs);
3342 for (i = 0; i < INT_SAV_CNT; i++)
3343 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3346 /* remove stackframe */
3348 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3350 /* test for exception */
3356 /* handle exception */
3358 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3359 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3360 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3362 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3365 /* generate patcher stubs */
3367 emit_patcher_stubs(jd);
3372 * These are local overrides for various environment variables in Emacs.
3373 * Please do not remove this and leave it at the end of the file, where
3374 * Emacs will automagically detect them.
3375 * ---------------------------------------------------------------------
3378 * indent-tabs-mode: t
3382 * vim:noexpandtab:sw=4:ts=4: