1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 7281 2007-02-03 19:51:36Z twisti $
39 #include "vm/jit/x86_64/arch.h"
40 #include "vm/jit/x86_64/codegen.h"
41 #include "vm/jit/x86_64/emit.h"
43 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
47 #if defined(ENABLE_THREADS)
48 # include "threads/native/lock.h"
51 #include "vm/builtin.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/stringlocal.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/methodheader.h"
63 #include "vm/jit/parse.h"
64 #include "vm/jit/patcher.h"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/replace.h"
67 #include "vm/jit/stacktrace.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
75 #include "vmcore/statistics.h"
78 /* codegen *********************************************************************
80 Generates machine code.
82 *******************************************************************************/
84 bool codegen(jitdata *jd)
90 s4 len, s1, s2, s3, d, disp;
97 constant_classref *cr;
99 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
100 unresolved_method *um;
101 builtintable_entry *bte;
104 unresolved_field *uf;
108 /* get required compiler data */
115 /* prevent compiler warnings */
128 /* space to save used callee saved registers */
130 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
131 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
133 cd->stackframesize = rd->memuse + savedregs_num;
135 #if defined(ENABLE_THREADS)
136 /* space to save argument of monitor_enter */
138 if (checksync && (m->flags & ACC_SYNCHRONIZED))
139 cd->stackframesize++;
142 /* Keep stack of non-leaf functions 16-byte aligned for calls into
143 native code e.g. libc or jni (alignment problems with
146 if (!jd->isleafmethod || opt_verbosecall)
147 cd->stackframesize |= 0x1;
149 /* create method header */
151 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
152 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
154 #if defined(ENABLE_THREADS)
155 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
161 if (checksync && (m->flags & ACC_SYNCHRONIZED))
162 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
165 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
167 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
168 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
169 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
171 (void) dseg_addlinenumbertablesize(cd);
173 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
175 /* create exception table */
177 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
178 dseg_add_target(cd, ex->start);
179 dseg_add_target(cd, ex->end);
180 dseg_add_target(cd, ex->handler);
181 (void) dseg_add_unique_address(cd, ex->catchtype.any);
184 #if defined(ENABLE_PROFILING)
185 /* generate method profiling code */
187 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
188 /* count frequency */
190 M_MOV_IMM(code, REG_ITMP3);
191 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
197 /* create stack frame (if necessary) */
199 if (cd->stackframesize)
200 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
202 /* save used callee saved registers */
204 p = cd->stackframesize;
205 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
206 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
208 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
209 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
212 /* take arguments out of register or stack frame */
216 for (p = 0, l = 0; p < md->paramcount; p++) {
217 t = md->paramtypes[p].type;
219 varindex = jd->local_map[l * 5 + t];
222 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
225 if (varindex == UNUSED)
230 s1 = md->params[p].regoff;
232 if (IS_INT_LNG_TYPE(t)) { /* integer args */
233 s2 = rd->argintregs[s1];
234 if (!md->params[p].inmemory) { /* register arguments */
235 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
236 M_INTMOVE(s2, var->vv.regoff);
238 } else { /* reg arg -> spilled */
239 M_LST(s2, REG_SP, var->vv.regoff * 8);
242 } else { /* stack arguments */
243 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
244 /* + 8 for return address */
245 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
247 } else { /* stack arg -> spilled */
248 var->vv.regoff = cd->stackframesize + s1 + 1;
252 } else { /* floating args */
253 if (!md->params[p].inmemory) { /* register arguments */
254 s2 = rd->argfltregs[s1];
255 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
256 M_FLTMOVE(s2, var->vv.regoff);
258 } else { /* reg arg -> spilled */
259 M_DST(s2, REG_SP, var->vv.regoff * 8);
262 } else { /* stack arguments */
263 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
264 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
267 var->vv.regoff = cd->stackframesize + s1 + 1;
273 /* save monitorenter argument */
275 #if defined(ENABLE_THREADS)
276 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
277 /* stack offset for monitor argument */
281 if (opt_verbosecall) {
282 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
284 for (p = 0; p < INT_ARG_CNT; p++)
285 M_LST(rd->argintregs[p], REG_SP, p * 8);
287 for (p = 0; p < FLT_ARG_CNT; p++)
288 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
290 s1 += INT_ARG_CNT + FLT_ARG_CNT;
293 /* decide which monitor enter function to call */
295 if (m->flags & ACC_STATIC) {
296 M_MOV_IMM(&m->class->object.header, REG_A0);
301 codegen_add_nullpointerexception_ref(cd);
304 M_AST(REG_A0, REG_SP, s1 * 8);
305 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
308 if (opt_verbosecall) {
309 for (p = 0; p < INT_ARG_CNT; p++)
310 M_LLD(rd->argintregs[p], REG_SP, p * 8);
312 for (p = 0; p < FLT_ARG_CNT; p++)
313 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
315 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
321 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
322 emit_verbosecall_enter(jd);
323 #endif /* !defined(NDEBUG) */
327 /* end of header generation */
329 /* create replacement points */
331 REPLACEMENT_POINTS_INIT(cd, jd);
333 /* walk through all basic blocks */
335 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
337 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
339 if (bptr->flags >= BBREACHED) {
341 /* branch resolving */
343 codegen_resolve_branchrefs(cd, bptr);
345 /* handle replacement points */
347 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
349 /* copy interface registers to their destination */
354 #if defined(ENABLE_PROFILING)
355 /* generate basicblock profiling code */
357 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
358 /* count frequency */
360 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
361 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
363 /* if this is an exception handler, start profiling again */
365 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);
448 emit_nullpointer_check(cd, iptr, s1);
451 /* constant operations ************************************************/
453 case ICMD_ICONST: /* ... ==> ..., constant */
455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
456 ICONST(d, iptr->sx.val.i);
457 emit_store_dst(jd, iptr, d);
460 case ICMD_LCONST: /* ... ==> ..., constant */
462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
463 LCONST(d, iptr->sx.val.l);
464 emit_store_dst(jd, iptr, d);
467 case ICMD_FCONST: /* ... ==> ..., constant */
469 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
470 disp = dseg_add_float(cd, iptr->sx.val.f);
471 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
472 emit_store_dst(jd, iptr, d);
475 case ICMD_DCONST: /* ... ==> ..., constant */
477 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
478 disp = dseg_add_double(cd, iptr->sx.val.d);
479 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
480 emit_store_dst(jd, iptr, d);
483 case ICMD_ACONST: /* ... ==> ..., constant */
485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
487 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
488 cr = iptr->sx.val.c.ref;
490 /* PROFILE_CYCLE_STOP; */
492 codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
494 /* PROFILE_CYCLE_START; */
499 if (iptr->sx.val.anyptr == 0)
502 M_MOV_IMM(iptr->sx.val.anyptr, d);
504 emit_store_dst(jd, iptr, d);
508 /* load/store/copy/move operations ************************************/
510 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
511 case ICMD_ALOAD: /* s1 = local variable */
515 case ICMD_ISTORE: /* ..., value ==> ... */
522 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
526 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
527 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
530 /* integer operations *************************************************/
532 case ICMD_INEG: /* ..., value ==> ..., - value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
538 emit_store_dst(jd, iptr, d);
541 case ICMD_LNEG: /* ..., value ==> ..., - value */
543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
547 emit_store_dst(jd, iptr, d);
550 case ICMD_I2L: /* ..., value ==> ..., value */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
555 emit_store_dst(jd, iptr, d);
558 case ICMD_L2I: /* ..., value ==> ..., value */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
563 emit_store_dst(jd, iptr, d);
566 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
569 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
571 emit_store_dst(jd, iptr, d);
574 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
579 emit_store_dst(jd, iptr, d);
582 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
587 emit_store_dst(jd, iptr, d);
591 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602 emit_store_dst(jd, iptr, d);
606 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
607 /* sx.val.i = constant */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
612 /* Using inc and dec is not faster than add (tested with
616 M_IADD_IMM(iptr->sx.val.i, d);
617 emit_store_dst(jd, iptr, d);
620 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
635 /* sx.val.l = constant */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
640 if (IS_IMM32(iptr->sx.val.l))
641 M_LADD_IMM(iptr->sx.val.l, d);
643 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
644 M_LADD(REG_ITMP2, d);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
655 M_INTMOVE(s1, REG_ITMP1);
656 M_ISUB(s2, REG_ITMP1);
657 M_INTMOVE(REG_ITMP1, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
666 /* sx.val.i = constant */
668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
671 M_ISUB_IMM(iptr->sx.val.i, d);
672 emit_store_dst(jd, iptr, d);
675 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
679 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
681 M_INTMOVE(s1, REG_ITMP1);
682 M_LSUB(s2, REG_ITMP1);
683 M_INTMOVE(REG_ITMP1, d);
688 emit_store_dst(jd, iptr, d);
691 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
692 /* sx.val.l = constant */
694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
697 if (IS_IMM32(iptr->sx.val.l))
698 M_LSUB_IMM(iptr->sx.val.l, d);
700 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
701 M_LSUB(REG_ITMP2, d);
703 emit_store_dst(jd, iptr, d);
706 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
717 emit_store_dst(jd, iptr, d);
720 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
721 /* sx.val.i = constant */
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
725 if (iptr->sx.val.i == 2) {
729 M_IMUL_IMM(s1, iptr->sx.val.i, d);
730 emit_store_dst(jd, iptr, d);
733 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
736 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
737 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
744 emit_store_dst(jd, iptr, d);
747 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
748 /* sx.val.l = constant */
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
752 if (IS_IMM32(iptr->sx.val.l))
753 M_LMUL_IMM(s1, iptr->sx.val.l, d);
755 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
757 M_LMUL(REG_ITMP2, d);
759 emit_store_dst(jd, iptr, d);
762 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
764 s1 = emit_load_s1(jd, iptr, RAX);
765 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
766 d = codegen_reg_of_dst(jd, iptr, RAX);
769 M_INTMOVE(s2, REG_ITMP3);
770 emit_arithmetic_check(cd, iptr, REG_ITMP3);
772 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
774 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
776 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
777 M_BEQ(1 + 3); /* 6 bytes */
779 emit_cltd(cd); /* 1 byte */
780 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
783 emit_store_dst(jd, iptr, d);
784 dst = VAROP(iptr->dst);
785 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
786 M_MOV(REG_ITMP2, RDX); /* restore RDX */
789 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
791 s1 = emit_load_s1(jd, iptr, RAX);
792 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
793 d = codegen_reg_of_dst(jd, iptr, RDX);
796 M_INTMOVE(s2, REG_ITMP3);
797 emit_arithmetic_check(cd, iptr, REG_ITMP3);
799 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
801 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
803 M_CLR(RDX); /* 3 bytes */
804 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
805 M_BEQ(1 + 3); /* 6 bytes */
807 emit_cltd(cd); /* 1 byte */
808 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
811 emit_store_dst(jd, iptr, d);
812 dst = VAROP(iptr->dst);
813 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
814 M_MOV(REG_ITMP2, RDX); /* restore RDX */
817 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
818 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
822 M_INTMOVE(s1, REG_ITMP1);
823 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
824 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
825 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
826 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
827 emit_mov_reg_reg(cd, REG_ITMP1, d);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
832 /* sx.val.i = constant */
834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
836 M_INTMOVE(s1, REG_ITMP1);
837 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
838 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
839 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
840 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
841 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
842 emit_mov_reg_reg(cd, REG_ITMP1, d);
843 emit_store_dst(jd, iptr, d);
847 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
849 s1 = emit_load_s1(jd, iptr, RAX);
850 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
851 d = codegen_reg_of_dst(jd, iptr, RAX);
854 M_INTMOVE(s2, REG_ITMP3);
855 emit_arithmetic_check(cd, iptr, REG_ITMP3);
857 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
859 /* check as described in jvm spec */
860 disp = dseg_add_s8(cd, 0x8000000000000000LL);
861 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
863 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
864 M_BEQ(2 + 3); /* 6 bytes */
866 emit_cqto(cd); /* 2 bytes */
867 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
870 emit_store_dst(jd, iptr, d);
871 dst = VAROP(iptr->dst);
872 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
873 M_MOV(REG_ITMP2, RDX); /* restore RDX */
876 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
878 s1 = emit_load_s1(jd, iptr, RAX);
879 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
880 d = codegen_reg_of_dst(jd, iptr, RDX);
883 M_INTMOVE(s2, REG_ITMP3);
884 emit_arithmetic_check(cd, iptr, REG_ITMP3);
886 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
888 /* check as described in jvm spec */
889 disp = dseg_add_s8(cd, 0x8000000000000000LL);
890 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
892 M_LXOR(RDX, RDX); /* 3 bytes */
893 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
894 M_BEQ(2 + 3); /* 6 bytes */
896 emit_cqto(cd); /* 2 bytes */
897 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
900 emit_store_dst(jd, iptr, d);
901 dst = VAROP(iptr->dst);
902 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
903 M_MOV(REG_ITMP2, RDX); /* restore RDX */
906 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
907 /* sx.val.i = constant */
909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
910 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
911 M_INTMOVE(s1, REG_ITMP1);
912 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
913 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
914 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
915 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
916 emit_mov_reg_reg(cd, REG_ITMP1, d);
917 emit_store_dst(jd, iptr, d);
920 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
921 /* sx.val.l = constant */
923 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
924 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
925 M_INTMOVE(s1, REG_ITMP1);
926 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
927 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
928 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
929 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
930 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
931 emit_mov_reg_reg(cd, REG_ITMP1, d);
932 emit_store_dst(jd, iptr, d);
935 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
937 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
938 emit_ishift(jd, SHIFT_SHL, iptr);
941 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
942 /* sx.val.i = constant */
944 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
945 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
947 M_ISLL_IMM(iptr->sx.val.i, d);
948 emit_store_dst(jd, iptr, d);
951 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
953 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
954 emit_ishift(jd, SHIFT_SAR, iptr);
957 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
958 /* sx.val.i = constant */
960 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
961 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
963 M_ISRA_IMM(iptr->sx.val.i, d);
964 emit_store_dst(jd, iptr, d);
967 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
969 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
970 emit_ishift(jd, SHIFT_SHR, iptr);
973 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
974 /* sx.val.i = constant */
976 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
977 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
979 M_ISRL_IMM(iptr->sx.val.i, d);
980 emit_store_dst(jd, iptr, d);
983 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
985 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
986 emit_lshift(jd, SHIFT_SHL, iptr);
989 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
990 /* sx.val.i = constant */
992 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
993 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
995 M_LSLL_IMM(iptr->sx.val.i, d);
996 emit_store_dst(jd, iptr, d);
999 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1001 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1002 emit_lshift(jd, SHIFT_SAR, iptr);
1005 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1006 /* sx.val.i = constant */
1008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1009 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1011 M_LSRA_IMM(iptr->sx.val.i, d);
1012 emit_store_dst(jd, iptr, d);
1015 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1017 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1018 emit_lshift(jd, SHIFT_SHR, iptr);
1021 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1022 /* sx.val.l = constant */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1027 M_LSRL_IMM(iptr->sx.val.i, d);
1028 emit_store_dst(jd, iptr, d);
1031 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1035 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1046 /* sx.val.i = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1051 M_IAND_IMM(iptr->sx.val.i, d);
1052 emit_store_dst(jd, iptr, d);
1055 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1057 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1058 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1059 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1070 /* sx.val.l = constant */
1072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1073 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1075 if (IS_IMM32(iptr->sx.val.l))
1076 M_LAND_IMM(iptr->sx.val.l, d);
1078 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1079 M_LAND(REG_ITMP2, d);
1081 emit_store_dst(jd, iptr, d);
1084 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1087 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1099 /* sx.val.i = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1104 M_IOR_IMM(iptr->sx.val.i, d);
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1111 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1123 /* sx.val.l = constant */
1125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1126 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1128 if (IS_IMM32(iptr->sx.val.l))
1129 M_LOR_IMM(iptr->sx.val.l, d);
1131 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1132 M_LOR(REG_ITMP2, d);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1140 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1152 /* sx.val.i = constant */
1154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1157 M_IXOR_IMM(iptr->sx.val.i, d);
1158 emit_store_dst(jd, iptr, d);
1161 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1164 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1176 /* sx.val.l = constant */
1178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1179 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1181 if (IS_IMM32(iptr->sx.val.l))
1182 M_LXOR_IMM(iptr->sx.val.l, d);
1184 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1185 M_LXOR(REG_ITMP2, d);
1187 emit_store_dst(jd, iptr, d);
1191 /* floating operations ************************************************/
1193 case ICMD_FNEG: /* ..., value ==> ..., - value */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1197 disp = dseg_add_s4(cd, 0x80000000);
1199 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1200 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1201 emit_store_dst(jd, iptr, d);
1204 case ICMD_DNEG: /* ..., value ==> ..., - value */
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1207 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1208 disp = dseg_add_s8(cd, 0x8000000000000000);
1210 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1211 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1217 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1218 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1219 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1231 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1232 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1233 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1240 emit_store_dst(jd, iptr, d);
1243 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1245 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1246 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1247 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1249 M_FLTMOVE(s2, REG_FTMP2);
1254 emit_store_dst(jd, iptr, d);
1257 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1259 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1260 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1261 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1263 M_FLTMOVE(s2, REG_FTMP2);
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1273 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1274 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1275 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1282 emit_store_dst(jd, iptr, d);
1285 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1287 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1288 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1289 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1301 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1302 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1303 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1305 M_FLTMOVE(s2, REG_FTMP2);
1310 emit_store_dst(jd, iptr, d);
1313 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1315 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1316 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1317 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1319 M_FLTMOVE(s2, REG_FTMP2);
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1332 emit_store_dst(jd, iptr, d);
1335 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1338 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1340 emit_store_dst(jd, iptr, d);
1343 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1346 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1354 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1356 emit_store_dst(jd, iptr, d);
1359 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1361 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1362 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1364 M_ICMP_IMM(0x80000000, d); /* corner cases */
1365 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1366 ((REG_RESULT == d) ? 0 : 3);
1368 M_FLTMOVE(s1, REG_FTMP1);
1369 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1371 M_INTMOVE(REG_RESULT, d);
1372 emit_store_dst(jd, iptr, d);
1375 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1377 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1380 M_ICMP_IMM(0x80000000, d); /* corner cases */
1381 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1382 ((REG_RESULT == d) ? 0 : 3);
1384 M_FLTMOVE(s1, REG_FTMP1);
1385 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1387 M_INTMOVE(REG_RESULT, d);
1388 emit_store_dst(jd, iptr, d);
1391 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1393 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1394 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1396 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1397 M_LCMP(REG_ITMP2, d); /* corner cases */
1398 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1399 ((REG_RESULT == d) ? 0 : 3);
1401 M_FLTMOVE(s1, REG_FTMP1);
1402 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1404 M_INTMOVE(REG_RESULT, d);
1405 emit_store_dst(jd, iptr, d);
1408 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1410 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1411 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1413 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1414 M_LCMP(REG_ITMP2, d); /* corner cases */
1415 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1416 ((REG_RESULT == d) ? 0 : 3);
1418 M_FLTMOVE(s1, REG_FTMP1);
1419 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1421 M_INTMOVE(REG_RESULT, d);
1422 emit_store_dst(jd, iptr, d);
1425 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1427 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1428 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1435 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1436 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1438 emit_store_dst(jd, iptr, d);
1441 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1442 /* == => 0, < => 1, > => -1 */
1444 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1445 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1448 M_MOV_IMM(1, REG_ITMP1);
1449 M_MOV_IMM(-1, REG_ITMP2);
1450 emit_ucomiss_reg_reg(cd, s1, s2);
1451 M_CMOVB(REG_ITMP1, d);
1452 M_CMOVA(REG_ITMP2, d);
1453 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1454 emit_store_dst(jd, iptr, d);
1457 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1458 /* == => 0, < => 1, > => -1 */
1460 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1461 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1464 M_MOV_IMM(1, REG_ITMP1);
1465 M_MOV_IMM(-1, REG_ITMP2);
1466 emit_ucomiss_reg_reg(cd, s1, s2);
1467 M_CMOVB(REG_ITMP1, d);
1468 M_CMOVA(REG_ITMP2, d);
1469 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1470 emit_store_dst(jd, iptr, d);
1473 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1474 /* == => 0, < => 1, > => -1 */
1476 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1478 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1480 M_MOV_IMM(1, REG_ITMP1);
1481 M_MOV_IMM(-1, REG_ITMP2);
1482 emit_ucomisd_reg_reg(cd, s1, s2);
1483 M_CMOVB(REG_ITMP1, d);
1484 M_CMOVA(REG_ITMP2, d);
1485 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1486 emit_store_dst(jd, iptr, d);
1489 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1490 /* == => 0, < => 1, > => -1 */
1492 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1493 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1496 M_MOV_IMM(1, REG_ITMP1);
1497 M_MOV_IMM(-1, REG_ITMP2);
1498 emit_ucomisd_reg_reg(cd, s1, s2);
1499 M_CMOVB(REG_ITMP1, d);
1500 M_CMOVA(REG_ITMP2, d);
1501 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1502 emit_store_dst(jd, iptr, d);
1506 /* memory operations **************************************************/
1508 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1512 emit_nullpointer_check(cd, iptr, s1);
1513 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1520 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1522 emit_array_checks(cd, iptr, s1, s2);
1523 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1524 emit_store_dst(jd, iptr, d);
1527 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1532 emit_array_checks(cd, iptr, s1, s2);
1533 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1534 emit_store_dst(jd, iptr, d);
1537 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1542 emit_array_checks(cd, iptr, s1, s2);
1543 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1544 emit_store_dst(jd, iptr, d);
1547 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1550 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1552 emit_array_checks(cd, iptr, s1, s2);
1553 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1554 emit_store_dst(jd, iptr, d);
1557 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1562 emit_array_checks(cd, iptr, s1, s2);
1563 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1564 emit_store_dst(jd, iptr, d);
1567 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1570 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1571 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1572 emit_array_checks(cd, iptr, s1, s2);
1573 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, 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 emit_array_checks(cd, iptr, s1, s2);
1583 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1584 emit_store_dst(jd, iptr, d);
1587 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1592 emit_array_checks(cd, iptr, s1, s2);
1593 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1594 emit_store_dst(jd, iptr, d);
1598 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1602 emit_array_checks(cd, iptr, s1, s2);
1603 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1604 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1607 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1611 emit_array_checks(cd, iptr, s1, s2);
1612 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1613 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1616 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1620 emit_array_checks(cd, iptr, s1, s2);
1621 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1622 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1625 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1629 emit_array_checks(cd, iptr, s1, s2);
1630 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1631 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1634 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1637 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1638 emit_array_checks(cd, iptr, s1, s2);
1639 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1640 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1643 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1647 emit_array_checks(cd, iptr, s1, s2);
1648 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1649 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1652 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1655 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1656 emit_array_checks(cd, iptr, s1, s2);
1657 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1658 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1661 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1664 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1665 emit_array_checks(cd, iptr, s1, s2);
1666 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1670 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1674 codegen_add_arraystoreexception_ref(cd);
1676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1678 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1679 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1683 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687 emit_array_checks(cd, iptr, s1, s2);
1688 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1691 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1695 emit_array_checks(cd, iptr, s1, s2);
1696 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1699 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1703 emit_array_checks(cd, iptr, s1, s2);
1704 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1707 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711 emit_array_checks(cd, iptr, s1, s2);
1712 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1715 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1719 emit_array_checks(cd, iptr, s1, s2);
1721 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1722 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1724 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1725 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1729 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1733 emit_array_checks(cd, iptr, s1, s2);
1734 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1738 case ICMD_GETSTATIC: /* ... ==> ..., value */
1740 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1741 uf = iptr->sx.s23.s3.uf;
1742 fieldtype = uf->fieldref->parseddesc.fd->type;
1743 disp = dseg_add_unique_address(cd, NULL);
1744 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1746 /* must be calculated before codegen_add_patch_ref */
1749 disp -= PATCHER_CALL_SIZE;
1751 /* PROFILE_CYCLE_STOP; */
1753 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1755 /* PROFILE_CYCLE_START; */
1758 fi = iptr->sx.s23.s3.fmiref->p.field;
1759 fieldtype = fi->type;
1760 disp = dseg_add_address(cd, &(fi->value));
1761 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1763 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1766 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1769 disp -= PATCHER_CALL_SIZE;
1771 PROFILE_CYCLE_START;
1775 /* This approach is much faster than moving the field
1776 address inline into a register. */
1778 M_ALD(REG_ITMP1, RIP, disp);
1780 switch (fieldtype) {
1782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1783 M_ILD(d, REG_ITMP1, 0);
1787 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1788 M_LLD(d, REG_ITMP1, 0);
1791 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1792 M_FLD(d, REG_ITMP1, 0);
1795 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1796 M_DLD(d, REG_ITMP1, 0);
1799 emit_store_dst(jd, iptr, d);
1802 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1804 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1805 uf = iptr->sx.s23.s3.uf;
1806 fieldtype = uf->fieldref->parseddesc.fd->type;
1807 disp = dseg_add_unique_address(cd, NULL);
1808 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1810 /* must be calculated before codegen_add_patch_ref */
1813 disp -= PATCHER_CALL_SIZE;
1815 /* PROFILE_CYCLE_STOP; */
1817 codegen_add_patch_ref(cd, 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));
1825 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1827 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1830 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1833 disp -= PATCHER_CALL_SIZE;
1835 PROFILE_CYCLE_START;
1839 /* This approach is much faster than moving the field
1840 address inline into a register. */
1842 M_ALD(REG_ITMP1, RIP, disp);
1844 switch (fieldtype) {
1846 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1847 M_IST(s1, REG_ITMP1, 0);
1851 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1852 M_LST(s1, REG_ITMP1, 0);
1855 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1856 M_FST(s1, REG_ITMP1, 0);
1859 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1860 M_DST(s1, REG_ITMP1, 0);
1865 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1866 /* val = value (in current instruction) */
1867 /* following NOP) */
1869 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1870 uf = iptr->sx.s23.s3.uf;
1871 fieldtype = uf->fieldref->parseddesc.fd->type;
1872 disp = dseg_add_unique_address(cd, NULL);
1873 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1875 /* must be calculated before codegen_add_patch_ref */
1878 disp -= PATCHER_CALL_SIZE;
1881 /* PROFILE_CYCLE_STOP; */
1883 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1885 /* PROFILE_CYCLE_START; */
1888 fi = iptr->sx.s23.s3.fmiref->p.field;
1889 fieldtype = fi->type;
1890 disp = dseg_add_address(cd, &(fi->value));
1891 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1893 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1896 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1899 disp -= PATCHER_CALL_SIZE;
1901 PROFILE_CYCLE_START;
1905 /* This approach is much faster than moving the field
1906 address inline into a register. */
1908 M_ALD(REG_ITMP1, RIP, disp);
1910 switch (fieldtype) {
1913 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1918 if (IS_IMM32(iptr->sx.s23.s2.constval))
1919 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1921 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1922 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1928 case ICMD_GETFIELD: /* ... ==> ..., value */
1930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1931 emit_nullpointer_check(cd, iptr, s1);
1933 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1934 uf = iptr->sx.s23.s3.uf;
1935 fieldtype = uf->fieldref->parseddesc.fd->type;
1938 /* PROFILE_CYCLE_STOP; */
1940 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1942 /* PROFILE_CYCLE_START; */
1945 fi = iptr->sx.s23.s3.fmiref->p.field;
1946 fieldtype = fi->type;
1950 switch (fieldtype) {
1952 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1953 M_ILD32(d, s1, disp);
1957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1958 M_LLD32(d, s1, disp);
1961 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1962 M_FLD32(d, s1, disp);
1965 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1966 M_DLD32(d, s1, disp);
1969 emit_store_dst(jd, iptr, d);
1972 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1974 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1976 emit_nullpointer_check(cd, iptr, s1);
1978 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1979 uf = iptr->sx.s23.s3.uf;
1980 fieldtype = uf->fieldref->parseddesc.fd->type;
1983 /* PROFILE_CYCLE_STOP; */
1985 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1987 /* PROFILE_CYCLE_START; */
1990 fi = iptr->sx.s23.s3.fmiref->p.field;
1991 fieldtype = fi->type;
1995 switch (fieldtype) {
1997 M_IST32(s2, s1, disp);
2001 M_LST32(s2, s1, disp);
2004 M_FST32(s2, s1, disp);
2007 M_DST32(s2, s1, disp);
2012 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2013 /* val = value (in current instruction) */
2014 /* following NOP) */
2016 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2017 emit_nullpointer_check(cd, iptr, s1);
2019 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2020 uf = iptr->sx.s23.s3.uf;
2021 fieldtype = uf->fieldref->parseddesc.fd->type;
2024 /* PROFILE_CYCLE_STOP; */
2026 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2028 /* PROFILE_CYCLE_START; */
2031 fi = iptr->sx.s23.s3.fmiref->p.field;
2032 fieldtype = fi->type;
2036 switch (fieldtype) {
2039 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2044 /* XXX why no check for IS_IMM32? */
2045 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2046 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2052 /* branch operations **************************************************/
2054 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2057 M_INTMOVE(s1, REG_ITMP1_XPTR);
2061 #ifdef ENABLE_VERIFIER
2062 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2063 uc = iptr->sx.s23.s2.uc;
2065 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2067 #endif /* ENABLE_VERIFIER */
2069 M_CALL_IMM(0); /* passing exception pc */
2070 M_POP(REG_ITMP2_XPC);
2072 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2076 case ICMD_GOTO: /* ... ==> ... */
2077 case ICMD_RET: /* ... ==> ... */
2080 codegen_add_branch_ref(cd, iptr->dst.block);
2083 case ICMD_JSR: /* ... ==> ... */
2086 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2089 case ICMD_IFNULL: /* ..., value ==> ... */
2091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094 codegen_add_branch_ref(cd, iptr->dst.block);
2097 case ICMD_IFNONNULL: /* ..., value ==> ... */
2099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2102 codegen_add_branch_ref(cd, iptr->dst.block);
2105 case ICMD_IFEQ: /* ..., value ==> ... */
2107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2108 M_ICMP_IMM(iptr->sx.val.i, s1);
2110 codegen_add_branch_ref(cd, iptr->dst.block);
2113 case ICMD_IFLT: /* ..., value ==> ... */
2115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2116 M_ICMP_IMM(iptr->sx.val.i, s1);
2118 codegen_add_branch_ref(cd, iptr->dst.block);
2121 case ICMD_IFLE: /* ..., value ==> ... */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 M_ICMP_IMM(iptr->sx.val.i, s1);
2126 codegen_add_branch_ref(cd, iptr->dst.block);
2129 case ICMD_IFNE: /* ..., value ==> ... */
2131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132 M_ICMP_IMM(iptr->sx.val.i, s1);
2134 codegen_add_branch_ref(cd, iptr->dst.block);
2137 case ICMD_IFGT: /* ..., value ==> ... */
2139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2140 M_ICMP_IMM(iptr->sx.val.i, s1);
2142 codegen_add_branch_ref(cd, iptr->dst.block);
2145 case ICMD_IFGE: /* ..., value ==> ... */
2147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2148 M_ICMP_IMM(iptr->sx.val.i, s1);
2150 codegen_add_branch_ref(cd, iptr->dst.block);
2153 case ICMD_IF_LEQ: /* ..., value ==> ... */
2155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2156 if (IS_IMM32(iptr->sx.val.l))
2157 M_LCMP_IMM(iptr->sx.val.l, s1);
2159 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2160 M_LCMP(REG_ITMP2, s1);
2163 codegen_add_branch_ref(cd, iptr->dst.block);
2166 case ICMD_IF_LLT: /* ..., value ==> ... */
2168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2169 if (IS_IMM32(iptr->sx.val.l))
2170 M_LCMP_IMM(iptr->sx.val.l, s1);
2172 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2173 M_LCMP(REG_ITMP2, s1);
2176 codegen_add_branch_ref(cd, iptr->dst.block);
2179 case ICMD_IF_LLE: /* ..., value ==> ... */
2181 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2182 if (IS_IMM32(iptr->sx.val.l))
2183 M_LCMP_IMM(iptr->sx.val.l, s1);
2185 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2186 M_LCMP(REG_ITMP2, s1);
2189 codegen_add_branch_ref(cd, iptr->dst.block);
2192 case ICMD_IF_LNE: /* ..., value ==> ... */
2194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195 if (IS_IMM32(iptr->sx.val.l))
2196 M_LCMP_IMM(iptr->sx.val.l, s1);
2198 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2199 M_LCMP(REG_ITMP2, s1);
2202 codegen_add_branch_ref(cd, iptr->dst.block);
2205 case ICMD_IF_LGT: /* ..., value ==> ... */
2207 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2208 if (IS_IMM32(iptr->sx.val.l))
2209 M_LCMP_IMM(iptr->sx.val.l, s1);
2211 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2212 M_LCMP(REG_ITMP2, s1);
2215 codegen_add_branch_ref(cd, iptr->dst.block);
2218 case ICMD_IF_LGE: /* ..., value ==> ... */
2220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2221 if (IS_IMM32(iptr->sx.val.l))
2222 M_LCMP_IMM(iptr->sx.val.l, s1);
2224 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2225 M_LCMP(REG_ITMP2, s1);
2228 codegen_add_branch_ref(cd, iptr->dst.block);
2231 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2234 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2237 codegen_add_branch_ref(cd, iptr->dst.block);
2240 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2241 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2243 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2244 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2247 codegen_add_branch_ref(cd, iptr->dst.block);
2250 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2252 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2253 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2256 codegen_add_branch_ref(cd, iptr->dst.block);
2259 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2260 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2263 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2266 codegen_add_branch_ref(cd, iptr->dst.block);
2269 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2275 codegen_add_branch_ref(cd, iptr->dst.block);
2278 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2280 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2281 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2284 codegen_add_branch_ref(cd, iptr->dst.block);
2287 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2289 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2290 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2293 codegen_add_branch_ref(cd, iptr->dst.block);
2296 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2298 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2299 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2302 codegen_add_branch_ref(cd, iptr->dst.block);
2305 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2308 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2311 codegen_add_branch_ref(cd, iptr->dst.block);
2314 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2316 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2317 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2320 codegen_add_branch_ref(cd, iptr->dst.block);
2323 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2326 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2329 codegen_add_branch_ref(cd, iptr->dst.block);
2332 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2338 codegen_add_branch_ref(cd, iptr->dst.block);
2341 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2344 REPLACEMENT_POINT_RETURN(cd, iptr);
2345 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2346 M_INTMOVE(s1, REG_RESULT);
2347 goto nowperformreturn;
2349 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2351 REPLACEMENT_POINT_RETURN(cd, iptr);
2352 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2353 M_INTMOVE(s1, REG_RESULT);
2355 #ifdef ENABLE_VERIFIER
2356 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2357 uc = iptr->sx.s23.s2.uc;
2361 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2363 PROFILE_CYCLE_START;
2365 #endif /* ENABLE_VERIFIER */
2366 goto nowperformreturn;
2368 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2371 REPLACEMENT_POINT_RETURN(cd, iptr);
2372 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2373 M_FLTMOVE(s1, REG_FRESULT);
2374 goto nowperformreturn;
2376 case ICMD_RETURN: /* ... ==> ... */
2378 REPLACEMENT_POINT_RETURN(cd, iptr);
2384 p = cd->stackframesize;
2386 #if !defined(NDEBUG)
2387 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2388 emit_verbosecall_exit(jd);
2389 #endif /* !defined(NDEBUG) */
2391 #if defined(ENABLE_THREADS)
2392 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2393 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2395 /* we need to save the proper return value */
2396 switch (iptr->opc) {
2400 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2404 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2408 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2411 /* and now restore the proper return value */
2412 switch (iptr->opc) {
2416 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2420 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2426 /* restore saved registers */
2428 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2429 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2431 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2432 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2435 /* deallocate stack */
2437 if (cd->stackframesize)
2438 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2440 /* generate method profiling code */
2449 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2452 branch_target_t *table;
2454 table = iptr->dst.table;
2456 l = iptr->sx.s23.s2.tablelow;
2457 i = iptr->sx.s23.s3.tablehigh;
2459 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2460 M_INTMOVE(s1, REG_ITMP1);
2463 M_ISUB_IMM(l, REG_ITMP1);
2465 /* number of targets */
2469 M_ICMP_IMM(i - 1, REG_ITMP1);
2472 codegen_add_branch_ref(cd, table[0].block); /* default target */
2474 /* build jump table top down and use address of lowest entry */
2479 dseg_add_target(cd, table->block);
2483 /* length of dataseg after last dseg_add_target is used
2486 M_MOV_IMM(0, REG_ITMP2);
2488 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2494 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2497 lookup_target_t *lookup;
2499 lookup = iptr->dst.lookup;
2501 i = iptr->sx.s23.s2.lookupcount;
2503 MCODECHECK(8 + ((7 + 6) * i) + 5);
2504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2507 M_ICMP_IMM(lookup->value, s1);
2509 codegen_add_branch_ref(cd, lookup->target.block);
2515 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2520 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2522 bte = iptr->sx.s23.s3.bte;
2526 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2528 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2529 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2530 case ICMD_INVOKEINTERFACE:
2532 REPLACEMENT_POINT_INVOKE(cd, iptr);
2534 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2536 um = iptr->sx.s23.s3.um;
2537 md = um->methodref->parseddesc.md;
2540 lm = iptr->sx.s23.s3.fmiref->p.method;
2542 md = lm->parseddesc;
2546 s3 = md->paramcount;
2548 MCODECHECK((20 * s3) + 128);
2550 /* copy arguments to registers or stack location */
2552 for (s3 = s3 - 1; s3 >= 0; s3--) {
2553 var = VAR(iptr->sx.s23.s2.args[s3]);
2555 /* Already Preallocated (ARGVAR) ? */
2556 if (var->flags & PREALLOC)
2559 if (IS_INT_LNG_TYPE(var->type)) {
2560 if (!md->params[s3].inmemory) {
2561 s1 = rd->argintregs[md->params[s3].regoff];
2562 d = emit_load(jd, iptr, var, s1);
2566 d = emit_load(jd, iptr, var, REG_ITMP1);
2567 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2571 if (!md->params[s3].inmemory) {
2572 s1 = rd->argfltregs[md->params[s3].regoff];
2573 d = emit_load(jd, iptr, var, s1);
2577 d = emit_load(jd, iptr, var, REG_FTMP1);
2579 if (IS_2_WORD_TYPE(var->type))
2580 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2582 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2587 /* generate method profiling code */
2591 switch (iptr->opc) {
2593 M_MOV_IMM(bte->fp, REG_ITMP1);
2596 if (INSTRUCTION_MUST_CHECK(iptr)) {
2599 codegen_add_fillinstacktrace_ref(cd);
2603 case ICMD_INVOKESPECIAL:
2606 codegen_add_nullpointerexception_ref(cd);
2610 case ICMD_INVOKESTATIC:
2612 disp = dseg_add_unique_address(cd, NULL);
2613 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2615 /* must be calculated before codegen_add_patch_ref */
2618 disp -= PATCHER_CALL_SIZE;
2620 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2626 disp = dseg_add_functionptr(cd, lm->stubroutine);
2627 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2629 /* a = (ptrint) lm->stubroutine; */
2632 /* M_MOV_IMM(a, REG_ITMP2); */
2633 M_ALD(REG_ITMP2, RIP, disp);
2637 case ICMD_INVOKEVIRTUAL:
2638 emit_nullpointer_check(cd, iptr, REG_A0);
2641 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2646 s1 = OFFSET(vftbl_t, table[0]) +
2647 sizeof(methodptr) * lm->vftblindex;
2649 M_ALD(REG_METHODPTR, REG_A0,
2650 OFFSET(java_objectheader, vftbl));
2651 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2655 case ICMD_INVOKEINTERFACE:
2656 emit_nullpointer_check(cd, iptr, REG_A0);
2659 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2665 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2666 sizeof(methodptr) * lm->class->index;
2668 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2671 M_ALD(REG_METHODPTR, REG_A0,
2672 OFFSET(java_objectheader, vftbl));
2673 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2674 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2679 /* generate method profiling code */
2681 PROFILE_CYCLE_START;
2683 /* store size of call code in replacement point */
2685 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2687 /* store return value */
2689 d = md->returntype.type;
2691 if (d != TYPE_VOID) {
2692 if (IS_INT_LNG_TYPE(d)) {
2693 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2694 M_INTMOVE(REG_RESULT, s1);
2697 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2698 M_FLTMOVE(REG_FRESULT, s1);
2700 emit_store_dst(jd, iptr, s1);
2705 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2707 /* val.a: (classinfo *) superclass */
2709 /* superclass is an interface:
2711 * OK if ((sub == NULL) ||
2712 * (sub->vftbl->interfacetablelength > super->index) &&
2713 * (sub->vftbl->interfacetable[-super->index] != NULL));
2715 * superclass is a class:
2717 * OK if ((sub == NULL) || (0
2718 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2719 * super->vftbl->diffval));
2722 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2723 /* object type cast-check */
2726 vftbl_t *supervftbl;
2729 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2735 super = iptr->sx.s23.s3.c.cls;
2736 superindex = super->index;
2737 supervftbl = super->vftbl;
2740 #if defined(ENABLE_THREADS)
2741 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2743 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2745 /* calculate interface checkcast code size */
2747 s2 = 3; /* mov_membase_reg */
2748 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
2750 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
2751 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
2752 3 /* test */ + 6 /* jcc */;
2755 s2 += (opt_shownops ? 5 : 0);
2757 /* calculate class checkcast code size */
2759 s3 = 3; /* mov_membase_reg */
2760 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
2761 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
2764 if (s1 != REG_ITMP1) {
2765 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
2766 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
2767 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
2768 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
2774 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
2775 10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
2776 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2779 s3 += 3 /* cmp */ + 6 /* jcc */;
2782 s3 += (opt_shownops ? 5 : 0);
2784 /* if class is not resolved, check which code to call */
2786 if (super == NULL) {
2788 M_BEQ(6 + (opt_shownops ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
2790 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2791 iptr->sx.s23.s3.c.ref, 0);
2793 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2794 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2798 /* interface checkcast code */
2800 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2801 if (super != NULL) {
2806 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2808 if (super == NULL) {
2809 codegen_add_patch_ref(cd,
2810 PATCHER_checkcast_instanceof_interface,
2811 iptr->sx.s23.s3.c.ref,
2815 emit_movl_membase32_reg(cd, REG_ITMP2,
2816 OFFSET(vftbl_t, interfacetablelength),
2818 /* XXX TWISTI: should this be int arithmetic? */
2819 M_LSUB_IMM32(superindex, REG_ITMP3);
2822 codegen_add_classcastexception_ref(cd, s1);
2823 emit_mov_membase32_reg(cd, REG_ITMP2,
2824 OFFSET(vftbl_t, interfacetable[0]) -
2825 superindex * sizeof(methodptr*),
2829 codegen_add_classcastexception_ref(cd, s1);
2835 /* class checkcast code */
2837 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2838 if (super != NULL) {
2843 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2845 if (super == NULL) {
2846 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
2847 iptr->sx.s23.s3.c.ref,
2851 M_MOV_IMM(supervftbl, REG_ITMP3);
2852 #if defined(ENABLE_THREADS)
2853 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2855 emit_movl_membase32_reg(cd, REG_ITMP2,
2856 OFFSET(vftbl_t, baseval),
2858 /* if (s1 != REG_ITMP1) { */
2859 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2860 /* OFFSET(vftbl_t, baseval), */
2862 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2863 /* OFFSET(vftbl_t, diffval), */
2865 /* #if defined(ENABLE_THREADS) */
2866 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2868 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2871 emit_movl_membase32_reg(cd, REG_ITMP3,
2872 OFFSET(vftbl_t, baseval),
2874 M_LSUB(REG_ITMP3, REG_ITMP2);
2875 M_MOV_IMM(supervftbl, REG_ITMP3);
2876 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2878 #if defined(ENABLE_THREADS)
2879 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2881 M_LCMP(REG_ITMP3, REG_ITMP2);
2882 M_BA(0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
2883 codegen_add_classcastexception_ref(cd, s1);
2886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2889 /* array type cast-check */
2891 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2892 M_INTMOVE(s1, REG_A0);
2894 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2895 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2896 iptr->sx.s23.s3.c.ref, 0);
2899 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2900 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2903 /* s1 may have been destroyed over the function call */
2904 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2907 codegen_add_classcastexception_ref(cd, s1);
2909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2913 emit_store_dst(jd, iptr, d);
2916 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2918 /* val.a: (classinfo *) superclass */
2920 /* superclass is an interface:
2922 * return (sub != NULL) &&
2923 * (sub->vftbl->interfacetablelength > super->index) &&
2924 * (sub->vftbl->interfacetable[-super->index] != NULL);
2926 * superclass is a class:
2928 * return ((sub != NULL) && (0
2929 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2930 * super->vftbl->diffvall));
2935 vftbl_t *supervftbl;
2938 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2944 super = iptr->sx.s23.s3.c.cls;
2945 superindex = super->index;
2946 supervftbl = super->vftbl;
2949 #if defined(ENABLE_THREADS)
2950 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2956 M_INTMOVE(s1, REG_ITMP1);
2960 /* calculate interface instanceof code size */
2962 s2 = 3; /* mov_membase_reg */
2963 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
2964 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub_imm32 */ +
2965 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
2966 3 /* test */ + 4 /* setcc */;
2969 s2 += (opt_shownops ? 5 : 0);
2971 /* calculate class instanceof code size */
2973 s3 = 3; /* mov_membase_reg */
2974 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
2975 s3 += 10; /* mov_imm_reg */
2976 s3 += 2; /* movl_membase_reg - only if REG_ITMP1 == RAX */
2977 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
2978 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
2979 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2980 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
2981 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2982 s3 += 3 /* sub */ + 3 /* xor */ + 3 /* cmp */ + 4 /* setcc */;
2985 s3 += (opt_shownops ? 5 : 0);
2987 emit_alu_reg_reg(cd, ALU_XOR, d, d);
2989 /* if class is not resolved, check which code to call */
2991 if (super == NULL) {
2992 emit_test_reg_reg(cd, s1, s1);
2993 emit_jcc(cd, CC_Z, (6 + (opt_shownops ? 5 : 0) +
2994 7 + 6 + s2 + 5 + s3));
2996 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2997 iptr->sx.s23.s3.c.ref, 0);
2999 emit_movl_imm_reg(cd, 0, REG_ITMP3); /* super->flags */
3000 emit_alul_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP3);
3001 emit_jcc(cd, CC_Z, s2 + 5);
3004 /* interface instanceof code */
3006 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3007 if (super != NULL) {
3008 emit_test_reg_reg(cd, s1, s1);
3009 emit_jcc(cd, CC_Z, s2);
3012 emit_mov_membase_reg(cd, s1,
3013 OFFSET(java_objectheader, vftbl),
3016 if (super == NULL) {
3017 codegen_add_patch_ref(cd,
3018 PATCHER_checkcast_instanceof_interface,
3019 iptr->sx.s23.s3.c.ref, 0);
3022 emit_movl_membase32_reg(cd, REG_ITMP1,
3023 OFFSET(vftbl_t, interfacetablelength),
3025 emit_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
3026 emit_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
3028 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
3030 emit_jcc(cd, CC_LE, a);
3031 emit_mov_membase32_reg(cd, REG_ITMP1,
3032 OFFSET(vftbl_t, interfacetable[0]) -
3033 superindex * sizeof(methodptr*),
3035 emit_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3036 emit_setcc_reg(cd, CC_NE, d);
3039 emit_jmp_imm(cd, s3);
3042 /* class instanceof code */
3044 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3045 if (super != NULL) {
3046 emit_test_reg_reg(cd, s1, s1);
3047 emit_jcc(cd, CC_E, s3);
3050 emit_mov_membase_reg(cd, s1,
3051 OFFSET(java_objectheader, vftbl),
3054 if (super == NULL) {
3055 codegen_add_patch_ref(cd, PATCHER_instanceof_class,
3056 iptr->sx.s23.s3.c.ref, 0);
3059 emit_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP2);
3060 #if defined(ENABLE_THREADS)
3061 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3063 emit_movl_membase_reg(cd, REG_ITMP1,
3064 OFFSET(vftbl_t, baseval),
3066 emit_movl_membase_reg(cd, REG_ITMP2,
3067 OFFSET(vftbl_t, diffval),
3069 emit_movl_membase_reg(cd, REG_ITMP2,
3070 OFFSET(vftbl_t, baseval),
3072 #if defined(ENABLE_THREADS)
3073 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3075 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
3076 emit_alu_reg_reg(cd, ALU_XOR, d, d); /* may be REG_ITMP2 */
3077 emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP1);
3078 emit_setcc_reg(cd, CC_BE, d);
3080 emit_store_dst(jd, iptr, d);
3084 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3086 /* check for negative sizes and copy sizes to stack if necessary */
3088 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3090 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3092 /* copy SAVEDVAR sizes to stack */
3093 var = VAR(iptr->sx.s23.s2.args[s1]);
3095 /* Already Preallocated? */
3096 if (!(var->flags & PREALLOC)) {
3097 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3098 M_LST(s2, REG_SP, s1 * 8);
3102 /* is a patcher function set? */
3104 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3105 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3106 iptr->sx.s23.s3.c.ref, 0);
3109 /* a0 = dimension count */
3111 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3113 /* a1 = classinfo */
3115 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3117 /* a2 = pointer to dimensions = stack pointer */
3119 M_MOV(REG_SP, REG_A2);
3121 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3124 /* check for exception before result assignment */
3128 codegen_add_fillinstacktrace_ref(cd);
3130 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3131 M_INTMOVE(REG_RESULT, s1);
3132 emit_store_dst(jd, iptr, s1);
3136 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3141 } /* for instruction */
3143 MCODECHECK(512); /* XXX require a lower number? */
3145 /* At the end of a basic block we may have to append some nops,
3146 because the patcher stub calling code might be longer than the
3147 actual instruction. So codepatching does not change the
3148 following block unintentionally. */
3150 if (cd->mcodeptr < cd->lastmcodeptr) {
3151 while (cd->mcodeptr < cd->lastmcodeptr) {
3156 } /* if (bptr -> flags >= BBREACHED) */
3157 } /* for basic block */
3159 dseg_createlinenumbertable(cd);
3161 /* generate stubs */
3163 emit_exception_stubs(jd);
3164 emit_patcher_stubs(jd);
3165 REPLACEMENT_EMIT_STUBS(jd);
3169 /* everything's ok */
3175 /* createcompilerstub **********************************************************
3177 Creates a stub routine which calls the compiler.
3179 *******************************************************************************/
3181 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3182 #define COMPILERSTUB_CODESIZE 7 + 7 + 3
3184 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3187 u1 *createcompilerstub(methodinfo *m)
3189 u1 *s; /* memory to hold the stub */
3194 s = CNEW(u1, COMPILERSTUB_SIZE);
3196 /* set data pointer and code pointer */
3199 s = s + COMPILERSTUB_DATASIZE;
3201 /* mark start of dump memory area */
3203 dumpsize = dump_size();
3205 cd = DNEW(codegendata);
3208 /* The codeinfo pointer is actually a pointer to the
3209 methodinfo. This fakes a codeinfo structure. */
3211 d[0] = (ptrint) asm_call_jit_compiler;
3213 d[2] = (ptrint) &d[1]; /* fake code->m */
3215 /* code for the stub */
3217 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
3218 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
3221 #if defined(ENABLE_STATISTICS)
3223 count_cstub_len += COMPILERSTUB_SIZE;
3226 /* release dump area */
3228 dump_release(dumpsize);
3234 /* createnativestub ************************************************************
3236 Creates a stub routine which calls a native method.
3238 *******************************************************************************/
3240 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3248 s4 i, j; /* count variables */
3252 /* get required compiler data */
3259 /* initialize variables */
3262 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3264 /* calculate stack frame size */
3266 cd->stackframesize =
3267 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3268 sizeof(localref_table) / SIZEOF_VOID_P +
3269 INT_ARG_CNT + FLT_ARG_CNT +
3270 1 + /* functionptr, TODO: store in data segment */
3273 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3275 /* create method header */
3277 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3278 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3279 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3280 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3281 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3282 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3283 (void) dseg_addlinenumbertablesize(cd);
3284 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3286 #if defined(ENABLE_PROFILING)
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));
3297 /* generate stub code */
3299 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3301 #if !defined(NDEBUG)
3302 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3303 emit_verbosecall_enter(jd);
3306 /* get function address (this must happen before the stackframeinfo) */
3308 #if !defined(WITH_STATIC_CLASSPATH)
3310 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3313 M_MOV_IMM(f, REG_ITMP3);
3316 /* save integer and float argument registers */
3318 for (i = 0, j = 0; i < md->paramcount; i++) {
3319 if (!md->params[i].inmemory) {
3320 s1 = md->params[i].regoff;
3322 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3323 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3325 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3331 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3333 /* create dynamic stack info */
3335 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3336 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3337 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3338 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3339 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3342 /* restore integer and float argument registers */
3344 for (i = 0, j = 0; i < md->paramcount; i++) {
3345 if (!md->params[i].inmemory) {
3346 s1 = md->params[i].regoff;
3348 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3349 M_LLD(rd->argintregs[s1], REG_SP, j * 8);
3351 M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
3357 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3360 /* copy or spill arguments to new locations */
3362 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3363 t = md->paramtypes[i].type;
3365 if (IS_INT_LNG_TYPE(t)) {
3366 if (!md->params[i].inmemory) {
3367 s1 = rd->argintregs[md->params[i].regoff];
3369 if (!nmd->params[j].inmemory) {
3370 s2 = rd->argintregs[nmd->params[j].regoff];
3374 s2 = nmd->params[j].regoff;
3375 M_LST(s1, REG_SP, s2 * 8);
3379 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3380 s2 = nmd->params[j].regoff;
3381 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3382 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3386 /* We only copy spilled float arguments, as the float argument */
3387 /* registers keep unchanged. */
3389 if (md->params[i].inmemory) {
3390 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3391 s2 = nmd->params[j].regoff;
3393 if (IS_2_WORD_TYPE(t)) {
3394 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3395 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3397 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3398 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3404 /* put class into second argument register */
3406 if (m->flags & ACC_STATIC)
3407 M_MOV_IMM(m->class, REG_A1);
3409 /* put env into first argument register */
3411 M_MOV_IMM(_Jv_env, REG_A0);
3413 /* do the native function call */
3417 /* save return value */
3419 if (md->returntype.type != TYPE_VOID) {
3420 if (IS_INT_LNG_TYPE(md->returntype.type))
3421 M_LST(REG_RESULT, REG_SP, 0 * 8);
3423 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3426 #if !defined(NDEBUG)
3427 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3428 emit_verbosecall_exit(jd);
3431 /* remove native stackframe info */
3433 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3434 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3436 M_MOV(REG_RESULT, REG_ITMP3);
3438 /* restore return value */
3440 if (md->returntype.type != TYPE_VOID) {
3441 if (IS_INT_LNG_TYPE(md->returntype.type))
3442 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3444 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3447 /* remove stackframe */
3449 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3451 /* test for exception */
3457 /* handle exception */
3459 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3460 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3461 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3463 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3466 /* generate patcher stubs */
3468 emit_patcher_stubs(jd);
3472 return code->entrypoint;
3477 * These are local overrides for various environment variables in Emacs.
3478 * Please do not remove this and leave it at the end of the file, where
3479 * Emacs will automagically detect them.
3480 * ---------------------------------------------------------------------
3483 * indent-tabs-mode: t
3487 * vim:noexpandtab:sw=4:ts=4: