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);
2403 M_MOV_IMM(bte->stub, REG_ITMP1);
2408 case ICMD_INVOKESPECIAL:
2409 emit_nullpointer_check(cd, iptr, REG_A0);
2412 case ICMD_INVOKESTATIC:
2414 disp = dseg_add_unique_address(cd, um);
2416 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2420 disp = dseg_add_functionptr(cd, lm->stubroutine);
2423 M_ALD(REG_ITMP2, RIP, disp);
2427 case ICMD_INVOKEVIRTUAL:
2429 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2434 s1 = OFFSET(vftbl_t, table[0]) +
2435 sizeof(methodptr) * lm->vftblindex;
2438 /* implicit null-pointer check */
2439 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2440 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2444 case ICMD_INVOKEINTERFACE:
2446 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2452 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2453 sizeof(methodptr) * lm->class->index;
2455 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2458 /* implicit null-pointer check */
2459 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2460 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2461 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2466 /* generate method profiling code */
2468 PROFILE_CYCLE_START;
2470 /* store size of call code in replacement point */
2472 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2473 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2475 /* store return value */
2477 switch (md->returntype.type) {
2481 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2482 M_INTMOVE(REG_RESULT, s1);
2483 emit_store_dst(jd, iptr, s1);
2487 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2488 M_FLTMOVE(REG_FRESULT, s1);
2489 emit_store_dst(jd, iptr, s1);
2498 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2500 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2501 /* object type cast-check */
2506 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2511 super = iptr->sx.s23.s3.c.cls;
2512 superindex = super->index;
2515 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2516 CODEGEN_CRITICAL_SECTION_NEW;
2518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2520 /* if class is not resolved, check which code to call */
2522 if (super == NULL) {
2524 emit_label_beq(cd, BRANCH_LABEL_1);
2526 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2527 iptr->sx.s23.s3.c.ref, 0);
2529 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2530 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2531 emit_label_beq(cd, BRANCH_LABEL_2);
2534 /* interface checkcast code */
2536 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2537 if (super != NULL) {
2539 emit_label_beq(cd, BRANCH_LABEL_3);
2542 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2544 if (super == NULL) {
2545 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2546 iptr->sx.s23.s3.c.ref,
2551 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2552 M_ICMP_IMM32(superindex, REG_ITMP3);
2553 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2555 M_ALD32(REG_ITMP3, REG_ITMP2,
2556 OFFSET(vftbl_t, interfacetable[0]) -
2557 superindex * sizeof(methodptr*));
2559 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2562 emit_label_br(cd, BRANCH_LABEL_4);
2564 emit_label(cd, BRANCH_LABEL_3);
2567 /* class checkcast code */
2569 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2570 if (super == NULL) {
2571 emit_label(cd, BRANCH_LABEL_2);
2573 cr = iptr->sx.s23.s3.c.ref;
2574 disp = dseg_add_unique_address(cd, cr);
2576 patcher_add_patch_ref(jd,
2577 PATCHER_resolve_classref_to_vftbl,
2582 emit_label_beq(cd, BRANCH_LABEL_5);
2584 disp = dseg_add_address(cd, super->vftbl);
2587 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2588 M_ALD(REG_ITMP3, RIP, disp);
2590 CODEGEN_CRITICAL_SECTION_START;
2592 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2594 /* if (s1 != REG_ITMP1) { */
2595 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2596 /* OFFSET(vftbl_t, baseval), */
2598 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2599 /* OFFSET(vftbl_t, diffval), */
2601 /* #if defined(ENABLE_THREADS) */
2602 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2604 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2608 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2609 M_ISUB(REG_ITMP3, REG_ITMP2);
2610 M_ALD(REG_ITMP3, RIP, disp);
2611 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2614 CODEGEN_CRITICAL_SECTION_END;
2616 M_ICMP(REG_ITMP3, REG_ITMP2);
2617 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2620 emit_label(cd, BRANCH_LABEL_5);
2623 if (super == NULL) {
2624 emit_label(cd, BRANCH_LABEL_1);
2625 emit_label(cd, BRANCH_LABEL_4);
2628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2631 /* array type cast-check */
2633 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2634 M_INTMOVE(s1, REG_A0);
2636 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2637 cr = iptr->sx.s23.s3.c.ref;
2638 disp = dseg_add_unique_address(cd, cr);
2640 patcher_add_patch_ref(jd,
2641 PATCHER_resolve_classref_to_classinfo,
2645 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2648 M_ALD(REG_A1, RIP, disp);
2649 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2652 /* s1 may have been destroyed over the function call */
2653 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2655 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2661 emit_store_dst(jd, iptr, d);
2664 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2670 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2675 super = iptr->sx.s23.s3.c.cls;
2676 superindex = super->index;
2679 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2680 CODEGEN_CRITICAL_SECTION_NEW;
2682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2686 M_INTMOVE(s1, REG_ITMP1);
2692 /* if class is not resolved, check which code to call */
2694 if (super == NULL) {
2696 emit_label_beq(cd, BRANCH_LABEL_1);
2698 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2699 iptr->sx.s23.s3.c.ref, 0);
2701 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2702 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2703 emit_label_beq(cd, BRANCH_LABEL_2);
2706 /* interface instanceof code */
2708 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2709 if (super != NULL) {
2711 emit_label_beq(cd, BRANCH_LABEL_3);
2714 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2716 if (super == NULL) {
2717 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2718 iptr->sx.s23.s3.c.ref, 0);
2722 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2723 M_ICMP_IMM32(superindex, REG_ITMP3);
2725 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2728 M_ALD32(REG_ITMP1, REG_ITMP1,
2729 OFFSET(vftbl_t, interfacetable[0]) -
2730 superindex * sizeof(methodptr*));
2735 emit_label_br(cd, BRANCH_LABEL_4);
2737 emit_label(cd, BRANCH_LABEL_3);
2740 /* class instanceof code */
2742 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2743 if (super == NULL) {
2744 emit_label(cd, BRANCH_LABEL_2);
2746 cr = iptr->sx.s23.s3.c.ref;
2747 disp = dseg_add_unique_address(cd, cr);
2749 patcher_add_patch_ref(jd,
2750 PATCHER_resolve_classref_to_vftbl,
2755 emit_label_beq(cd, BRANCH_LABEL_5);
2757 disp = dseg_add_address(cd, super->vftbl);
2760 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2761 M_ALD(REG_ITMP2, RIP, disp);
2763 CODEGEN_CRITICAL_SECTION_START;
2765 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2766 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2767 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2769 CODEGEN_CRITICAL_SECTION_END;
2771 M_ISUB(REG_ITMP2, REG_ITMP1);
2772 M_CLR(d); /* may be REG_ITMP2 */
2773 M_ICMP(REG_ITMP3, REG_ITMP1);
2777 emit_label(cd, BRANCH_LABEL_5);
2780 if (super == NULL) {
2781 emit_label(cd, BRANCH_LABEL_1);
2782 emit_label(cd, BRANCH_LABEL_4);
2785 emit_store_dst(jd, iptr, d);
2789 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2791 /* check for negative sizes and copy sizes to stack if necessary */
2793 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2795 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2797 /* copy SAVEDVAR sizes to stack */
2798 var = VAR(iptr->sx.s23.s2.args[s1]);
2800 /* Already Preallocated? */
2801 if (!(var->flags & PREALLOC)) {
2802 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2803 M_LST(s2, REG_SP, s1 * 8);
2807 /* a0 = dimension count */
2809 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2811 /* is a patcher function set? */
2813 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2814 cr = iptr->sx.s23.s3.c.ref;
2815 disp = dseg_add_unique_address(cd, cr);
2817 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2821 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2824 /* a1 = classinfo */
2826 M_ALD(REG_A1, RIP, disp);
2828 /* a2 = pointer to dimensions = stack pointer */
2830 M_MOV(REG_SP, REG_A2);
2832 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2835 /* check for exception before result assignment */
2837 emit_exception_check(cd, iptr);
2839 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2840 M_INTMOVE(REG_RESULT, s1);
2841 emit_store_dst(jd, iptr, s1);
2845 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2850 } /* for instruction */
2852 MCODECHECK(512); /* XXX require a lower number? */
2854 /* At the end of a basic block we may have to append some nops,
2855 because the patcher stub calling code might be longer than the
2856 actual instruction. So codepatching does not change the
2857 following block unintentionally. */
2859 if (cd->mcodeptr < cd->lastmcodeptr) {
2860 while (cd->mcodeptr < cd->lastmcodeptr) {
2865 } /* if (bptr -> flags >= BBREACHED) */
2866 } /* for basic block */
2868 dseg_createlinenumbertable(cd);
2870 /* Generate patcher traps. */
2872 emit_patcher_traps(jd);
2874 /* everything's ok */
2880 /* codegen_emit_stub_native ****************************************************
2882 Emits a stub routine which calls a native method.
2884 *******************************************************************************/
2886 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2895 #if defined(ENABLE_GC_CACAO)
2899 /* get required compiler data */
2905 /* initialize variables */
2909 /* calculate stack frame size */
2911 cd->stackframesize =
2912 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2913 sizeof(localref_table) / SIZEOF_VOID_P +
2915 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2918 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2920 /* create method header */
2922 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2923 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2924 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2925 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2926 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2927 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2928 (void) dseg_addlinenumbertablesize(cd);
2929 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2931 #if defined(ENABLE_PROFILING)
2932 /* generate native method profiling code */
2934 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2935 /* count frequency */
2937 M_MOV_IMM(code, REG_ITMP3);
2938 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2942 /* generate stub code */
2944 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2946 /* get function address (this must happen before the stackframeinfo) */
2948 funcdisp = dseg_add_functionptr(cd, f);
2951 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
2953 #if defined(ENABLE_GC_CACAO)
2954 /* Save callee saved integer registers in stackframeinfo (GC may
2955 need to recover them during a collection). */
2957 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
2958 OFFSET(stackframeinfo, intregs);
2960 for (i = 0; i < INT_SAV_CNT; i++)
2961 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2964 /* save integer and float argument registers */
2966 for (i = 0; i < md->paramcount; i++) {
2967 if (!md->params[i].inmemory) {
2968 s1 = md->params[i].regoff;
2970 switch (md->paramtypes[i].type) {
2974 M_LST(s1, REG_SP, i * 8);
2978 M_DST(s1, REG_SP, i * 8);
2984 /* create dynamic stack info */
2986 M_MOV(REG_SP, REG_A0);
2987 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2988 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2991 /* remember class argument */
2993 if (m->flags & ACC_STATIC)
2994 M_MOV(REG_RESULT, REG_ITMP2);
2996 /* restore integer and float argument registers */
2998 for (i = 0; i < md->paramcount; i++) {
2999 if (!md->params[i].inmemory) {
3000 s1 = md->params[i].regoff;
3002 switch (md->paramtypes[i].type) {
3006 M_LLD(s1, REG_SP, i * 8);
3010 M_DLD(s1, REG_SP, i * 8);
3016 /* Copy or spill arguments to new locations. */
3018 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3019 s2 = nmd->params[j].regoff;
3021 switch (md->paramtypes[i].type) {
3025 if (!md->params[i].inmemory) {
3026 s1 = md->params[i].regoff;
3028 if (!nmd->params[j].inmemory)
3031 M_LST(s1, REG_SP, s2);
3034 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3035 M_LLD(REG_ITMP1, REG_SP, s1);
3036 M_LST(REG_ITMP1, REG_SP, s2);
3040 /* We only copy spilled float arguments, as the float
3041 argument registers keep unchanged. */
3043 if (md->params[i].inmemory) {
3044 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3046 M_FLD(REG_FTMP1, REG_SP, s1);
3047 M_FST(REG_FTMP1, REG_SP, s2);
3051 if (md->params[i].inmemory) {
3052 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3053 M_DLD(REG_FTMP1, REG_SP, s1);
3054 M_DST(REG_FTMP1, REG_SP, s2);
3060 /* Handle native Java methods. */
3062 if (m->flags & ACC_NATIVE) {
3063 /* put class into second argument register */
3065 if (m->flags & ACC_STATIC)
3066 M_MOV(REG_ITMP2, REG_A1);
3068 /* put env into first argument register */
3070 M_MOV_IMM(_Jv_env, REG_A0);
3073 /* do the native function call */
3075 M_ALD(REG_ITMP1, RIP, funcdisp);
3078 /* save return value */
3080 switch (md->returntype.type) {
3084 M_LST(REG_RESULT, REG_SP, 0 * 8);
3088 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3094 /* remove native stackframe info */
3096 M_MOV(REG_SP, REG_A0);
3097 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3098 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3100 M_MOV(REG_RESULT, REG_ITMP3);
3102 /* restore return value */
3104 switch (md->returntype.type) {
3108 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3112 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3118 #if defined(ENABLE_GC_CACAO)
3119 /* Restore callee saved integer registers from stackframeinfo (GC
3120 might have modified them during a collection). */
3122 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3123 OFFSET(stackframeinfo, intregs);
3125 for (i = 0; i < INT_SAV_CNT; i++)
3126 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3129 /* remove stackframe */
3131 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3133 /* test for exception */
3139 /* handle exception */
3141 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3142 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3143 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3145 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3148 /* Generate patcher traps. */
3150 emit_patcher_traps(jd);
3155 * These are local overrides for various environment variables in Emacs.
3156 * Please do not remove this and leave it at the end of the file, where
3157 * Emacs will automagically detect them.
3158 * ---------------------------------------------------------------------
3161 * indent-tabs-mode: t
3165 * vim:noexpandtab:sw=4:ts=4: