1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "vm/jit/x86_64/arch.h"
38 #include "vm/jit/x86_64/codegen.h"
39 #include "vm/jit/x86_64/emit.h"
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/localref.h"
45 #include "native/native.h"
47 #include "threads/lock-common.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit/abi.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen-common.h"
58 #include "vm/jit/dseg.h"
59 #include "vm/jit/emit-common.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/methodheader.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher-common.h"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.h"
66 #include "vm/jit/stacktrace.h"
68 #if defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
72 #include "vmcore/loader.h"
73 #include "vmcore/options.h"
74 #include "vmcore/statistics.h"
77 /* codegen_emit ****************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen_emit(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
96 constant_classref *cr;
98 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
99 unresolved_method *um;
100 builtintable_entry *bte;
103 unresolved_field *uf;
107 /* get required compiler data */
114 /* prevent compiler warnings */
127 /* space to save used callee saved registers */
129 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
130 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
132 cd->stackframesize = rd->memuse + savedregs_num;
134 #if defined(ENABLE_THREADS)
135 /* space to save argument of monitor_enter */
137 if (checksync && (m->flags & ACC_SYNCHRONIZED))
138 cd->stackframesize++;
141 /* Keep stack of non-leaf functions 16-byte aligned for calls into
142 native code e.g. libc or jni (alignment problems with
145 if (!jd->isleafmethod || opt_verbosecall)
146 cd->stackframesize |= 0x1;
148 /* create method header */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
166 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
167 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
168 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 (void) dseg_addlinenumbertablesize(cd);
172 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_add_target(cd, ex->start);
178 dseg_add_target(cd, ex->end);
179 dseg_add_target(cd, ex->handler);
180 (void) dseg_add_unique_address(cd, ex->catchtype.any);
183 #if defined(ENABLE_PROFILING)
184 /* generate method profiling code */
186 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
187 /* count frequency */
189 M_MOV_IMM(code, REG_ITMP3);
190 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
196 /* create stack frame (if necessary) */
198 if (cd->stackframesize)
199 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
201 /* save used callee saved registers */
203 p = cd->stackframesize;
204 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
205 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
207 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
208 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
211 /* take arguments out of register or stack frame */
215 for (p = 0, l = 0; p < md->paramcount; p++) {
216 t = md->paramtypes[p].type;
218 varindex = jd->local_map[l * 5 + t];
221 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
224 if (varindex == UNUSED)
229 s1 = md->params[p].regoff;
231 if (IS_INT_LNG_TYPE(t)) { /* integer args */
232 if (!md->params[p].inmemory) { /* register arguments */
233 if (!IS_INMEMORY(var->flags))
234 M_INTMOVE(s1, var->vv.regoff);
236 M_LST(s1, REG_SP, var->vv.regoff);
238 else { /* stack arguments */
239 if (!IS_INMEMORY(var->flags))
240 /* + 8 for return address */
241 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
243 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
246 else { /* floating args */
247 if (!md->params[p].inmemory) { /* register arguments */
248 if (!IS_INMEMORY(var->flags))
249 M_FLTMOVE(s1, var->vv.regoff);
251 M_DST(s1, REG_SP, var->vv.regoff);
253 else { /* stack arguments */
254 if (!IS_INMEMORY(var->flags))
255 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
257 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
262 /* save monitorenter argument */
264 #if defined(ENABLE_THREADS)
265 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
266 /* stack offset for monitor argument */
270 if (opt_verbosecall) {
271 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
273 for (p = 0; p < INT_ARG_CNT; p++)
274 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
276 for (p = 0; p < FLT_ARG_CNT; p++)
277 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
279 s1 += INT_ARG_CNT + FLT_ARG_CNT;
282 /* decide which monitor enter function to call */
284 if (m->flags & ACC_STATIC) {
285 M_MOV_IMM(&m->class->object.header, REG_A0);
290 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
293 M_AST(REG_A0, REG_SP, s1 * 8);
294 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
297 if (opt_verbosecall) {
298 for (p = 0; p < INT_ARG_CNT; p++)
299 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
301 for (p = 0; p < FLT_ARG_CNT; p++)
302 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
304 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
310 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
311 emit_verbosecall_enter(jd);
312 #endif /* !defined(NDEBUG) */
316 /* end of header generation */
318 /* create replacement points */
320 REPLACEMENT_POINTS_INIT(cd, jd);
322 /* walk through all basic blocks */
324 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
326 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
328 if (bptr->flags >= BBREACHED) {
330 /* branch resolving */
332 codegen_resolve_branchrefs(cd, bptr);
334 /* handle replacement points */
336 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
338 /* copy interface registers to their destination */
343 #if defined(ENABLE_PROFILING)
344 /* generate basicblock profiling code */
346 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
347 /* count frequency */
349 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
350 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
352 /* if this is an exception handler, start profiling again */
354 if (bptr->type == BBTYPE_EXH)
359 #if defined(ENABLE_LSRA)
363 src = bptr->invars[len];
364 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
365 if (bptr->type == BBTYPE_EXH) {
366 /* d = reg_of_var(rd, src, REG_ITMP1); */
367 if (!IS_INMEMORY(src->flags))
371 M_INTMOVE(REG_ITMP1, d);
372 emit_store(jd, NULL, src, d);
382 var = VAR(bptr->invars[len]);
383 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
384 if (bptr->type == BBTYPE_EXH) {
385 d = codegen_reg_of_var(0, var, REG_ITMP1);
386 M_INTMOVE(REG_ITMP1, d);
387 emit_store(jd, NULL, var, d);
391 assert((var->flags & INOUT));
394 #if defined(ENABLE_LSRA)
397 /* walk through all instructions */
402 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
403 if (iptr->line != currentline) {
404 dseg_addlinenumber(cd, iptr->line);
405 currentline = iptr->line;
408 MCODECHECK(1024); /* 1KB should be enough */
411 case ICMD_NOP: /* ... ==> ... */
412 case ICMD_POP: /* ..., value ==> ... */
413 case ICMD_POP2: /* ..., value, value ==> ... */
416 case ICMD_INLINE_START:
418 REPLACEMENT_POINT_INLINE_START(cd, iptr);
421 case ICMD_INLINE_BODY:
423 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
424 dseg_addlinenumber_inline_start(cd, iptr);
425 dseg_addlinenumber(cd, iptr->line);
428 case ICMD_INLINE_END:
430 dseg_addlinenumber_inline_end(cd, iptr);
431 dseg_addlinenumber(cd, iptr->line);
434 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
437 emit_nullpointer_check(cd, iptr, s1);
440 /* constant operations ************************************************/
442 case ICMD_ICONST: /* ... ==> ..., constant */
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
445 ICONST(d, iptr->sx.val.i);
446 emit_store_dst(jd, iptr, d);
449 case ICMD_LCONST: /* ... ==> ..., constant */
451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
452 LCONST(d, iptr->sx.val.l);
453 emit_store_dst(jd, iptr, d);
456 case ICMD_FCONST: /* ... ==> ..., constant */
458 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
459 disp = dseg_add_float(cd, iptr->sx.val.f);
460 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
461 emit_store_dst(jd, iptr, d);
464 case ICMD_DCONST: /* ... ==> ..., constant */
466 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
467 disp = dseg_add_double(cd, iptr->sx.val.d);
468 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
469 emit_store_dst(jd, iptr, d);
472 case ICMD_ACONST: /* ... ==> ..., constant */
474 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
476 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
477 cr = iptr->sx.val.c.ref;
478 disp = dseg_add_unique_address(cd, cr);
480 /* PROFILE_CYCLE_STOP; */
482 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
485 /* PROFILE_CYCLE_START; */
490 if (iptr->sx.val.anyptr == 0) {
494 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
498 emit_store_dst(jd, iptr, d);
502 /* load/store/copy/move operations ************************************/
504 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
505 case ICMD_ALOAD: /* s1 = local variable */
509 case ICMD_ISTORE: /* ..., value ==> ... */
520 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
524 /* integer operations *************************************************/
526 case ICMD_INEG: /* ..., value ==> ..., - value */
528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
529 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
532 emit_store_dst(jd, iptr, d);
535 case ICMD_LNEG: /* ..., value ==> ..., - value */
537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
541 emit_store_dst(jd, iptr, d);
544 case ICMD_I2L: /* ..., value ==> ..., value */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_L2I: /* ..., value ==> ..., value */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
557 emit_store_dst(jd, iptr, d);
560 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
573 emit_store_dst(jd, iptr, d);
576 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
581 emit_store_dst(jd, iptr, d);
585 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596 emit_store_dst(jd, iptr, d);
600 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
601 /* sx.val.i = constant */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
606 /* Using inc and dec is not faster than add (tested with
610 M_IADD_IMM(iptr->sx.val.i, d);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 emit_store_dst(jd, iptr, d);
628 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
629 /* sx.val.l = constant */
631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
634 if (IS_IMM32(iptr->sx.val.l))
635 M_LADD_IMM(iptr->sx.val.l, d);
637 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
638 M_LADD(REG_ITMP2, d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649 M_INTMOVE(s1, REG_ITMP1);
650 M_ISUB(s2, REG_ITMP1);
651 M_INTMOVE(REG_ITMP1, d);
656 emit_store_dst(jd, iptr, d);
659 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
660 /* sx.val.i = constant */
662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
665 M_ISUB_IMM(iptr->sx.val.i, d);
666 emit_store_dst(jd, iptr, d);
669 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
675 M_INTMOVE(s1, REG_ITMP1);
676 M_LSUB(s2, REG_ITMP1);
677 M_INTMOVE(REG_ITMP1, d);
682 emit_store_dst(jd, iptr, d);
685 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
686 /* sx.val.l = constant */
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
691 if (IS_IMM32(iptr->sx.val.l))
692 M_LSUB_IMM(iptr->sx.val.l, d);
694 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
695 M_LSUB(REG_ITMP2, d);
697 emit_store_dst(jd, iptr, d);
700 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
711 emit_store_dst(jd, iptr, d);
714 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
715 /* sx.val.i = constant */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
719 if (iptr->sx.val.i == 2) {
723 M_IMUL_IMM(s1, iptr->sx.val.i, d);
724 emit_store_dst(jd, iptr, d);
727 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
738 emit_store_dst(jd, iptr, d);
741 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
742 /* sx.val.l = constant */
744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
745 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
746 if (IS_IMM32(iptr->sx.val.l))
747 M_LMUL_IMM(s1, iptr->sx.val.l, d);
749 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
751 M_LMUL(REG_ITMP2, d);
753 emit_store_dst(jd, iptr, d);
756 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
758 s1 = emit_load_s1(jd, iptr, RAX);
759 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
760 d = codegen_reg_of_dst(jd, iptr, RAX);
763 M_INTMOVE(s2, REG_ITMP3);
764 emit_arithmetic_check(cd, iptr, REG_ITMP3);
766 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
768 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
770 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
771 M_BEQ(1 + 3); /* 6 bytes */
773 emit_cltd(cd); /* 1 byte */
774 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
777 emit_store_dst(jd, iptr, d);
778 dst = VAROP(iptr->dst);
779 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
780 M_MOV(REG_ITMP2, RDX); /* restore RDX */
783 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
785 s1 = emit_load_s1(jd, iptr, RAX);
786 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
787 d = codegen_reg_of_dst(jd, iptr, RDX);
790 M_INTMOVE(s2, REG_ITMP3);
791 emit_arithmetic_check(cd, iptr, REG_ITMP3);
793 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
795 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
797 M_CLR(RDX); /* 3 bytes */
798 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
799 M_BEQ(1 + 3); /* 6 bytes */
801 emit_cltd(cd); /* 1 byte */
802 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
805 emit_store_dst(jd, iptr, d);
806 dst = VAROP(iptr->dst);
807 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
808 M_MOV(REG_ITMP2, RDX); /* restore RDX */
811 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
812 /* sx.val.i = constant */
814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
816 M_INTMOVE(s1, REG_ITMP1);
817 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
818 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
819 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
820 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
821 emit_mov_reg_reg(cd, REG_ITMP1, d);
822 emit_store_dst(jd, iptr, d);
825 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
826 /* sx.val.i = constant */
828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
830 M_INTMOVE(s1, REG_ITMP1);
831 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
832 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
833 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
834 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
835 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
836 emit_mov_reg_reg(cd, REG_ITMP1, d);
837 emit_store_dst(jd, iptr, d);
841 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
843 s1 = emit_load_s1(jd, iptr, RAX);
844 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
845 d = codegen_reg_of_dst(jd, iptr, RAX);
848 M_INTMOVE(s2, REG_ITMP3);
849 emit_arithmetic_check(cd, iptr, REG_ITMP3);
851 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
853 /* check as described in jvm spec */
854 disp = dseg_add_s8(cd, 0x8000000000000000LL);
855 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
857 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
858 M_BEQ(2 + 3); /* 6 bytes */
860 emit_cqto(cd); /* 2 bytes */
861 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
864 emit_store_dst(jd, iptr, d);
865 dst = VAROP(iptr->dst);
866 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
867 M_MOV(REG_ITMP2, RDX); /* restore RDX */
870 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
872 s1 = emit_load_s1(jd, iptr, RAX);
873 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
874 d = codegen_reg_of_dst(jd, iptr, RDX);
877 M_INTMOVE(s2, REG_ITMP3);
878 emit_arithmetic_check(cd, iptr, REG_ITMP3);
880 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
882 /* check as described in jvm spec */
883 disp = dseg_add_s8(cd, 0x8000000000000000LL);
884 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
886 M_LXOR(RDX, RDX); /* 3 bytes */
887 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
888 M_BEQ(2 + 3); /* 6 bytes */
890 emit_cqto(cd); /* 2 bytes */
891 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
894 emit_store_dst(jd, iptr, d);
895 dst = VAROP(iptr->dst);
896 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
897 M_MOV(REG_ITMP2, RDX); /* restore RDX */
900 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
901 /* sx.val.i = constant */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
905 M_INTMOVE(s1, REG_ITMP1);
906 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
907 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
908 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
909 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
910 emit_mov_reg_reg(cd, REG_ITMP1, d);
911 emit_store_dst(jd, iptr, d);
914 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
915 /* sx.val.l = constant */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
919 M_INTMOVE(s1, REG_ITMP1);
920 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
921 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
922 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
923 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
924 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
925 emit_mov_reg_reg(cd, REG_ITMP1, d);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
931 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
932 emit_ishift(jd, SHIFT_SHL, iptr);
935 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
936 /* sx.val.i = constant */
938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
939 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
941 M_ISLL_IMM(iptr->sx.val.i, d);
942 emit_store_dst(jd, iptr, d);
945 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
947 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
948 emit_ishift(jd, SHIFT_SAR, iptr);
951 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
952 /* sx.val.i = constant */
954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
955 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
957 M_ISRA_IMM(iptr->sx.val.i, d);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
963 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
964 emit_ishift(jd, SHIFT_SHR, iptr);
967 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
968 /* sx.val.i = constant */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973 M_ISRL_IMM(iptr->sx.val.i, d);
974 emit_store_dst(jd, iptr, d);
977 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
979 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
980 emit_lshift(jd, SHIFT_SHL, iptr);
983 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
984 /* sx.val.i = constant */
986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
987 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
989 M_LSLL_IMM(iptr->sx.val.i, d);
990 emit_store_dst(jd, iptr, d);
993 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
995 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
996 emit_lshift(jd, SHIFT_SAR, iptr);
999 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1000 /* sx.val.i = constant */
1002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1005 M_LSRA_IMM(iptr->sx.val.i, d);
1006 emit_store_dst(jd, iptr, d);
1009 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1011 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1012 emit_lshift(jd, SHIFT_SHR, iptr);
1015 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1016 /* sx.val.l = constant */
1018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1019 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021 M_LSRL_IMM(iptr->sx.val.i, d);
1022 emit_store_dst(jd, iptr, d);
1025 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1028 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1029 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1036 emit_store_dst(jd, iptr, d);
1039 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1040 /* sx.val.i = constant */
1042 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1043 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1045 M_IAND_IMM(iptr->sx.val.i, d);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1052 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1064 /* sx.val.l = constant */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1069 if (IS_IMM32(iptr->sx.val.l))
1070 M_LAND_IMM(iptr->sx.val.l, d);
1072 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1073 M_LAND(REG_ITMP2, d);
1075 emit_store_dst(jd, iptr, d);
1078 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1081 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089 emit_store_dst(jd, iptr, d);
1092 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1093 /* sx.val.i = constant */
1095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1096 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1098 M_IOR_IMM(iptr->sx.val.i, d);
1099 emit_store_dst(jd, iptr, d);
1102 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1106 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1117 /* sx.val.l = constant */
1119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1120 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1122 if (IS_IMM32(iptr->sx.val.l))
1123 M_LOR_IMM(iptr->sx.val.l, d);
1125 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1126 M_LOR(REG_ITMP2, d);
1128 emit_store_dst(jd, iptr, d);
1131 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1134 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1146 /* sx.val.i = constant */
1148 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1149 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1151 M_IXOR_IMM(iptr->sx.val.i, d);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1158 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1159 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1166 emit_store_dst(jd, iptr, d);
1169 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1170 /* sx.val.l = constant */
1172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1173 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1175 if (IS_IMM32(iptr->sx.val.l))
1176 M_LXOR_IMM(iptr->sx.val.l, d);
1178 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1179 M_LXOR(REG_ITMP2, d);
1181 emit_store_dst(jd, iptr, d);
1185 /* floating operations ************************************************/
1187 case ICMD_FNEG: /* ..., value ==> ..., - value */
1189 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1190 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1191 disp = dseg_add_s4(cd, 0x80000000);
1193 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1194 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1195 emit_store_dst(jd, iptr, d);
1198 case ICMD_DNEG: /* ..., value ==> ..., - value */
1200 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1201 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1202 disp = dseg_add_s8(cd, 0x8000000000000000);
1204 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1205 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1206 emit_store_dst(jd, iptr, d);
1209 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1211 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1212 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1213 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1220 emit_store_dst(jd, iptr, d);
1223 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1225 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1226 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1227 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1234 emit_store_dst(jd, iptr, d);
1237 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1239 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1240 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1241 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1243 M_FLTMOVE(s2, REG_FTMP2);
1248 emit_store_dst(jd, iptr, d);
1251 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1253 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1254 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1255 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1257 M_FLTMOVE(s2, REG_FTMP2);
1262 emit_store_dst(jd, iptr, d);
1265 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1267 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1268 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1269 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1276 emit_store_dst(jd, iptr, d);
1279 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1281 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1282 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1283 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1290 emit_store_dst(jd, iptr, d);
1293 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1295 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1296 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1297 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1299 M_FLTMOVE(s2, REG_FTMP2);
1304 emit_store_dst(jd, iptr, d);
1307 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1309 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1310 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1311 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1313 M_FLTMOVE(s2, REG_FTMP2);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1326 emit_store_dst(jd, iptr, d);
1329 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1331 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1332 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1340 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1348 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1350 emit_store_dst(jd, iptr, d);
1353 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1355 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1356 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1358 M_ICMP_IMM(0x80000000, d); /* corner cases */
1359 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1360 ((REG_RESULT == d) ? 0 : 3);
1362 M_FLTMOVE(s1, REG_FTMP1);
1363 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1365 M_INTMOVE(REG_RESULT, d);
1366 emit_store_dst(jd, iptr, d);
1369 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1371 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1374 M_ICMP_IMM(0x80000000, d); /* corner cases */
1375 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1376 ((REG_RESULT == d) ? 0 : 3);
1378 M_FLTMOVE(s1, REG_FTMP1);
1379 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1381 M_INTMOVE(REG_RESULT, d);
1382 emit_store_dst(jd, iptr, d);
1385 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1387 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1390 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1391 M_LCMP(REG_ITMP2, d); /* corner cases */
1392 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1393 ((REG_RESULT == d) ? 0 : 3);
1395 M_FLTMOVE(s1, REG_FTMP1);
1396 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1398 M_INTMOVE(REG_RESULT, d);
1399 emit_store_dst(jd, iptr, d);
1402 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1404 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1407 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1408 M_LCMP(REG_ITMP2, d); /* corner cases */
1409 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1410 ((REG_RESULT == d) ? 0 : 3);
1412 M_FLTMOVE(s1, REG_FTMP1);
1413 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1415 M_INTMOVE(REG_RESULT, d);
1416 emit_store_dst(jd, iptr, d);
1419 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1421 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1422 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1424 emit_store_dst(jd, iptr, d);
1427 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1429 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1430 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1432 emit_store_dst(jd, iptr, d);
1435 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1436 /* == => 0, < => 1, > => -1 */
1438 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1440 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1442 M_MOV_IMM(1, REG_ITMP1);
1443 M_MOV_IMM(-1, REG_ITMP2);
1444 emit_ucomiss_reg_reg(cd, s1, s2);
1445 M_CMOVULT(REG_ITMP1, d);
1446 M_CMOVUGT(REG_ITMP2, d);
1447 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1452 /* == => 0, < => 1, > => -1 */
1454 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1455 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1458 M_MOV_IMM(1, REG_ITMP1);
1459 M_MOV_IMM(-1, REG_ITMP2);
1460 emit_ucomiss_reg_reg(cd, s1, s2);
1461 M_CMOVULT(REG_ITMP1, d);
1462 M_CMOVUGT(REG_ITMP2, d);
1463 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1464 emit_store_dst(jd, iptr, d);
1467 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1468 /* == => 0, < => 1, > => -1 */
1470 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1472 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1474 M_MOV_IMM(1, REG_ITMP1);
1475 M_MOV_IMM(-1, REG_ITMP2);
1476 emit_ucomisd_reg_reg(cd, s1, s2);
1477 M_CMOVULT(REG_ITMP1, d);
1478 M_CMOVUGT(REG_ITMP2, d);
1479 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1480 emit_store_dst(jd, iptr, d);
1483 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1484 /* == => 0, < => 1, > => -1 */
1486 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1490 M_MOV_IMM(1, REG_ITMP1);
1491 M_MOV_IMM(-1, REG_ITMP2);
1492 emit_ucomisd_reg_reg(cd, s1, s2);
1493 M_CMOVULT(REG_ITMP1, d);
1494 M_CMOVUGT(REG_ITMP2, d);
1495 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1496 emit_store_dst(jd, iptr, d);
1500 /* memory operations **************************************************/
1502 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1505 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1506 /* implicit null-pointer check */
1507 M_ILD(d, s1, OFFSET(java_array_t, size));
1508 emit_store_dst(jd, iptr, d);
1511 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1516 /* implicit null-pointer check */
1517 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1518 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1519 emit_store_dst(jd, iptr, d);
1522 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1525 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1527 /* implicit null-pointer check */
1528 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1529 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1530 emit_store_dst(jd, iptr, d);
1533 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1536 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1538 /* implicit null-pointer check */
1539 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1540 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1541 emit_store_dst(jd, iptr, d);
1544 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1549 /* implicit null-pointer check */
1550 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1551 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1552 emit_store_dst(jd, iptr, d);
1555 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1558 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1560 /* implicit null-pointer check */
1561 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1562 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1563 emit_store_dst(jd, iptr, d);
1566 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1570 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1571 /* implicit null-pointer check */
1572 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1573 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1574 emit_store_dst(jd, iptr, d);
1577 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1580 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1581 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1582 /* implicit null-pointer check */
1583 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1584 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1585 emit_store_dst(jd, iptr, d);
1588 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1591 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1593 /* implicit null-pointer check */
1594 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1595 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1596 emit_store_dst(jd, iptr, d);
1600 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1603 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1604 /* implicit null-pointer check */
1605 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1606 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1607 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1610 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1614 /* implicit null-pointer check */
1615 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1616 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1617 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1620 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1624 /* implicit null-pointer check */
1625 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1626 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1627 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1630 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1634 /* implicit null-pointer check */
1635 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1636 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1637 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1640 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1643 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1644 /* implicit null-pointer check */
1645 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1646 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1647 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1650 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1654 /* implicit null-pointer check */
1655 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1656 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1657 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1660 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1663 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1664 /* implicit null-pointer check */
1665 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1666 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1667 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1670 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1674 /* implicit null-pointer check */
1675 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1676 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1680 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1682 emit_arraystore_check(cd, iptr);
1684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1686 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1687 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1691 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1695 /* implicit null-pointer check */
1696 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1697 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1700 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1704 /* implicit null-pointer check */
1705 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1706 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1709 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1713 /* implicit null-pointer check */
1714 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1715 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1718 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1722 /* implicit null-pointer check */
1723 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1724 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1727 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1731 /* implicit null-pointer check */
1732 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1734 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1735 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1738 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1739 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1743 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1746 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1747 /* implicit null-pointer check */
1748 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1749 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1753 case ICMD_GETSTATIC: /* ... ==> ..., value */
1755 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1756 uf = iptr->sx.s23.s3.uf;
1757 fieldtype = uf->fieldref->parseddesc.fd->type;
1758 disp = dseg_add_unique_address(cd, uf);
1760 /* PROFILE_CYCLE_STOP; */
1762 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1764 /* PROFILE_CYCLE_START; */
1767 fi = iptr->sx.s23.s3.fmiref->p.field;
1768 fieldtype = fi->type;
1769 disp = dseg_add_address(cd, fi->value);
1771 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1774 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1777 PROFILE_CYCLE_START;
1781 /* This approach is much faster than moving the field
1782 address inline into a register. */
1784 M_ALD(REG_ITMP1, RIP, disp);
1786 switch (fieldtype) {
1788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1789 M_ILD(d, REG_ITMP1, 0);
1793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1794 M_LLD(d, REG_ITMP1, 0);
1797 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1798 M_FLD(d, REG_ITMP1, 0);
1801 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1802 M_DLD(d, REG_ITMP1, 0);
1805 emit_store_dst(jd, iptr, d);
1808 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1810 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1811 uf = iptr->sx.s23.s3.uf;
1812 fieldtype = uf->fieldref->parseddesc.fd->type;
1813 disp = dseg_add_unique_address(cd, uf);
1815 /* PROFILE_CYCLE_STOP; */
1817 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1819 /* PROFILE_CYCLE_START; */
1822 fi = iptr->sx.s23.s3.fmiref->p.field;
1823 fieldtype = fi->type;
1824 disp = dseg_add_address(cd, fi->value);
1826 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1829 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1832 PROFILE_CYCLE_START;
1836 /* This approach is much faster than moving the field
1837 address inline into a register. */
1839 M_ALD(REG_ITMP1, RIP, disp);
1841 switch (fieldtype) {
1843 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1844 M_IST(s1, REG_ITMP1, 0);
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1849 M_LST(s1, REG_ITMP1, 0);
1852 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1853 M_FST(s1, REG_ITMP1, 0);
1856 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1857 M_DST(s1, REG_ITMP1, 0);
1862 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1863 /* val = value (in current instruction) */
1864 /* following NOP) */
1866 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1867 uf = iptr->sx.s23.s3.uf;
1868 fieldtype = uf->fieldref->parseddesc.fd->type;
1869 disp = dseg_add_unique_address(cd, uf);
1871 /* PROFILE_CYCLE_STOP; */
1873 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1875 /* PROFILE_CYCLE_START; */
1878 fi = iptr->sx.s23.s3.fmiref->p.field;
1879 fieldtype = fi->type;
1880 disp = dseg_add_address(cd, fi->value);
1882 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1885 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1888 PROFILE_CYCLE_START;
1892 /* This approach is much faster than moving the field
1893 address inline into a register. */
1895 M_ALD(REG_ITMP1, RIP, disp);
1897 switch (fieldtype) {
1900 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1905 if (IS_IMM32(iptr->sx.s23.s2.constval))
1906 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1908 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1909 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1915 case ICMD_GETFIELD: /* ... ==> ..., value */
1917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1920 uf = iptr->sx.s23.s3.uf;
1921 fieldtype = uf->fieldref->parseddesc.fd->type;
1924 /* PROFILE_CYCLE_STOP; */
1926 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1928 /* PROFILE_CYCLE_START; */
1931 fi = iptr->sx.s23.s3.fmiref->p.field;
1932 fieldtype = fi->type;
1936 /* implicit null-pointer check */
1937 switch (fieldtype) {
1939 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1940 M_ILD32(d, s1, disp);
1944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1945 M_LLD32(d, s1, disp);
1948 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1949 M_FLD32(d, s1, disp);
1952 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1953 M_DLD32(d, s1, disp);
1956 emit_store_dst(jd, iptr, d);
1959 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1962 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1964 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1965 uf = iptr->sx.s23.s3.uf;
1966 fieldtype = uf->fieldref->parseddesc.fd->type;
1969 /* PROFILE_CYCLE_STOP; */
1971 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1973 /* PROFILE_CYCLE_START; */
1976 fi = iptr->sx.s23.s3.fmiref->p.field;
1977 fieldtype = fi->type;
1981 /* implicit null-pointer check */
1982 switch (fieldtype) {
1984 M_IST32(s2, s1, disp);
1988 M_LST32(s2, s1, disp);
1991 M_FST32(s2, s1, disp);
1994 M_DST32(s2, s1, disp);
1999 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2000 /* val = value (in current instruction) */
2001 /* following NOP) */
2003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2005 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2006 uf = iptr->sx.s23.s3.uf;
2007 fieldtype = uf->fieldref->parseddesc.fd->type;
2010 /* PROFILE_CYCLE_STOP; */
2012 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
2014 /* PROFILE_CYCLE_START; */
2017 fi = iptr->sx.s23.s3.fmiref->p.field;
2018 fieldtype = fi->type;
2022 /* implicit null-pointer check */
2023 switch (fieldtype) {
2026 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2031 /* XXX why no check for IS_IMM32? */
2032 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2033 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2039 /* branch operations **************************************************/
2041 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2044 M_INTMOVE(s1, REG_ITMP1_XPTR);
2048 #ifdef ENABLE_VERIFIER
2049 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2050 uc = iptr->sx.s23.s2.uc;
2052 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2054 #endif /* ENABLE_VERIFIER */
2056 M_CALL_IMM(0); /* passing exception pc */
2057 M_POP(REG_ITMP2_XPC);
2059 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2063 case ICMD_GOTO: /* ... ==> ... */
2066 emit_br(cd, iptr->dst.block);
2070 case ICMD_JSR: /* ... ==> ... */
2072 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2076 case ICMD_IFNULL: /* ..., value ==> ... */
2077 case ICMD_IFNONNULL:
2079 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2081 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2084 case ICMD_IFEQ: /* ..., value ==> ... */
2091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2092 M_ICMP_IMM(iptr->sx.val.i, s1);
2093 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2096 case ICMD_IF_LEQ: /* ..., value ==> ... */
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 if (IS_IMM32(iptr->sx.val.l))
2105 M_LCMP_IMM(iptr->sx.val.l, s1);
2107 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2108 M_LCMP(REG_ITMP2, s1);
2110 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2113 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2114 case ICMD_IF_ICMPNE:
2115 case ICMD_IF_ICMPLT:
2116 case ICMD_IF_ICMPGE:
2117 case ICMD_IF_ICMPGT:
2118 case ICMD_IF_ICMPLE:
2120 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2121 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2123 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2126 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2127 case ICMD_IF_ACMPNE:
2129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2130 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2132 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2135 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2136 case ICMD_IF_LCMPNE:
2137 case ICMD_IF_LCMPLT:
2138 case ICMD_IF_LCMPGE:
2139 case ICMD_IF_LCMPGT:
2140 case ICMD_IF_LCMPLE:
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2143 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2145 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2148 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2151 REPLACEMENT_POINT_RETURN(cd, iptr);
2152 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2153 M_INTMOVE(s1, REG_RESULT);
2154 goto nowperformreturn;
2156 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2158 REPLACEMENT_POINT_RETURN(cd, iptr);
2159 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2160 M_INTMOVE(s1, REG_RESULT);
2162 #ifdef ENABLE_VERIFIER
2163 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2164 uc = iptr->sx.s23.s2.uc;
2168 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2170 PROFILE_CYCLE_START;
2172 #endif /* ENABLE_VERIFIER */
2173 goto nowperformreturn;
2175 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2178 REPLACEMENT_POINT_RETURN(cd, iptr);
2179 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2180 M_FLTMOVE(s1, REG_FRESULT);
2181 goto nowperformreturn;
2183 case ICMD_RETURN: /* ... ==> ... */
2185 REPLACEMENT_POINT_RETURN(cd, iptr);
2191 p = cd->stackframesize;
2193 #if !defined(NDEBUG)
2194 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2195 emit_verbosecall_exit(jd);
2196 #endif /* !defined(NDEBUG) */
2198 #if defined(ENABLE_THREADS)
2199 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2200 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2202 /* we need to save the proper return value */
2203 switch (iptr->opc) {
2207 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2211 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2215 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2218 /* and now restore the proper return value */
2219 switch (iptr->opc) {
2223 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2227 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2233 /* restore saved registers */
2235 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2236 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2238 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2239 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2242 /* deallocate stack */
2244 if (cd->stackframesize)
2245 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2247 /* generate method profiling code */
2256 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2259 branch_target_t *table;
2261 table = iptr->dst.table;
2263 l = iptr->sx.s23.s2.tablelow;
2264 i = iptr->sx.s23.s3.tablehigh;
2266 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2267 M_INTMOVE(s1, REG_ITMP1);
2270 M_ISUB_IMM(l, REG_ITMP1);
2272 /* number of targets */
2277 M_ICMP_IMM(i - 1, REG_ITMP1);
2278 emit_bugt(cd, table[0].block);
2280 /* build jump table top down and use address of lowest entry */
2285 dseg_add_target(cd, table->block);
2289 /* length of dataseg after last dseg_add_target is used
2292 M_MOV_IMM(0, REG_ITMP2);
2294 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2300 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2303 lookup_target_t *lookup;
2305 lookup = iptr->dst.lookup;
2307 i = iptr->sx.s23.s2.lookupcount;
2309 MCODECHECK(8 + ((7 + 6) * i) + 5);
2310 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2313 M_ICMP_IMM(lookup->value, s1);
2314 emit_beq(cd, lookup->target.block);
2318 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2324 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2326 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2328 bte = iptr->sx.s23.s3.bte;
2332 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2334 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2335 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2336 case ICMD_INVOKEINTERFACE:
2338 REPLACEMENT_POINT_INVOKE(cd, iptr);
2340 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2342 um = iptr->sx.s23.s3.um;
2343 md = um->methodref->parseddesc.md;
2346 lm = iptr->sx.s23.s3.fmiref->p.method;
2348 md = lm->parseddesc;
2352 s3 = md->paramcount;
2354 MCODECHECK((20 * s3) + 128);
2356 /* copy arguments to registers or stack location */
2358 for (s3 = s3 - 1; s3 >= 0; s3--) {
2359 var = VAR(iptr->sx.s23.s2.args[s3]);
2360 d = md->params[s3].regoff;
2362 /* already preallocated (ARGVAR)? */
2364 if (var->flags & PREALLOC)
2367 if (IS_INT_LNG_TYPE(var->type)) {
2368 if (!md->params[s3].inmemory) {
2369 s1 = emit_load(jd, iptr, var, d);
2373 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2374 M_LST(s1, REG_SP, d);
2378 if (!md->params[s3].inmemory) {
2379 s1 = emit_load(jd, iptr, var, d);
2383 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2385 if (IS_2_WORD_TYPE(var->type))
2386 M_DST(s1, REG_SP, d);
2388 M_FST(s1, REG_SP, d);
2393 /* generate method profiling code */
2397 switch (iptr->opc) {
2399 if (bte->stub == NULL) {
2400 M_MOV_IMM(bte->fp, REG_ITMP1);
2402 M_MOV_IMM(bte->stub, REG_ITMP1);
2406 emit_exception_check(cd, iptr);
2409 case ICMD_INVOKESPECIAL:
2410 emit_nullpointer_check(cd, iptr, REG_A0);
2413 case ICMD_INVOKESTATIC:
2415 disp = dseg_add_unique_address(cd, um);
2417 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2421 disp = dseg_add_functionptr(cd, lm->stubroutine);
2424 M_ALD(REG_ITMP2, RIP, disp);
2428 case ICMD_INVOKEVIRTUAL:
2430 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2435 s1 = OFFSET(vftbl_t, table[0]) +
2436 sizeof(methodptr) * lm->vftblindex;
2439 /* implicit null-pointer check */
2440 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2441 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2445 case ICMD_INVOKEINTERFACE:
2447 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2453 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2454 sizeof(methodptr) * lm->class->index;
2456 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2459 /* implicit null-pointer check */
2460 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2461 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2462 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2467 /* generate method profiling code */
2469 PROFILE_CYCLE_START;
2471 /* store size of call code in replacement point */
2473 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2474 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2476 /* store return value */
2478 switch (md->returntype.type) {
2482 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2483 M_INTMOVE(REG_RESULT, s1);
2484 emit_store_dst(jd, iptr, s1);
2488 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2489 M_FLTMOVE(REG_FRESULT, s1);
2490 emit_store_dst(jd, iptr, s1);
2499 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2501 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2502 /* object type cast-check */
2507 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2512 super = iptr->sx.s23.s3.c.cls;
2513 superindex = super->index;
2516 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2517 CODEGEN_CRITICAL_SECTION_NEW;
2519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2521 /* if class is not resolved, check which code to call */
2523 if (super == NULL) {
2525 emit_label_beq(cd, BRANCH_LABEL_1);
2527 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2528 iptr->sx.s23.s3.c.ref, 0);
2530 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2531 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2532 emit_label_beq(cd, BRANCH_LABEL_2);
2535 /* interface checkcast code */
2537 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2538 if (super != NULL) {
2540 emit_label_beq(cd, BRANCH_LABEL_3);
2543 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2545 if (super == NULL) {
2546 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2547 iptr->sx.s23.s3.c.ref,
2552 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2553 M_ICMP_IMM32(superindex, REG_ITMP3);
2554 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2556 M_ALD32(REG_ITMP3, REG_ITMP2,
2557 OFFSET(vftbl_t, interfacetable[0]) -
2558 superindex * sizeof(methodptr*));
2560 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2563 emit_label_br(cd, BRANCH_LABEL_4);
2565 emit_label(cd, BRANCH_LABEL_3);
2568 /* class checkcast code */
2570 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2571 if (super == NULL) {
2572 emit_label(cd, BRANCH_LABEL_2);
2574 cr = iptr->sx.s23.s3.c.ref;
2575 disp = dseg_add_unique_address(cd, cr);
2577 patcher_add_patch_ref(jd,
2578 PATCHER_resolve_classref_to_vftbl,
2583 emit_label_beq(cd, BRANCH_LABEL_5);
2585 disp = dseg_add_address(cd, super->vftbl);
2588 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2589 M_ALD(REG_ITMP3, RIP, disp);
2591 CODEGEN_CRITICAL_SECTION_START;
2593 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2595 /* if (s1 != REG_ITMP1) { */
2596 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2597 /* OFFSET(vftbl_t, baseval), */
2599 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2600 /* OFFSET(vftbl_t, diffval), */
2602 /* #if defined(ENABLE_THREADS) */
2603 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2605 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2609 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2610 M_ISUB(REG_ITMP3, REG_ITMP2);
2611 M_ALD(REG_ITMP3, RIP, disp);
2612 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2615 CODEGEN_CRITICAL_SECTION_END;
2617 M_ICMP(REG_ITMP3, REG_ITMP2);
2618 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2621 emit_label(cd, BRANCH_LABEL_5);
2624 if (super == NULL) {
2625 emit_label(cd, BRANCH_LABEL_1);
2626 emit_label(cd, BRANCH_LABEL_4);
2629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2632 /* array type cast-check */
2634 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2635 M_INTMOVE(s1, REG_A0);
2637 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2638 cr = iptr->sx.s23.s3.c.ref;
2639 disp = dseg_add_unique_address(cd, cr);
2641 patcher_add_patch_ref(jd,
2642 PATCHER_resolve_classref_to_classinfo,
2646 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2649 M_ALD(REG_A1, RIP, disp);
2650 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2653 /* s1 may have been destroyed over the function call */
2654 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2656 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2662 emit_store_dst(jd, iptr, d);
2665 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2671 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2676 super = iptr->sx.s23.s3.c.cls;
2677 superindex = super->index;
2680 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2681 CODEGEN_CRITICAL_SECTION_NEW;
2683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2687 M_INTMOVE(s1, REG_ITMP1);
2693 /* if class is not resolved, check which code to call */
2695 if (super == NULL) {
2697 emit_label_beq(cd, BRANCH_LABEL_1);
2699 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2700 iptr->sx.s23.s3.c.ref, 0);
2702 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2703 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2704 emit_label_beq(cd, BRANCH_LABEL_2);
2707 /* interface instanceof code */
2709 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2710 if (super != NULL) {
2712 emit_label_beq(cd, BRANCH_LABEL_3);
2715 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2717 if (super == NULL) {
2718 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2719 iptr->sx.s23.s3.c.ref, 0);
2723 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2724 M_ICMP_IMM32(superindex, REG_ITMP3);
2726 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2729 M_ALD32(REG_ITMP1, REG_ITMP1,
2730 OFFSET(vftbl_t, interfacetable[0]) -
2731 superindex * sizeof(methodptr*));
2736 emit_label_br(cd, BRANCH_LABEL_4);
2738 emit_label(cd, BRANCH_LABEL_3);
2741 /* class instanceof code */
2743 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2744 if (super == NULL) {
2745 emit_label(cd, BRANCH_LABEL_2);
2747 cr = iptr->sx.s23.s3.c.ref;
2748 disp = dseg_add_unique_address(cd, cr);
2750 patcher_add_patch_ref(jd,
2751 PATCHER_resolve_classref_to_vftbl,
2756 emit_label_beq(cd, BRANCH_LABEL_5);
2758 disp = dseg_add_address(cd, super->vftbl);
2761 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2762 M_ALD(REG_ITMP2, RIP, disp);
2764 CODEGEN_CRITICAL_SECTION_START;
2766 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2767 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2768 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2770 CODEGEN_CRITICAL_SECTION_END;
2772 M_ISUB(REG_ITMP2, REG_ITMP1);
2773 M_CLR(d); /* may be REG_ITMP2 */
2774 M_ICMP(REG_ITMP3, REG_ITMP1);
2778 emit_label(cd, BRANCH_LABEL_5);
2781 if (super == NULL) {
2782 emit_label(cd, BRANCH_LABEL_1);
2783 emit_label(cd, BRANCH_LABEL_4);
2786 emit_store_dst(jd, iptr, d);
2790 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2792 /* check for negative sizes and copy sizes to stack if necessary */
2794 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2796 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2798 /* copy SAVEDVAR sizes to stack */
2799 var = VAR(iptr->sx.s23.s2.args[s1]);
2801 /* Already Preallocated? */
2802 if (!(var->flags & PREALLOC)) {
2803 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2804 M_LST(s2, REG_SP, s1 * 8);
2808 /* a0 = dimension count */
2810 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2812 /* is a patcher function set? */
2814 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2815 cr = iptr->sx.s23.s3.c.ref;
2816 disp = dseg_add_unique_address(cd, cr);
2818 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2822 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2825 /* a1 = classinfo */
2827 M_ALD(REG_A1, RIP, disp);
2829 /* a2 = pointer to dimensions = stack pointer */
2831 M_MOV(REG_SP, REG_A2);
2833 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2836 /* check for exception before result assignment */
2838 emit_exception_check(cd, iptr);
2840 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2841 M_INTMOVE(REG_RESULT, s1);
2842 emit_store_dst(jd, iptr, s1);
2846 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2851 } /* for instruction */
2853 MCODECHECK(512); /* XXX require a lower number? */
2855 /* At the end of a basic block we may have to append some nops,
2856 because the patcher stub calling code might be longer than the
2857 actual instruction. So codepatching does not change the
2858 following block unintentionally. */
2860 if (cd->mcodeptr < cd->lastmcodeptr) {
2861 while (cd->mcodeptr < cd->lastmcodeptr) {
2866 } /* if (bptr -> flags >= BBREACHED) */
2867 } /* for basic block */
2869 dseg_createlinenumbertable(cd);
2871 /* Generate patcher traps. */
2873 emit_patcher_traps(jd);
2875 /* everything's ok */
2881 /* codegen_emit_stub_compiler **************************************************
2883 Emit a stub routine which calls the compiler.
2885 *******************************************************************************/
2887 void codegen_emit_stub_compiler(jitdata *jd)
2892 /* get required compiler data */
2897 /* code for the stub */
2899 M_LLD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
2900 /* M_ALD(REG_ITMP1, RIP, -(2 * SIZEOF_VOID_P)); /\* methodinfo *\/ */
2901 M_LLD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
2902 /* M_ALD(REG_ITMP3, RIP, -(3 * SIZEOF_VOID_P)); /\* compiler pointer *\/ */
2907 /* codegen_emit_stub_builtin ***************************************************
2909 Creates a stub routine which calls a builtin function.
2911 *******************************************************************************/
2913 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
2921 /* get required compiler data */
2928 /* calculate stack frame size */
2930 cd->stackframesize =
2931 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2932 md->paramcount + /* saved argument registers */
2933 1; /* return value */
2935 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
2937 /* create method header */
2939 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2940 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2941 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2942 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2943 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2944 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2945 (void) dseg_addlinenumbertablesize(cd);
2946 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2948 /* generate stub code */
2950 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2952 #if defined(ENABLE_GC_CACAO)
2953 /* Save callee saved integer registers in stackframeinfo (GC may
2954 need to recover them during a collection). */
2956 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
2957 OFFSET(stackframeinfo, intregs);
2959 for (i = 0; i < INT_SAV_CNT; i++)
2960 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2963 /* save integer and float argument registers */
2965 for (i = 0, j = 0; i < md->paramcount; i++) {
2966 if (!md->params[i].inmemory) {
2967 s1 = md->params[i].regoff;
2969 switch (md->paramtypes[i].type) {
2973 M_LST(s1, REG_SP, j * 8);
2977 M_DST(s1, REG_SP, j * 8);
2985 /* create dynamic stack info */
2987 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
2988 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2989 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
2990 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
2991 M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
2994 /* restore integer and float argument registers */
2996 for (i = 0, j = 0; i < md->paramcount; i++) {
2997 if (!md->params[i].inmemory) {
2998 s1 = md->params[i].regoff;
3000 switch (md->paramtypes[i].type) {
3004 M_LLD(s1, REG_SP, j * 8);
3008 M_DLD(s1, REG_SP, j * 8);
3016 /* call the builtin function */
3018 M_MOV_IMM(bte->fp, REG_ITMP3);
3021 /* save return value */
3023 switch (md->returntype.type) {
3027 M_LST(REG_RESULT, REG_SP, 0 * 8);
3031 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3037 /* remove native stackframe info */
3039 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3040 M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
3043 /* restore return value */
3045 switch (md->returntype.type) {
3049 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3053 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3059 #if defined(ENABLE_GC_CACAO)
3060 /* Restore callee saved integer registers from stackframeinfo (GC
3061 might have modified them during a collection). */
3063 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3064 OFFSET(stackframeinfo, intregs);
3066 for (i = 0; i < INT_SAV_CNT; i++)
3067 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3070 /* remove stackframe */
3072 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3077 /* codegen_emit_stub_native ****************************************************
3079 Emits a stub routine which calls a native method.
3081 *******************************************************************************/
3083 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3094 #if defined(ENABLE_GC_CACAO)
3098 /* get required compiler data */
3104 /* initialize variables */
3107 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3109 /* calculate stack frame size */
3111 cd->stackframesize =
3112 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3113 sizeof(localref_table) / SIZEOF_VOID_P +
3115 1 + /* functionptr, TODO: store in data segment */
3118 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3120 /* create method header */
3122 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3123 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3124 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3125 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3126 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3127 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3128 (void) dseg_addlinenumbertablesize(cd);
3129 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3131 #if defined(ENABLE_PROFILING)
3132 /* generate native method profiling code */
3134 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3135 /* count frequency */
3137 M_MOV_IMM(code, REG_ITMP3);
3138 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3142 /* generate stub code */
3144 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3146 /* get function address (this must happen before the stackframeinfo) */
3148 funcdisp = dseg_add_functionptr(cd, f);
3151 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3153 #if defined(ENABLE_GC_CACAO)
3154 /* Save callee saved integer registers in stackframeinfo (GC may
3155 need to recover them during a collection). */
3157 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3158 OFFSET(stackframeinfo, intregs);
3160 for (i = 0; i < INT_SAV_CNT; i++)
3161 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3164 /* save integer and float argument registers */
3166 for (i = 0; i < md->paramcount; i++) {
3167 if (!md->params[i].inmemory) {
3168 s1 = md->params[i].regoff;
3170 switch (md->paramtypes[i].type) {
3174 M_LST(s1, REG_SP, i * 8);
3178 M_DST(s1, REG_SP, i * 8);
3184 /* create dynamic stack info */
3186 M_MOV(REG_SP, REG_A0);
3187 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3188 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3191 /* remember class argument */
3193 if (m->flags & ACC_STATIC)
3194 M_MOV(REG_RESULT, REG_ITMP2);
3196 /* restore integer and float argument registers */
3198 for (i = 0; i < md->paramcount; i++) {
3199 if (!md->params[i].inmemory) {
3200 s1 = md->params[i].regoff;
3202 switch (md->paramtypes[i].type) {
3206 M_LLD(s1, REG_SP, i * 8);
3210 M_DLD(s1, REG_SP, i * 8);
3216 /* copy or spill arguments to new locations */
3218 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3219 t = md->paramtypes[i].type;
3220 s2 = nmd->params[j].regoff;
3222 if (IS_INT_LNG_TYPE(t)) {
3223 if (!md->params[i].inmemory) {
3224 s1 = md->params[i].regoff;
3226 if (!nmd->params[j].inmemory)
3229 M_LST(s1, REG_SP, s2);
3232 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3233 M_LLD(REG_ITMP1, REG_SP, s1);
3234 M_LST(REG_ITMP1, REG_SP, s2);
3238 /* We only copy spilled float arguments, as the float
3239 argument registers keep unchanged. */
3241 if (md->params[i].inmemory) {
3242 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3244 if (IS_2_WORD_TYPE(t)) {
3245 M_DLD(REG_FTMP1, REG_SP, s1);
3246 M_DST(REG_FTMP1, REG_SP, s2);
3249 M_FLD(REG_FTMP1, REG_SP, s1);
3250 M_FST(REG_FTMP1, REG_SP, s2);
3256 /* put class into second argument register */
3258 if (m->flags & ACC_STATIC)
3259 M_MOV(REG_ITMP2, REG_A1);
3261 /* put env into first argument register */
3263 M_MOV_IMM(_Jv_env, REG_A0);
3265 /* do the native function call */
3267 M_ALD(REG_ITMP1, RIP, funcdisp);
3270 /* save return value */
3272 switch (md->returntype.type) {
3276 M_LST(REG_RESULT, REG_SP, 0 * 8);
3280 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3286 /* remove native stackframe info */
3288 M_MOV(REG_SP, REG_A0);
3289 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3290 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3292 M_MOV(REG_RESULT, REG_ITMP3);
3294 /* restore return value */
3296 switch (md->returntype.type) {
3300 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3304 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3310 #if defined(ENABLE_GC_CACAO)
3311 /* Restore callee saved integer registers from stackframeinfo (GC
3312 might have modified them during a collection). */
3314 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3315 OFFSET(stackframeinfo, intregs);
3317 for (i = 0; i < INT_SAV_CNT; i++)
3318 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3321 /* remove stackframe */
3323 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3325 /* test for exception */
3331 /* handle exception */
3333 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3334 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3335 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3337 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3340 /* Generate patcher traps. */
3342 emit_patcher_traps(jd);
3347 * These are local overrides for various environment variables in Emacs.
3348 * Please do not remove this and leave it at the end of the file, where
3349 * Emacs will automagically detect them.
3350 * ---------------------------------------------------------------------
3353 * indent-tabs-mode: t
3357 * vim:noexpandtab:sw=4:ts=4: