1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
32 $Id: codegen.c 6148 2006-12-07 23:57:45Z edwin $
46 #include "vm/jit/x86_64/arch.h"
47 #include "vm/jit/x86_64/codegen.h"
48 #include "vm/jit/x86_64/emit.h"
50 #include "mm/memory.h"
51 #include "native/jni.h"
52 #include "native/native.h"
54 #if defined(ENABLE_THREADS)
55 # include "threads/native/lock.h"
58 #include "vm/builtin.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/loader.h"
62 #include "vm/options.h"
63 #include "vm/statistics.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/codegen-common.h"
68 #include "vm/jit/dseg.h"
69 #include "vm/jit/emit-common.h"
70 #include "vm/jit/jit.h"
71 #include "vm/jit/methodheader.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
82 /* codegen *********************************************************************
84 Generates machine code.
86 *******************************************************************************/
88 bool codegen(jitdata *jd)
94 s4 len, s1, s2, s3, d, disp;
101 constant_classref *cr;
102 unresolved_class *uc;
103 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
104 unresolved_method *um;
105 builtintable_entry *bte;
108 unresolved_field *uf;
112 /* get required compiler data */
119 /* prevent compiler warnings */
132 /* space to save used callee saved registers */
134 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
135 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
137 cd->stackframesize = rd->memuse + savedregs_num;
139 #if defined(ENABLE_THREADS)
140 /* space to save argument of monitor_enter */
142 if (checksync && (m->flags & ACC_SYNCHRONIZED))
143 cd->stackframesize++;
146 /* Keep stack of non-leaf functions 16-byte aligned for calls into
147 native code e.g. libc or jni (alignment problems with
150 if (!jd->isleafmethod || opt_verbosecall)
151 cd->stackframesize |= 0x1;
153 /* create method header */
155 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
156 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
158 #if defined(ENABLE_THREADS)
159 /* IsSync contains the offset relative to the stack pointer for the
160 argument of monitor_exit used in the exception handler. Since the
161 offset could be zero and give a wrong meaning of the flag it is
165 if (checksync && (m->flags & ACC_SYNCHRONIZED))
166 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
169 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
171 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
172 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
173 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
175 (void) dseg_addlinenumbertablesize(cd);
177 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
179 /* create exception table */
181 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
182 dseg_add_target(cd, ex->start);
183 dseg_add_target(cd, ex->end);
184 dseg_add_target(cd, ex->handler);
185 (void) dseg_add_unique_address(cd, ex->catchtype.any);
188 /* generate method profiling code */
190 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
191 /* count frequency */
193 M_MOV_IMM(code, REG_ITMP3);
194 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
199 /* create stack frame (if necessary) */
201 if (cd->stackframesize)
202 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
204 /* save used callee saved registers */
206 p = cd->stackframesize;
207 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
208 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
210 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
211 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
214 /* take arguments out of register or stack frame */
218 for (p = 0, l = 0; p < md->paramcount; p++) {
219 t = md->paramtypes[p].type;
221 varindex = jd->local_map[l * 5 + t];
224 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
227 if (varindex == UNUSED)
232 s1 = md->params[p].regoff;
234 if (IS_INT_LNG_TYPE(t)) { /* integer args */
235 s2 = rd->argintregs[s1];
236 if (!md->params[p].inmemory) { /* register arguments */
237 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
238 M_INTMOVE(s2, var->vv.regoff);
240 } else { /* reg arg -> spilled */
241 M_LST(s2, REG_SP, var->vv.regoff * 8);
244 } else { /* stack arguments */
245 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
246 /* + 8 for return address */
247 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
249 } else { /* stack arg -> spilled */
250 var->vv.regoff = cd->stackframesize + s1 + 1;
254 } else { /* floating args */
255 if (!md->params[p].inmemory) { /* register arguments */
256 s2 = rd->argfltregs[s1];
257 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
258 M_FLTMOVE(s2, var->vv.regoff);
260 } else { /* reg arg -> spilled */
261 M_DST(s2, REG_SP, var->vv.regoff * 8);
264 } else { /* stack arguments */
265 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
266 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
269 var->vv.regoff = cd->stackframesize + s1 + 1;
275 /* save monitorenter argument */
277 #if defined(ENABLE_THREADS)
278 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
279 /* stack offset for monitor argument */
283 if (opt_verbosecall) {
284 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
286 for (p = 0; p < INT_ARG_CNT; p++)
287 M_LST(rd->argintregs[p], REG_SP, p * 8);
289 for (p = 0; p < FLT_ARG_CNT; p++)
290 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
292 s1 += INT_ARG_CNT + FLT_ARG_CNT;
295 /* decide which monitor enter function to call */
297 if (m->flags & ACC_STATIC) {
298 M_MOV_IMM(&m->class->object.header, REG_A0);
303 codegen_add_nullpointerexception_ref(cd);
306 M_AST(REG_A0, REG_SP, s1 * 8);
307 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
310 if (opt_verbosecall) {
311 for (p = 0; p < INT_ARG_CNT; p++)
312 M_LLD(rd->argintregs[p], REG_SP, p * 8);
314 for (p = 0; p < FLT_ARG_CNT; p++)
315 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
317 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
323 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
324 emit_verbosecall_enter(jd);
325 #endif /* !defined(NDEBUG) */
329 /* end of header generation */
331 /* create replacement points */
333 REPLACEMENT_POINTS_INIT(cd, jd);
335 /* walk through all basic blocks */
337 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
339 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
341 if (bptr->flags >= BBREACHED) {
343 /* branch resolving */
345 codegen_resolve_branchrefs(cd, bptr);
347 /* handle replacement points */
349 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
351 /* copy interface registers to their destination */
356 /* generate basicblock profiling code */
358 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
359 /* count frequency */
361 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
362 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
364 /* if this is an exception handler, start profiling again */
366 if (bptr->type == BBTYPE_EXH)
370 #if defined(ENABLE_LSRA)
374 src = bptr->invars[len];
375 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
376 if (bptr->type == BBTYPE_EXH) {
377 /* d = reg_of_var(rd, src, REG_ITMP1); */
378 if (!IS_INMEMORY(src->flags))
382 M_INTMOVE(REG_ITMP1, d);
383 emit_store(jd, NULL, src, d);
393 var = VAR(bptr->invars[len]);
394 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
395 if (bptr->type == BBTYPE_EXH) {
396 d = codegen_reg_of_var(0, var, REG_ITMP1);
397 M_INTMOVE(REG_ITMP1, d);
398 emit_store(jd, NULL, var, d);
402 assert((var->flags & INOUT));
405 #if defined(ENABLE_LSRA)
408 /* walk through all instructions */
413 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
414 if (iptr->line != currentline) {
415 dseg_addlinenumber(cd, iptr->line);
416 currentline = iptr->line;
419 MCODECHECK(1024); /* 1KB should be enough */
422 case ICMD_NOP: /* ... ==> ... */
423 case ICMD_POP: /* ..., value ==> ... */
424 case ICMD_POP2: /* ..., value, value ==> ... */
427 case ICMD_INLINE_START:
429 REPLACEMENT_POINT_INLINE_START(cd, iptr);
432 case ICMD_INLINE_BODY:
434 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
435 dseg_addlinenumber_inline_start(cd, iptr);
436 dseg_addlinenumber(cd, iptr->line);
439 case ICMD_INLINE_END:
441 dseg_addlinenumber_inline_end(cd, iptr);
442 dseg_addlinenumber(cd, iptr->line);
445 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
447 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
450 codegen_add_nullpointerexception_ref(cd);
453 /* constant operations ************************************************/
455 case ICMD_ICONST: /* ... ==> ..., constant */
457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
458 ICONST(d, iptr->sx.val.i);
459 emit_store_dst(jd, iptr, d);
462 case ICMD_LCONST: /* ... ==> ..., constant */
464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
465 LCONST(d, iptr->sx.val.l);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_FCONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
472 disp = dseg_add_float(cd, iptr->sx.val.f);
473 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_DCONST: /* ... ==> ..., constant */
479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
480 disp = dseg_add_double(cd, iptr->sx.val.d);
481 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_ACONST: /* ... ==> ..., constant */
487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
489 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
490 cr = iptr->sx.val.c.ref;
492 /* PROFILE_CYCLE_STOP; */
494 codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
496 /* PROFILE_CYCLE_START; */
501 if (iptr->sx.val.anyptr == 0)
504 M_MOV_IMM(iptr->sx.val.anyptr, d);
506 emit_store_dst(jd, iptr, d);
510 /* load/store/copy/move operations ************************************/
512 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
513 case ICMD_ALOAD: /* s1 = local variable */
517 case ICMD_ISTORE: /* ..., value ==> ... */
524 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
528 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
529 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
532 /* integer operations *************************************************/
534 case ICMD_INEG: /* ..., value ==> ..., - value */
536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_LNEG: /* ..., value ==> ..., - value */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_I2L: /* ..., value ==> ..., value */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
557 emit_store_dst(jd, iptr, d);
560 case ICMD_L2I: /* ..., value ==> ..., value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_INT2BYTE: /* ..., 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_INT2CHAR: /* ..., 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);
584 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
589 emit_store_dst(jd, iptr, d);
593 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
597 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
604 emit_store_dst(jd, iptr, d);
608 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
609 /* sx.val.i = constant */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
614 /* Using inc and dec is not faster than add (tested with
618 M_IADD_IMM(iptr->sx.val.i, d);
619 emit_store_dst(jd, iptr, d);
622 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
637 /* sx.val.l = constant */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
642 if (IS_IMM32(iptr->sx.val.l))
643 M_LADD_IMM(iptr->sx.val.l, d);
645 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
646 M_LADD(REG_ITMP2, d);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 M_INTMOVE(s1, REG_ITMP1);
658 M_ISUB(s2, REG_ITMP1);
659 M_INTMOVE(REG_ITMP1, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
668 /* sx.val.i = constant */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
673 M_ISUB_IMM(iptr->sx.val.i, d);
674 emit_store_dst(jd, iptr, d);
677 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
680 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
683 M_INTMOVE(s1, REG_ITMP1);
684 M_LSUB(s2, REG_ITMP1);
685 M_INTMOVE(REG_ITMP1, d);
690 emit_store_dst(jd, iptr, d);
693 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
694 /* sx.val.l = constant */
696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
699 if (IS_IMM32(iptr->sx.val.l))
700 M_LSUB_IMM(iptr->sx.val.l, d);
702 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
703 M_LSUB(REG_ITMP2, d);
705 emit_store_dst(jd, iptr, d);
708 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
711 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
712 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
719 emit_store_dst(jd, iptr, d);
722 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
723 /* sx.val.i = constant */
725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
727 if (iptr->sx.val.i == 2) {
731 M_IMUL_IMM(s1, iptr->sx.val.i, d);
732 emit_store_dst(jd, iptr, d);
735 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
738 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
739 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
750 /* sx.val.l = constant */
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
754 if (IS_IMM32(iptr->sx.val.l))
755 M_LMUL_IMM(s1, iptr->sx.val.l, d);
757 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
759 M_LMUL(REG_ITMP2, d);
761 emit_store_dst(jd, iptr, d);
764 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
766 s1 = emit_load_s1(jd, iptr, RAX);
767 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
768 d = codegen_reg_of_dst(jd, iptr, RAX);
771 M_INTMOVE(s2, REG_ITMP3);
772 emit_arithmetic_check(cd, REG_ITMP3);
774 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
776 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
778 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
779 M_BEQ(1 + 3); /* 6 bytes */
781 emit_cltd(cd); /* 1 byte */
782 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
785 emit_store_dst(jd, iptr, d);
786 dst = VAROP(iptr->dst);
787 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
788 M_MOV(REG_ITMP2, RDX); /* restore RDX */
791 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
793 s1 = emit_load_s1(jd, iptr, RAX);
794 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
795 d = codegen_reg_of_dst(jd, iptr, RDX);
798 M_INTMOVE(s2, REG_ITMP3);
799 emit_arithmetic_check(cd, REG_ITMP3);
801 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
803 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
805 M_CLR(RDX); /* 3 bytes */
806 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
807 M_BEQ(1 + 3); /* 6 bytes */
809 emit_cltd(cd); /* 1 byte */
810 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
813 emit_store_dst(jd, iptr, d);
814 dst = VAROP(iptr->dst);
815 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
816 M_MOV(REG_ITMP2, RDX); /* restore RDX */
819 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
820 /* sx.val.i = constant */
822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
823 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
824 M_INTMOVE(s1, REG_ITMP1);
825 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
826 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
827 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
828 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
829 emit_mov_reg_reg(cd, REG_ITMP1, d);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
834 /* sx.val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
838 M_INTMOVE(s1, REG_ITMP1);
839 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
840 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
841 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
842 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
843 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
844 emit_mov_reg_reg(cd, REG_ITMP1, d);
845 emit_store_dst(jd, iptr, d);
849 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
851 s1 = emit_load_s1(jd, iptr, RAX);
852 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
853 d = codegen_reg_of_dst(jd, iptr, RAX);
856 M_INTMOVE(s2, REG_ITMP3);
857 emit_arithmetic_check(cd, REG_ITMP3);
859 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
861 /* check as described in jvm spec */
862 disp = dseg_add_s8(cd, 0x8000000000000000LL);
863 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
865 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
866 M_BEQ(2 + 3); /* 6 bytes */
868 emit_cqto(cd); /* 2 bytes */
869 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
872 emit_store_dst(jd, iptr, d);
873 dst = VAROP(iptr->dst);
874 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
875 M_MOV(REG_ITMP2, RDX); /* restore RDX */
878 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
880 s1 = emit_load_s1(jd, iptr, RAX);
881 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
882 d = codegen_reg_of_dst(jd, iptr, RDX);
885 M_INTMOVE(s2, REG_ITMP3);
886 emit_arithmetic_check(cd, REG_ITMP3);
888 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
890 /* check as described in jvm spec */
891 disp = dseg_add_s8(cd, 0x8000000000000000LL);
892 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
894 M_LXOR(RDX, RDX); /* 3 bytes */
895 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
896 M_BEQ(2 + 3); /* 6 bytes */
898 emit_cqto(cd); /* 2 bytes */
899 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
902 emit_store_dst(jd, iptr, d);
903 dst = VAROP(iptr->dst);
904 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
905 M_MOV(REG_ITMP2, RDX); /* restore RDX */
908 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
909 /* sx.val.i = constant */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
913 M_INTMOVE(s1, REG_ITMP1);
914 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
915 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
916 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
917 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
918 emit_mov_reg_reg(cd, REG_ITMP1, d);
919 emit_store_dst(jd, iptr, d);
922 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
923 /* sx.val.l = constant */
925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
927 M_INTMOVE(s1, REG_ITMP1);
928 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
929 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
930 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
931 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
932 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
933 emit_mov_reg_reg(cd, REG_ITMP1, d);
934 emit_store_dst(jd, iptr, d);
937 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
939 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
940 emit_ishift(jd, SHIFT_SHL, iptr);
943 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
944 /* sx.val.i = constant */
946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
947 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
949 M_ISLL_IMM(iptr->sx.val.i, d);
950 emit_store_dst(jd, iptr, d);
953 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
955 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
956 emit_ishift(jd, SHIFT_SAR, iptr);
959 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
960 /* sx.val.i = constant */
962 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
963 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
965 M_ISRA_IMM(iptr->sx.val.i, d);
966 emit_store_dst(jd, iptr, d);
969 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
971 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
972 emit_ishift(jd, SHIFT_SHR, iptr);
975 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
976 /* sx.val.i = constant */
978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
979 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
981 M_ISRL_IMM(iptr->sx.val.i, d);
982 emit_store_dst(jd, iptr, d);
985 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
987 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
988 emit_lshift(jd, SHIFT_SHL, iptr);
991 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
992 /* sx.val.i = constant */
994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
997 M_LSLL_IMM(iptr->sx.val.i, d);
998 emit_store_dst(jd, iptr, d);
1001 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1003 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1004 emit_lshift(jd, SHIFT_SAR, iptr);
1007 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1008 /* sx.val.i = constant */
1010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013 M_LSRA_IMM(iptr->sx.val.i, d);
1014 emit_store_dst(jd, iptr, d);
1017 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1019 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1020 emit_lshift(jd, SHIFT_SHR, iptr);
1023 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1024 /* sx.val.l = constant */
1026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1027 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1029 M_LSRL_IMM(iptr->sx.val.i, d);
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1044 emit_store_dst(jd, iptr, d);
1047 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1048 /* sx.val.i = constant */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1053 M_IAND_IMM(iptr->sx.val.i, d);
1054 emit_store_dst(jd, iptr, d);
1057 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1060 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1068 emit_store_dst(jd, iptr, d);
1071 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1072 /* sx.val.l = constant */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1077 if (IS_IMM32(iptr->sx.val.l))
1078 M_LAND_IMM(iptr->sx.val.l, d);
1080 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1081 M_LAND(REG_ITMP2, d);
1083 emit_store_dst(jd, iptr, d);
1086 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1097 emit_store_dst(jd, iptr, d);
1100 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1101 /* sx.val.i = constant */
1103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1104 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1106 M_IOR_IMM(iptr->sx.val.i, d);
1107 emit_store_dst(jd, iptr, d);
1110 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1114 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1121 emit_store_dst(jd, iptr, d);
1124 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1125 /* sx.val.l = constant */
1127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1128 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1130 if (IS_IMM32(iptr->sx.val.l))
1131 M_LOR_IMM(iptr->sx.val.l, d);
1133 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1134 M_LOR(REG_ITMP2, d);
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1150 emit_store_dst(jd, iptr, d);
1153 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1154 /* sx.val.i = constant */
1156 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1157 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1159 M_IXOR_IMM(iptr->sx.val.i, d);
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1166 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1167 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1178 /* sx.val.l = constant */
1180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1183 if (IS_IMM32(iptr->sx.val.l))
1184 M_LXOR_IMM(iptr->sx.val.l, d);
1186 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1187 M_LXOR(REG_ITMP2, d);
1189 emit_store_dst(jd, iptr, d);
1193 /* floating operations ************************************************/
1195 case ICMD_FNEG: /* ..., value ==> ..., - value */
1197 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1198 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1199 disp = dseg_add_s4(cd, 0x80000000);
1201 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1202 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_DNEG: /* ..., value ==> ..., - value */
1208 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1210 disp = dseg_add_s8(cd, 0x8000000000000000);
1212 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1213 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1214 emit_store_dst(jd, iptr, d);
1217 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1219 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1220 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1221 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1233 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1247 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1251 M_FLTMOVE(s2, REG_FTMP2);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1261 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1262 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1263 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1265 M_FLTMOVE(s2, REG_FTMP2);
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1275 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1276 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1277 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1289 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1290 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1291 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1303 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1304 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1305 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1307 M_FLTMOVE(s2, REG_FTMP2);
1312 emit_store_dst(jd, iptr, d);
1315 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1317 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1318 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1319 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1321 M_FLTMOVE(s2, REG_FTMP2);
1326 emit_store_dst(jd, iptr, d);
1329 case ICMD_I2F: /* ..., value ==> ..., (float) 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_I2D: /* ..., value ==> ..., (double) 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_L2F: /* ..., value ==> ..., (float) 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_L2D: /* ..., value ==> ..., (double) value */
1355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1356 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1358 emit_store_dst(jd, iptr, d);
1361 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1363 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1366 M_ICMP_IMM(0x80000000, d); /* corner cases */
1367 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1368 ((REG_RESULT == d) ? 0 : 3);
1370 M_FLTMOVE(s1, REG_FTMP1);
1371 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1373 M_INTMOVE(REG_RESULT, d);
1374 emit_store_dst(jd, iptr, d);
1377 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1379 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1380 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1382 M_ICMP_IMM(0x80000000, d); /* corner cases */
1383 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1384 ((REG_RESULT == d) ? 0 : 3);
1386 M_FLTMOVE(s1, REG_FTMP1);
1387 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1389 M_INTMOVE(REG_RESULT, d);
1390 emit_store_dst(jd, iptr, d);
1393 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1395 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1396 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1398 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1399 M_LCMP(REG_ITMP2, d); /* corner cases */
1400 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1401 ((REG_RESULT == d) ? 0 : 3);
1403 M_FLTMOVE(s1, REG_FTMP1);
1404 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1406 M_INTMOVE(REG_RESULT, d);
1407 emit_store_dst(jd, iptr, d);
1410 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1412 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1413 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1415 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1416 M_LCMP(REG_ITMP2, d); /* corner cases */
1417 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1418 ((REG_RESULT == d) ? 0 : 3);
1420 M_FLTMOVE(s1, REG_FTMP1);
1421 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1423 M_INTMOVE(REG_RESULT, d);
1424 emit_store_dst(jd, iptr, d);
1427 case ICMD_F2D: /* ..., value ==> ..., (double) 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_D2F: /* ..., value ==> ..., (float) value */
1437 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1438 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1440 emit_store_dst(jd, iptr, d);
1443 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1444 /* == => 0, < => 1, > => -1 */
1446 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1447 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1448 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1450 M_MOV_IMM(1, REG_ITMP1);
1451 M_MOV_IMM(-1, REG_ITMP2);
1452 emit_ucomiss_reg_reg(cd, s1, s2);
1453 M_CMOVB(REG_ITMP1, d);
1454 M_CMOVA(REG_ITMP2, d);
1455 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1456 emit_store_dst(jd, iptr, d);
1459 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1460 /* == => 0, < => 1, > => -1 */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1466 M_MOV_IMM(1, REG_ITMP1);
1467 M_MOV_IMM(-1, REG_ITMP2);
1468 emit_ucomiss_reg_reg(cd, s1, s2);
1469 M_CMOVB(REG_ITMP1, d);
1470 M_CMOVA(REG_ITMP2, d);
1471 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1472 emit_store_dst(jd, iptr, d);
1475 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1476 /* == => 0, < => 1, > => -1 */
1478 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1479 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1482 M_MOV_IMM(1, REG_ITMP1);
1483 M_MOV_IMM(-1, REG_ITMP2);
1484 emit_ucomisd_reg_reg(cd, s1, s2);
1485 M_CMOVB(REG_ITMP1, d);
1486 M_CMOVA(REG_ITMP2, d);
1487 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1488 emit_store_dst(jd, iptr, d);
1491 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1492 /* == => 0, < => 1, > => -1 */
1494 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1495 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1496 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1498 M_MOV_IMM(1, REG_ITMP1);
1499 M_MOV_IMM(-1, REG_ITMP2);
1500 emit_ucomisd_reg_reg(cd, s1, s2);
1501 M_CMOVB(REG_ITMP1, d);
1502 M_CMOVA(REG_ITMP2, d);
1503 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1504 emit_store_dst(jd, iptr, d);
1508 /* memory operations **************************************************/
1510 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1513 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1514 emit_nullpointer_check(cd, s1);
1515 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1524 emit_array_checks(cd, iptr, s1, s2);
1525 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1526 emit_store_dst(jd, iptr, d);
1529 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1534 emit_array_checks(cd, iptr, s1, s2);
1535 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1536 emit_store_dst(jd, iptr, d);
1539 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1544 emit_array_checks(cd, iptr, s1, s2);
1545 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1546 emit_store_dst(jd, iptr, d);
1549 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1552 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1554 emit_array_checks(cd, iptr, s1, s2);
1555 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1564 emit_array_checks(cd, iptr, s1, s2);
1565 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1566 emit_store_dst(jd, iptr, d);
1569 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1572 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1573 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1574 emit_array_checks(cd, iptr, s1, s2);
1575 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1576 emit_store_dst(jd, iptr, d);
1579 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1583 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1584 emit_array_checks(cd, iptr, s1, s2);
1585 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1586 emit_store_dst(jd, iptr, d);
1589 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1592 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1594 emit_array_checks(cd, iptr, s1, s2);
1595 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, 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 emit_array_checks(cd, iptr, s1, s2);
1605 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1606 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1609 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1612 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1613 emit_array_checks(cd, iptr, s1, s2);
1614 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1615 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1618 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1622 emit_array_checks(cd, iptr, s1, s2);
1623 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1624 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1627 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1631 emit_array_checks(cd, iptr, s1, s2);
1632 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1633 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1636 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1639 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1640 emit_array_checks(cd, iptr, s1, s2);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1645 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1649 emit_array_checks(cd, iptr, s1, s2);
1650 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1651 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1654 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1657 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1658 emit_array_checks(cd, iptr, s1, s2);
1659 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1660 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1663 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1667 emit_array_checks(cd, iptr, s1, s2);
1668 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1672 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1676 codegen_add_arraystoreexception_ref(cd);
1678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1680 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1681 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1685 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1688 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1689 emit_array_checks(cd, iptr, s1, s2);
1690 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1693 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 emit_array_checks(cd, iptr, s1, s2);
1698 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1701 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1704 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1705 emit_array_checks(cd, iptr, s1, s2);
1706 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1709 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1713 emit_array_checks(cd, iptr, s1, s2);
1714 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1717 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1720 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1721 emit_array_checks(cd, iptr, s1, s2);
1723 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1724 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1726 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1727 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1731 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1735 emit_array_checks(cd, iptr, s1, s2);
1736 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1740 case ICMD_GETSTATIC: /* ... ==> ..., value */
1742 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1743 uf = iptr->sx.s23.s3.uf;
1744 fieldtype = uf->fieldref->parseddesc.fd->type;
1745 disp = dseg_add_unique_address(cd, NULL);
1746 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1748 /* must be calculated before codegen_add_patch_ref */
1751 disp -= PATCHER_CALL_SIZE;
1753 /* PROFILE_CYCLE_STOP; */
1755 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1757 /* PROFILE_CYCLE_START; */
1760 fi = iptr->sx.s23.s3.fmiref->p.field;
1761 fieldtype = fi->type;
1762 disp = dseg_add_address(cd, &(fi->value));
1763 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1765 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1768 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1771 disp -= PATCHER_CALL_SIZE;
1773 PROFILE_CYCLE_START;
1777 /* This approach is much faster than moving the field
1778 address inline into a register. */
1780 M_ALD(REG_ITMP1, RIP, disp);
1782 switch (fieldtype) {
1784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1785 M_ILD(d, REG_ITMP1, 0);
1789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1790 M_LLD(d, REG_ITMP1, 0);
1793 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1794 M_FLD(d, REG_ITMP1, 0);
1797 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1798 M_DLD(d, REG_ITMP1, 0);
1801 emit_store_dst(jd, iptr, d);
1804 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1806 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1807 uf = iptr->sx.s23.s3.uf;
1808 fieldtype = uf->fieldref->parseddesc.fd->type;
1809 disp = dseg_add_unique_address(cd, NULL);
1810 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1812 /* must be calculated before codegen_add_patch_ref */
1815 disp -= PATCHER_CALL_SIZE;
1817 /* PROFILE_CYCLE_STOP; */
1819 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1821 /* PROFILE_CYCLE_START; */
1824 fi = iptr->sx.s23.s3.fmiref->p.field;
1825 fieldtype = fi->type;
1826 disp = dseg_add_address(cd, &(fi->value));
1827 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1829 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1832 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1835 disp -= PATCHER_CALL_SIZE;
1837 PROFILE_CYCLE_START;
1841 /* This approach is much faster than moving the field
1842 address inline into a register. */
1844 M_ALD(REG_ITMP1, RIP, disp);
1846 switch (fieldtype) {
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1849 M_IST(s1, REG_ITMP1, 0);
1853 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1854 M_LST(s1, REG_ITMP1, 0);
1857 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1858 M_FST(s1, REG_ITMP1, 0);
1861 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1862 M_DST(s1, REG_ITMP1, 0);
1867 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1868 /* val = value (in current instruction) */
1869 /* following NOP) */
1871 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1872 uf = iptr->sx.s23.s3.uf;
1873 fieldtype = uf->fieldref->parseddesc.fd->type;
1874 disp = dseg_add_unique_address(cd, NULL);
1875 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1877 /* must be calculated before codegen_add_patch_ref */
1880 disp -= PATCHER_CALL_SIZE;
1883 /* PROFILE_CYCLE_STOP; */
1885 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1887 /* PROFILE_CYCLE_START; */
1890 fi = iptr->sx.s23.s3.fmiref->p.field;
1891 fieldtype = fi->type;
1892 disp = dseg_add_address(cd, &(fi->value));
1893 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1895 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1898 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1901 disp -= PATCHER_CALL_SIZE;
1903 PROFILE_CYCLE_START;
1907 /* This approach is much faster than moving the field
1908 address inline into a register. */
1910 M_ALD(REG_ITMP1, RIP, disp);
1912 switch (fieldtype) {
1915 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1920 if (IS_IMM32(iptr->sx.s23.s2.constval))
1921 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1923 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1924 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1930 case ICMD_GETFIELD: /* ... ==> ..., value */
1932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1933 emit_nullpointer_check(cd, s1);
1935 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1936 uf = iptr->sx.s23.s3.uf;
1937 fieldtype = uf->fieldref->parseddesc.fd->type;
1940 /* PROFILE_CYCLE_STOP; */
1942 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1944 /* PROFILE_CYCLE_START; */
1947 fi = iptr->sx.s23.s3.fmiref->p.field;
1948 fieldtype = fi->type;
1952 switch (fieldtype) {
1954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1955 M_ILD32(d, s1, disp);
1959 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1960 M_LLD32(d, s1, disp);
1963 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1964 M_FLD32(d, s1, disp);
1967 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1968 M_DLD32(d, s1, disp);
1971 emit_store_dst(jd, iptr, d);
1974 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1976 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1977 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1978 emit_nullpointer_check(cd, s1);
1980 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1981 uf = iptr->sx.s23.s3.uf;
1982 fieldtype = uf->fieldref->parseddesc.fd->type;
1985 /* PROFILE_CYCLE_STOP; */
1987 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1989 /* PROFILE_CYCLE_START; */
1992 fi = iptr->sx.s23.s3.fmiref->p.field;
1993 fieldtype = fi->type;
1997 switch (fieldtype) {
1999 M_IST32(s2, s1, disp);
2003 M_LST32(s2, s1, disp);
2006 M_FST32(s2, s1, disp);
2009 M_DST32(s2, s1, disp);
2014 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2015 /* val = value (in current instruction) */
2016 /* following NOP) */
2018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019 emit_nullpointer_check(cd, s1);
2021 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2022 uf = iptr->sx.s23.s3.uf;
2023 fieldtype = uf->fieldref->parseddesc.fd->type;
2026 /* PROFILE_CYCLE_STOP; */
2028 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2030 /* PROFILE_CYCLE_START; */
2033 fi = iptr->sx.s23.s3.fmiref->p.field;
2034 fieldtype = fi->type;
2038 switch (fieldtype) {
2041 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2046 /* XXX why no check for IS_IMM32? */
2047 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2048 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2054 /* branch operations **************************************************/
2056 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2059 M_INTMOVE(s1, REG_ITMP1_XPTR);
2063 #ifdef ENABLE_VERIFIER
2064 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2065 uc = iptr->sx.s23.s2.uc;
2067 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2069 #endif /* ENABLE_VERIFIER */
2071 M_CALL_IMM(0); /* passing exception pc */
2072 M_POP(REG_ITMP2_XPC);
2074 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2078 case ICMD_GOTO: /* ... ==> ... */
2079 case ICMD_RET: /* ... ==> ... */
2082 codegen_add_branch_ref(cd, iptr->dst.block);
2085 case ICMD_JSR: /* ... ==> ... */
2088 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2091 case ICMD_IFNULL: /* ..., value ==> ... */
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2096 codegen_add_branch_ref(cd, iptr->dst.block);
2099 case ICMD_IFNONNULL: /* ..., value ==> ... */
2101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 codegen_add_branch_ref(cd, iptr->dst.block);
2107 case ICMD_IFEQ: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 M_ICMP_IMM(iptr->sx.val.i, s1);
2112 codegen_add_branch_ref(cd, iptr->dst.block);
2115 case ICMD_IFLT: /* ..., value ==> ... */
2117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2118 M_ICMP_IMM(iptr->sx.val.i, s1);
2120 codegen_add_branch_ref(cd, iptr->dst.block);
2123 case ICMD_IFLE: /* ..., value ==> ... */
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 M_ICMP_IMM(iptr->sx.val.i, s1);
2128 codegen_add_branch_ref(cd, iptr->dst.block);
2131 case ICMD_IFNE: /* ..., value ==> ... */
2133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2134 M_ICMP_IMM(iptr->sx.val.i, s1);
2136 codegen_add_branch_ref(cd, iptr->dst.block);
2139 case ICMD_IFGT: /* ..., value ==> ... */
2141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2142 M_ICMP_IMM(iptr->sx.val.i, s1);
2144 codegen_add_branch_ref(cd, iptr->dst.block);
2147 case ICMD_IFGE: /* ..., value ==> ... */
2149 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2150 M_ICMP_IMM(iptr->sx.val.i, s1);
2152 codegen_add_branch_ref(cd, iptr->dst.block);
2155 case ICMD_IF_LEQ: /* ..., value ==> ... */
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158 if (IS_IMM32(iptr->sx.val.l))
2159 M_LCMP_IMM(iptr->sx.val.l, s1);
2161 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2162 M_LCMP(REG_ITMP2, s1);
2165 codegen_add_branch_ref(cd, iptr->dst.block);
2168 case ICMD_IF_LLT: /* ..., value ==> ... */
2170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171 if (IS_IMM32(iptr->sx.val.l))
2172 M_LCMP_IMM(iptr->sx.val.l, s1);
2174 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2175 M_LCMP(REG_ITMP2, s1);
2178 codegen_add_branch_ref(cd, iptr->dst.block);
2181 case ICMD_IF_LLE: /* ..., value ==> ... */
2183 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2184 if (IS_IMM32(iptr->sx.val.l))
2185 M_LCMP_IMM(iptr->sx.val.l, s1);
2187 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2188 M_LCMP(REG_ITMP2, s1);
2191 codegen_add_branch_ref(cd, iptr->dst.block);
2194 case ICMD_IF_LNE: /* ..., value ==> ... */
2196 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2197 if (IS_IMM32(iptr->sx.val.l))
2198 M_LCMP_IMM(iptr->sx.val.l, s1);
2200 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2201 M_LCMP(REG_ITMP2, s1);
2204 codegen_add_branch_ref(cd, iptr->dst.block);
2207 case ICMD_IF_LGT: /* ..., value ==> ... */
2209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2210 if (IS_IMM32(iptr->sx.val.l))
2211 M_LCMP_IMM(iptr->sx.val.l, s1);
2213 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2214 M_LCMP(REG_ITMP2, s1);
2217 codegen_add_branch_ref(cd, iptr->dst.block);
2220 case ICMD_IF_LGE: /* ..., value ==> ... */
2222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2223 if (IS_IMM32(iptr->sx.val.l))
2224 M_LCMP_IMM(iptr->sx.val.l, s1);
2226 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2227 M_LCMP(REG_ITMP2, s1);
2230 codegen_add_branch_ref(cd, iptr->dst.block);
2233 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2239 codegen_add_branch_ref(cd, iptr->dst.block);
2242 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2243 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2245 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2246 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2249 codegen_add_branch_ref(cd, iptr->dst.block);
2252 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2255 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2258 codegen_add_branch_ref(cd, iptr->dst.block);
2261 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2262 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2264 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2265 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2268 codegen_add_branch_ref(cd, iptr->dst.block);
2271 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2273 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2274 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2277 codegen_add_branch_ref(cd, iptr->dst.block);
2280 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2283 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2286 codegen_add_branch_ref(cd, iptr->dst.block);
2289 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2292 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2295 codegen_add_branch_ref(cd, iptr->dst.block);
2298 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2304 codegen_add_branch_ref(cd, iptr->dst.block);
2307 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2313 codegen_add_branch_ref(cd, iptr->dst.block);
2316 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2322 codegen_add_branch_ref(cd, iptr->dst.block);
2325 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2331 codegen_add_branch_ref(cd, iptr->dst.block);
2334 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2340 codegen_add_branch_ref(cd, iptr->dst.block);
2343 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2346 REPLACEMENT_POINT_RETURN(cd, iptr);
2347 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2348 M_INTMOVE(s1, REG_RESULT);
2349 goto nowperformreturn;
2351 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2353 REPLACEMENT_POINT_RETURN(cd, iptr);
2354 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2355 M_INTMOVE(s1, REG_RESULT);
2357 #ifdef ENABLE_VERIFIER
2358 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2359 uc = iptr->sx.s23.s2.uc;
2363 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2365 PROFILE_CYCLE_START;
2367 #endif /* ENABLE_VERIFIER */
2368 goto nowperformreturn;
2370 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2373 REPLACEMENT_POINT_RETURN(cd, iptr);
2374 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2375 M_FLTMOVE(s1, REG_FRESULT);
2376 goto nowperformreturn;
2378 case ICMD_RETURN: /* ... ==> ... */
2380 REPLACEMENT_POINT_RETURN(cd, iptr);
2386 p = cd->stackframesize;
2388 #if !defined(NDEBUG)
2389 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2390 emit_verbosecall_exit(jd);
2391 #endif /* !defined(NDEBUG) */
2393 #if defined(ENABLE_THREADS)
2394 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2395 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2397 /* we need to save the proper return value */
2398 switch (iptr->opc) {
2402 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2406 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2410 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2413 /* and now restore the proper return value */
2414 switch (iptr->opc) {
2418 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2422 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2428 /* restore saved registers */
2430 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2431 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2433 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2434 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2437 /* deallocate stack */
2439 if (cd->stackframesize)
2440 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2442 /* generate method profiling code */
2451 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2454 branch_target_t *table;
2456 table = iptr->dst.table;
2458 l = iptr->sx.s23.s2.tablelow;
2459 i = iptr->sx.s23.s3.tablehigh;
2461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2462 M_INTMOVE(s1, REG_ITMP1);
2465 M_ISUB_IMM(l, REG_ITMP1);
2467 /* number of targets */
2471 M_ICMP_IMM(i - 1, REG_ITMP1);
2474 codegen_add_branch_ref(cd, table[0].block); /* default target */
2476 /* build jump table top down and use address of lowest entry */
2481 dseg_add_target(cd, table->block);
2485 /* length of dataseg after last dseg_add_target is used
2488 M_MOV_IMM(0, REG_ITMP2);
2490 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2496 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2499 lookup_target_t *lookup;
2501 lookup = iptr->dst.lookup;
2503 i = iptr->sx.s23.s2.lookupcount;
2505 MCODECHECK(8 + ((7 + 6) * i) + 5);
2506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2509 M_ICMP_IMM(lookup->value, s1);
2511 codegen_add_branch_ref(cd, lookup->target.block);
2517 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2522 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2524 bte = iptr->sx.s23.s3.bte;
2528 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2530 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2531 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2532 case ICMD_INVOKEINTERFACE:
2534 REPLACEMENT_POINT_INVOKE(cd, iptr);
2536 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2538 um = iptr->sx.s23.s3.um;
2539 md = um->methodref->parseddesc.md;
2542 lm = iptr->sx.s23.s3.fmiref->p.method;
2544 md = lm->parseddesc;
2548 s3 = md->paramcount;
2550 MCODECHECK((20 * s3) + 128);
2552 /* copy arguments to registers or stack location */
2554 for (s3 = s3 - 1; s3 >= 0; s3--) {
2555 var = VAR(iptr->sx.s23.s2.args[s3]);
2557 /* Already Preallocated (ARGVAR) ? */
2558 if (var->flags & PREALLOC)
2561 if (IS_INT_LNG_TYPE(var->type)) {
2562 if (!md->params[s3].inmemory) {
2563 s1 = rd->argintregs[md->params[s3].regoff];
2564 d = emit_load(jd, iptr, var, s1);
2568 d = emit_load(jd, iptr, var, REG_ITMP1);
2569 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2573 if (!md->params[s3].inmemory) {
2574 s1 = rd->argfltregs[md->params[s3].regoff];
2575 d = emit_load(jd, iptr, var, s1);
2579 d = emit_load(jd, iptr, var, REG_FTMP1);
2581 if (IS_2_WORD_TYPE(var->type))
2582 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2584 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2589 /* generate method profiling code */
2593 switch (iptr->opc) {
2595 M_MOV_IMM(bte->fp, REG_ITMP1);
2598 if (INSTRUCTION_MUST_CHECK(iptr)) {
2601 codegen_add_fillinstacktrace_ref(cd);
2605 case ICMD_INVOKESPECIAL:
2608 codegen_add_nullpointerexception_ref(cd);
2612 case ICMD_INVOKESTATIC:
2614 disp = dseg_add_unique_address(cd, NULL);
2615 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2617 /* must be calculated before codegen_add_patch_ref */
2620 disp -= PATCHER_CALL_SIZE;
2622 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2628 disp = dseg_add_functionptr(cd, lm->stubroutine);
2629 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2631 /* a = (ptrint) lm->stubroutine; */
2634 /* M_MOV_IMM(a, REG_ITMP2); */
2635 M_ALD(REG_ITMP2, RIP, disp);
2639 case ICMD_INVOKEVIRTUAL:
2640 emit_nullpointer_check(cd, REG_A0);
2643 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2648 s1 = OFFSET(vftbl_t, table[0]) +
2649 sizeof(methodptr) * lm->vftblindex;
2651 M_ALD(REG_METHODPTR, REG_A0,
2652 OFFSET(java_objectheader, vftbl));
2653 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2657 case ICMD_INVOKEINTERFACE:
2658 emit_nullpointer_check(cd, REG_A0);
2661 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2667 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2668 sizeof(methodptr) * lm->class->index;
2670 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2673 M_ALD(REG_METHODPTR, REG_A0,
2674 OFFSET(java_objectheader, vftbl));
2675 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2676 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2681 /* generate method profiling code */
2683 PROFILE_CYCLE_START;
2685 /* store size of call code in replacement point */
2687 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2689 /* store return value */
2691 d = md->returntype.type;
2693 if (d != TYPE_VOID) {
2694 if (IS_INT_LNG_TYPE(d)) {
2695 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2696 M_INTMOVE(REG_RESULT, s1);
2699 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2700 M_FLTMOVE(REG_FRESULT, s1);
2702 emit_store_dst(jd, iptr, s1);
2707 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2709 /* val.a: (classinfo *) superclass */
2711 /* superclass is an interface:
2713 * OK if ((sub == NULL) ||
2714 * (sub->vftbl->interfacetablelength > super->index) &&
2715 * (sub->vftbl->interfacetable[-super->index] != NULL));
2717 * superclass is a class:
2719 * OK if ((sub == NULL) || (0
2720 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2721 * super->vftbl->diffval));
2724 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2725 /* object type cast-check */
2728 vftbl_t *supervftbl;
2731 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2737 super = iptr->sx.s23.s3.c.cls;
2738 superindex = super->index;
2739 supervftbl = super->vftbl;
2742 #if defined(ENABLE_THREADS)
2743 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2747 /* calculate interface checkcast code size */
2749 s2 = 3; /* mov_membase_reg */
2750 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
2752 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
2753 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
2754 3 /* test */ + 6 /* jcc */;
2757 s2 += (opt_shownops ? 5 : 0);
2759 /* calculate class checkcast code size */
2761 s3 = 3; /* mov_membase_reg */
2762 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
2763 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
2766 if (s1 != REG_ITMP1) {
2767 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
2768 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
2769 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
2770 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
2776 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
2777 10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
2778 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2781 s3 += 3 /* cmp */ + 6 /* jcc */;
2784 s3 += (opt_shownops ? 5 : 0);
2786 /* if class is not resolved, check which code to call */
2788 if (super == NULL) {
2790 M_BEQ(6 + (opt_shownops ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
2792 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2793 iptr->sx.s23.s3.c.ref, 0);
2795 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2796 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2800 /* interface checkcast code */
2802 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2803 if (super != NULL) {
2808 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2810 if (super == NULL) {
2811 codegen_add_patch_ref(cd,
2812 PATCHER_checkcast_instanceof_interface,
2813 iptr->sx.s23.s3.c.ref,
2817 emit_movl_membase32_reg(cd, REG_ITMP2,
2818 OFFSET(vftbl_t, interfacetablelength),
2820 /* XXX TWISTI: should this be int arithmetic? */
2821 M_LSUB_IMM32(superindex, REG_ITMP3);
2824 codegen_add_classcastexception_ref(cd, s1);
2825 emit_mov_membase32_reg(cd, REG_ITMP2,
2826 OFFSET(vftbl_t, interfacetable[0]) -
2827 superindex * sizeof(methodptr*),
2831 codegen_add_classcastexception_ref(cd, s1);
2837 /* class checkcast code */
2839 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2840 if (super != NULL) {
2845 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2847 if (super == NULL) {
2848 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
2849 iptr->sx.s23.s3.c.ref,
2853 M_MOV_IMM(supervftbl, REG_ITMP3);
2854 #if defined(ENABLE_THREADS)
2855 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2857 emit_movl_membase32_reg(cd, REG_ITMP2,
2858 OFFSET(vftbl_t, baseval),
2860 /* if (s1 != REG_ITMP1) { */
2861 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2862 /* OFFSET(vftbl_t, baseval), */
2864 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2865 /* OFFSET(vftbl_t, diffval), */
2867 /* #if defined(ENABLE_THREADS) */
2868 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2870 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2873 emit_movl_membase32_reg(cd, REG_ITMP3,
2874 OFFSET(vftbl_t, baseval),
2876 M_LSUB(REG_ITMP3, REG_ITMP2);
2877 M_MOV_IMM(supervftbl, REG_ITMP3);
2878 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2880 #if defined(ENABLE_THREADS)
2881 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2883 M_LCMP(REG_ITMP3, REG_ITMP2);
2884 M_BA(0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
2885 codegen_add_classcastexception_ref(cd, s1);
2888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2891 /* array type cast-check */
2893 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2894 M_INTMOVE(s1, REG_A0);
2896 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2897 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2898 iptr->sx.s23.s3.c.ref, 0);
2901 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2902 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2905 /* s1 may have been destroyed over the function call */
2906 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2909 codegen_add_classcastexception_ref(cd, s1);
2911 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2915 emit_store_dst(jd, iptr, d);
2918 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2920 /* val.a: (classinfo *) superclass */
2922 /* superclass is an interface:
2924 * return (sub != NULL) &&
2925 * (sub->vftbl->interfacetablelength > super->index) &&
2926 * (sub->vftbl->interfacetable[-super->index] != NULL);
2928 * superclass is a class:
2930 * return ((sub != NULL) && (0
2931 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2932 * super->vftbl->diffvall));
2937 vftbl_t *supervftbl;
2940 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2946 super = iptr->sx.s23.s3.c.cls;
2947 superindex = super->index;
2948 supervftbl = super->vftbl;
2951 #if defined(ENABLE_THREADS)
2952 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2956 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2958 M_INTMOVE(s1, REG_ITMP1);
2962 /* calculate interface instanceof code size */
2964 s2 = 3; /* mov_membase_reg */
2965 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
2966 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub_imm32 */ +
2967 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
2968 3 /* test */ + 4 /* setcc */;
2971 s2 += (opt_shownops ? 5 : 0);
2973 /* calculate class instanceof code size */
2975 s3 = 3; /* mov_membase_reg */
2976 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
2977 s3 += 10; /* mov_imm_reg */
2978 s3 += 2; /* movl_membase_reg - only if REG_ITMP1 == RAX */
2979 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
2980 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
2981 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2982 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
2983 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2984 s3 += 3 /* sub */ + 3 /* xor */ + 3 /* cmp */ + 4 /* setcc */;
2987 s3 += (opt_shownops ? 5 : 0);
2989 emit_alu_reg_reg(cd, ALU_XOR, d, d);
2991 /* if class is not resolved, check which code to call */
2993 if (super == NULL) {
2994 emit_test_reg_reg(cd, s1, s1);
2995 emit_jcc(cd, CC_Z, (6 + (opt_shownops ? 5 : 0) +
2996 7 + 6 + s2 + 5 + s3));
2998 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2999 iptr->sx.s23.s3.c.ref, 0);
3001 emit_movl_imm_reg(cd, 0, REG_ITMP3); /* super->flags */
3002 emit_alul_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP3);
3003 emit_jcc(cd, CC_Z, s2 + 5);
3006 /* interface instanceof code */
3008 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3009 if (super != NULL) {
3010 emit_test_reg_reg(cd, s1, s1);
3011 emit_jcc(cd, CC_Z, s2);
3014 emit_mov_membase_reg(cd, s1,
3015 OFFSET(java_objectheader, vftbl),
3018 if (super == NULL) {
3019 codegen_add_patch_ref(cd,
3020 PATCHER_checkcast_instanceof_interface,
3021 iptr->sx.s23.s3.c.ref, 0);
3024 emit_movl_membase32_reg(cd, REG_ITMP1,
3025 OFFSET(vftbl_t, interfacetablelength),
3027 emit_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
3028 emit_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
3030 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
3032 emit_jcc(cd, CC_LE, a);
3033 emit_mov_membase32_reg(cd, REG_ITMP1,
3034 OFFSET(vftbl_t, interfacetable[0]) -
3035 superindex * sizeof(methodptr*),
3037 emit_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3038 emit_setcc_reg(cd, CC_NE, d);
3041 emit_jmp_imm(cd, s3);
3044 /* class instanceof code */
3046 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3047 if (super != NULL) {
3048 emit_test_reg_reg(cd, s1, s1);
3049 emit_jcc(cd, CC_E, s3);
3052 emit_mov_membase_reg(cd, s1,
3053 OFFSET(java_objectheader, vftbl),
3056 if (super == NULL) {
3057 codegen_add_patch_ref(cd, PATCHER_instanceof_class,
3058 iptr->sx.s23.s3.c.ref, 0);
3061 emit_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP2);
3062 #if defined(ENABLE_THREADS)
3063 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3065 emit_movl_membase_reg(cd, REG_ITMP1,
3066 OFFSET(vftbl_t, baseval),
3068 emit_movl_membase_reg(cd, REG_ITMP2,
3069 OFFSET(vftbl_t, diffval),
3071 emit_movl_membase_reg(cd, REG_ITMP2,
3072 OFFSET(vftbl_t, baseval),
3074 #if defined(ENABLE_THREADS)
3075 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3077 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
3078 emit_alu_reg_reg(cd, ALU_XOR, d, d); /* may be REG_ITMP2 */
3079 emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP1);
3080 emit_setcc_reg(cd, CC_BE, d);
3082 emit_store_dst(jd, iptr, d);
3086 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3088 /* check for negative sizes and copy sizes to stack if necessary */
3090 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3092 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3094 /* copy SAVEDVAR sizes to stack */
3095 var = VAR(iptr->sx.s23.s2.args[s1]);
3097 /* Already Preallocated? */
3098 if (!(var->flags & PREALLOC)) {
3099 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3100 M_LST(s2, REG_SP, s1 * 8);
3104 /* is a patcher function set? */
3106 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3107 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3108 iptr->sx.s23.s3.c.ref, 0);
3111 /* a0 = dimension count */
3113 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3115 /* a1 = classinfo */
3117 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3119 /* a2 = pointer to dimensions = stack pointer */
3121 M_MOV(REG_SP, REG_A2);
3123 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3126 /* check for exception before result assignment */
3130 codegen_add_fillinstacktrace_ref(cd);
3132 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3133 M_INTMOVE(REG_RESULT, s1);
3134 emit_store_dst(jd, iptr, s1);
3138 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3142 } /* for instruction */
3144 MCODECHECK(512); /* XXX require a lower number? */
3146 /* At the end of a basic block we may have to append some nops,
3147 because the patcher stub calling code might be longer than the
3148 actual instruction. So codepatching does not change the
3149 following block unintentionally. */
3151 if (cd->mcodeptr < cd->lastmcodeptr) {
3152 while (cd->mcodeptr < cd->lastmcodeptr) {
3157 } /* if (bptr -> flags >= BBREACHED) */
3158 } /* for basic block */
3160 dseg_createlinenumbertable(cd);
3162 /* generate stubs */
3164 emit_exception_stubs(jd);
3165 emit_patcher_stubs(jd);
3166 REPLACEMENT_EMIT_STUBS(jd);
3170 /* everything's ok */
3176 /* createcompilerstub **********************************************************
3178 Creates a stub routine which calls the compiler.
3180 *******************************************************************************/
3182 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3183 #define COMPILERSTUB_CODESIZE 7 + 7 + 3
3185 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3188 u1 *createcompilerstub(methodinfo *m)
3190 u1 *s; /* memory to hold the stub */
3195 s = CNEW(u1, COMPILERSTUB_SIZE);
3197 /* set data pointer and code pointer */
3200 s = s + COMPILERSTUB_DATASIZE;
3202 /* mark start of dump memory area */
3204 dumpsize = dump_size();
3206 cd = DNEW(codegendata);
3209 /* The codeinfo pointer is actually a pointer to the
3210 methodinfo. This fakes a codeinfo structure. */
3212 d[0] = (ptrint) asm_call_jit_compiler;
3214 d[2] = (ptrint) &d[1]; /* fake code->m */
3216 /* code for the stub */
3218 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
3219 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
3222 #if defined(ENABLE_STATISTICS)
3224 count_cstub_len += COMPILERSTUB_SIZE;
3227 /* release dump area */
3229 dump_release(dumpsize);
3235 /* createnativestub ************************************************************
3237 Creates a stub routine which calls a native method.
3239 *******************************************************************************/
3241 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3249 s4 i, j; /* count variables */
3253 /* get required compiler data */
3260 /* initialize variables */
3263 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3265 /* calculate stack frame size */
3267 cd->stackframesize =
3268 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3269 sizeof(localref_table) / SIZEOF_VOID_P +
3270 INT_ARG_CNT + FLT_ARG_CNT +
3271 1 + /* functionptr, TODO: store in data segment */
3274 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3276 /* create method header */
3278 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3279 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3280 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3281 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3282 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3283 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3284 (void) dseg_addlinenumbertablesize(cd);
3285 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3287 /* generate native method profiling code */
3289 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3290 /* count frequency */
3292 M_MOV_IMM(code, REG_ITMP3);
3293 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3296 /* generate stub code */
3298 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3300 #if !defined(NDEBUG)
3301 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3302 emit_verbosecall_enter(jd);
3305 /* get function address (this must happen before the stackframeinfo) */
3307 #if !defined(WITH_STATIC_CLASSPATH)
3309 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3312 M_MOV_IMM(f, REG_ITMP3);
3315 /* save integer and float argument registers */
3317 for (i = 0, j = 0; i < md->paramcount; i++) {
3318 if (!md->params[i].inmemory) {
3319 s1 = md->params[i].regoff;
3321 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3322 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3324 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3330 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3332 /* create dynamic stack info */
3334 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3335 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3336 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3337 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3338 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3341 /* restore integer and float argument registers */
3343 for (i = 0, j = 0; i < md->paramcount; i++) {
3344 if (!md->params[i].inmemory) {
3345 s1 = md->params[i].regoff;
3347 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3348 M_LLD(rd->argintregs[s1], REG_SP, j * 8);
3350 M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
3356 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3359 /* copy or spill arguments to new locations */
3361 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3362 t = md->paramtypes[i].type;
3364 if (IS_INT_LNG_TYPE(t)) {
3365 if (!md->params[i].inmemory) {
3366 s1 = rd->argintregs[md->params[i].regoff];
3368 if (!nmd->params[j].inmemory) {
3369 s2 = rd->argintregs[nmd->params[j].regoff];
3373 s2 = nmd->params[j].regoff;
3374 M_LST(s1, REG_SP, s2 * 8);
3378 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3379 s2 = nmd->params[j].regoff;
3380 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3381 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3385 /* We only copy spilled float arguments, as the float argument */
3386 /* registers keep unchanged. */
3388 if (md->params[i].inmemory) {
3389 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3390 s2 = nmd->params[j].regoff;
3392 if (IS_2_WORD_TYPE(t)) {
3393 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3394 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3396 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3397 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3403 /* put class into second argument register */
3405 if (m->flags & ACC_STATIC)
3406 M_MOV_IMM(m->class, REG_A1);
3408 /* put env into first argument register */
3410 M_MOV_IMM(_Jv_env, REG_A0);
3412 /* do the native function call */
3416 /* save return value */
3418 if (md->returntype.type != TYPE_VOID) {
3419 if (IS_INT_LNG_TYPE(md->returntype.type))
3420 M_LST(REG_RESULT, REG_SP, 0 * 8);
3422 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3425 #if !defined(NDEBUG)
3426 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3427 emit_verbosecall_exit(jd);
3430 /* remove native stackframe info */
3432 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3433 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3435 M_MOV(REG_RESULT, REG_ITMP3);
3437 /* restore return value */
3439 if (md->returntype.type != TYPE_VOID) {
3440 if (IS_INT_LNG_TYPE(md->returntype.type))
3441 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3443 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3446 /* remove stackframe */
3448 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3450 /* test for exception */
3456 /* handle exception */
3458 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3459 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3460 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3462 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3465 /* generate patcher stubs */
3467 emit_patcher_stubs(jd);
3471 return code->entrypoint;
3476 * These are local overrides for various environment variables in Emacs.
3477 * Please do not remove this and leave it at the end of the file, where
3478 * Emacs will automagically detect them.
3479 * ---------------------------------------------------------------------
3482 * indent-tabs-mode: t
3486 * vim:noexpandtab:sw=4:ts=4: