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 7702 2007-04-15 01:15:59Z michi $
39 #include "vm/jit/x86_64/arch.h"
40 #include "vm/jit/x86_64/codegen.h"
41 #include "vm/jit/x86_64/emit.h"
43 #include "mm/memory.h"
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/abi.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/emit-common.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/parse.h"
65 #include "vm/jit/patcher.h"
66 #include "vm/jit/reg.h"
67 #include "vm/jit/replace.h"
68 #include "vm/jit/stacktrace.h"
70 #if defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
74 #include "vmcore/loader.h"
75 #include "vmcore/options.h"
76 #include "vmcore/statistics.h"
79 /* codegen_emit ****************************************************************
81 Generates machine code.
83 *******************************************************************************/
85 bool codegen_emit(jitdata *jd)
91 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 /* space to save used callee saved registers */
131 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
132 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
134 cd->stackframesize = rd->memuse + savedregs_num;
136 #if defined(ENABLE_THREADS)
137 /* space to save argument of monitor_enter */
139 if (checksync && (m->flags & ACC_SYNCHRONIZED))
140 cd->stackframesize++;
143 /* Keep stack of non-leaf functions 16-byte aligned for calls into
144 native code e.g. libc or jni (alignment problems with
147 if (!jd->isleafmethod || opt_verbosecall)
148 cd->stackframesize |= 0x1;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 #if defined(ENABLE_THREADS)
156 /* IsSync contains the offset relative to the stack pointer for the
157 argument of monitor_exit used in the exception handler. Since the
158 offset could be zero and give a wrong meaning of the flag it is
162 if (checksync && (m->flags & ACC_SYNCHRONIZED))
163 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
166 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
168 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
169 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
170 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
172 (void) dseg_addlinenumbertablesize(cd);
174 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
176 /* create exception table */
178 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
179 dseg_add_target(cd, ex->start);
180 dseg_add_target(cd, ex->end);
181 dseg_add_target(cd, ex->handler);
182 (void) dseg_add_unique_address(cd, ex->catchtype.any);
185 #if defined(ENABLE_PROFILING)
186 /* generate method profiling code */
188 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
189 /* count frequency */
191 M_MOV_IMM(code, REG_ITMP3);
192 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
198 /* create stack frame (if necessary) */
200 if (cd->stackframesize)
201 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
203 /* save used callee saved registers */
205 p = cd->stackframesize;
206 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
207 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
209 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
210 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
213 /* take arguments out of register or stack frame */
217 for (p = 0, l = 0; p < md->paramcount; p++) {
218 t = md->paramtypes[p].type;
220 varindex = jd->local_map[l * 5 + t];
223 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
226 if (varindex == UNUSED)
231 s1 = md->params[p].regoff;
233 if (IS_INT_LNG_TYPE(t)) { /* integer args */
234 s2 = rd->argintregs[s1];
235 if (!md->params[p].inmemory) { /* register arguments */
236 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
237 M_INTMOVE(s2, var->vv.regoff);
239 } else { /* reg arg -> spilled */
240 M_LST(s2, REG_SP, var->vv.regoff * 8);
243 } else { /* stack arguments */
244 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
245 /* + 8 for return address */
246 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
248 } else { /* stack arg -> spilled */
249 var->vv.regoff = cd->stackframesize + s1 + 1;
253 } else { /* floating args */
254 if (!md->params[p].inmemory) { /* register arguments */
255 s2 = rd->argfltregs[s1];
256 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
257 M_FLTMOVE(s2, var->vv.regoff);
259 } else { /* reg arg -> spilled */
260 M_DST(s2, REG_SP, var->vv.regoff * 8);
263 } else { /* stack arguments */
264 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
265 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
268 var->vv.regoff = cd->stackframesize + s1 + 1;
274 /* save monitorenter argument */
276 #if defined(ENABLE_THREADS)
277 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
278 /* stack offset for monitor argument */
282 if (opt_verbosecall) {
283 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
285 for (p = 0; p < INT_ARG_CNT; p++)
286 M_LST(rd->argintregs[p], REG_SP, p * 8);
288 for (p = 0; p < FLT_ARG_CNT; p++)
289 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
291 s1 += INT_ARG_CNT + FLT_ARG_CNT;
294 /* decide which monitor enter function to call */
296 if (m->flags & ACC_STATIC) {
297 M_MOV_IMM(&m->class->object.header, REG_A0);
302 M_ALD_MEM(REG_A0, EXCEPTION_HARDWARE_NULLPOINTER);
305 M_AST(REG_A0, REG_SP, s1 * 8);
306 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
309 if (opt_verbosecall) {
310 for (p = 0; p < INT_ARG_CNT; p++)
311 M_LLD(rd->argintregs[p], REG_SP, p * 8);
313 for (p = 0; p < FLT_ARG_CNT; p++)
314 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
316 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
322 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
323 emit_verbosecall_enter(jd);
324 #endif /* !defined(NDEBUG) */
328 /* end of header generation */
330 /* create replacement points */
332 REPLACEMENT_POINTS_INIT(cd, jd);
334 /* walk through all basic blocks */
336 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
338 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
340 if (bptr->flags >= BBREACHED) {
342 /* branch resolving */
344 codegen_resolve_branchrefs(cd, bptr);
346 /* handle replacement points */
348 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
350 /* copy interface registers to their destination */
355 #if defined(ENABLE_PROFILING)
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)
371 #if defined(ENABLE_LSRA)
375 src = bptr->invars[len];
376 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
377 if (bptr->type == BBTYPE_EXH) {
378 /* d = reg_of_var(rd, src, REG_ITMP1); */
379 if (!IS_INMEMORY(src->flags))
383 M_INTMOVE(REG_ITMP1, d);
384 emit_store(jd, NULL, src, d);
394 var = VAR(bptr->invars[len]);
395 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
396 if (bptr->type == BBTYPE_EXH) {
397 d = codegen_reg_of_var(0, var, REG_ITMP1);
398 M_INTMOVE(REG_ITMP1, d);
399 emit_store(jd, NULL, var, d);
403 assert((var->flags & INOUT));
406 #if defined(ENABLE_LSRA)
409 /* walk through all instructions */
414 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
415 if (iptr->line != currentline) {
416 dseg_addlinenumber(cd, iptr->line);
417 currentline = iptr->line;
420 MCODECHECK(1024); /* 1KB should be enough */
423 case ICMD_NOP: /* ... ==> ... */
424 case ICMD_POP: /* ..., value ==> ... */
425 case ICMD_POP2: /* ..., value, value ==> ... */
428 case ICMD_INLINE_START:
430 REPLACEMENT_POINT_INLINE_START(cd, iptr);
433 case ICMD_INLINE_BODY:
435 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
436 dseg_addlinenumber_inline_start(cd, iptr);
437 dseg_addlinenumber(cd, iptr->line);
440 case ICMD_INLINE_END:
442 dseg_addlinenumber_inline_end(cd, iptr);
443 dseg_addlinenumber(cd, iptr->line);
446 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
448 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
449 emit_nullpointer_check(cd, iptr, s1);
452 /* constant operations ************************************************/
454 case ICMD_ICONST: /* ... ==> ..., constant */
456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
457 ICONST(d, iptr->sx.val.i);
458 emit_store_dst(jd, iptr, d);
461 case ICMD_LCONST: /* ... ==> ..., constant */
463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
464 LCONST(d, iptr->sx.val.l);
465 emit_store_dst(jd, iptr, d);
468 case ICMD_FCONST: /* ... ==> ..., constant */
470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
471 disp = dseg_add_float(cd, iptr->sx.val.f);
472 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
473 emit_store_dst(jd, iptr, d);
476 case ICMD_DCONST: /* ... ==> ..., constant */
478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
479 disp = dseg_add_double(cd, iptr->sx.val.d);
480 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
481 emit_store_dst(jd, iptr, d);
484 case ICMD_ACONST: /* ... ==> ..., constant */
486 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
488 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
489 cr = iptr->sx.val.c.ref;
491 /* PROFILE_CYCLE_STOP; */
493 codegen_add_patch_ref(cd, PATCHER_aconst, cr, 0);
495 /* PROFILE_CYCLE_START; */
500 if (iptr->sx.val.anyptr == 0)
503 M_MOV_IMM(iptr->sx.val.anyptr, d);
505 emit_store_dst(jd, iptr, d);
509 /* load/store/copy/move operations ************************************/
511 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
512 case ICMD_ALOAD: /* s1 = local variable */
516 case ICMD_ISTORE: /* ..., value ==> ... */
523 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
527 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
528 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
531 /* integer operations *************************************************/
533 case ICMD_INEG: /* ..., value ==> ..., - value */
535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
536 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_LNEG: /* ..., value ==> ..., - value */
544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
548 emit_store_dst(jd, iptr, d);
551 case ICMD_I2L: /* ..., value ==> ..., value */
553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
556 emit_store_dst(jd, iptr, d);
559 case ICMD_L2I: /* ..., value ==> ..., value */
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
564 emit_store_dst(jd, iptr, d);
567 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
572 emit_store_dst(jd, iptr, d);
575 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
580 emit_store_dst(jd, iptr, d);
583 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
588 emit_store_dst(jd, iptr, d);
592 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 emit_store_dst(jd, iptr, d);
607 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
608 /* sx.val.i = constant */
610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
613 /* Using inc and dec is not faster than add (tested with
617 M_IADD_IMM(iptr->sx.val.i, d);
618 emit_store_dst(jd, iptr, d);
621 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
623 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
624 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
632 emit_store_dst(jd, iptr, d);
635 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
636 /* sx.val.l = constant */
638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
641 if (IS_IMM32(iptr->sx.val.l))
642 M_LADD_IMM(iptr->sx.val.l, d);
644 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
645 M_LADD(REG_ITMP2, d);
647 emit_store_dst(jd, iptr, d);
650 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656 M_INTMOVE(s1, REG_ITMP1);
657 M_ISUB(s2, REG_ITMP1);
658 M_INTMOVE(REG_ITMP1, d);
663 emit_store_dst(jd, iptr, d);
666 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
667 /* sx.val.i = constant */
669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
672 M_ISUB_IMM(iptr->sx.val.i, d);
673 emit_store_dst(jd, iptr, d);
676 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
682 M_INTMOVE(s1, REG_ITMP1);
683 M_LSUB(s2, REG_ITMP1);
684 M_INTMOVE(REG_ITMP1, d);
689 emit_store_dst(jd, iptr, d);
692 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
693 /* sx.val.l = constant */
695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
696 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
698 if (IS_IMM32(iptr->sx.val.l))
699 M_LSUB_IMM(iptr->sx.val.l, d);
701 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
702 M_LSUB(REG_ITMP2, d);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 emit_store_dst(jd, iptr, d);
721 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
722 /* sx.val.i = constant */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
726 if (iptr->sx.val.i == 2) {
730 M_IMUL_IMM(s1, iptr->sx.val.i, d);
731 emit_store_dst(jd, iptr, d);
734 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
737 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
745 emit_store_dst(jd, iptr, d);
748 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
749 /* sx.val.l = constant */
751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
753 if (IS_IMM32(iptr->sx.val.l))
754 M_LMUL_IMM(s1, iptr->sx.val.l, d);
756 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
758 M_LMUL(REG_ITMP2, d);
760 emit_store_dst(jd, iptr, d);
763 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
765 s1 = emit_load_s1(jd, iptr, RAX);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
767 d = codegen_reg_of_dst(jd, iptr, RAX);
770 M_INTMOVE(s2, REG_ITMP3);
771 emit_arithmetic_check(cd, iptr, REG_ITMP3);
773 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
775 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
777 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
778 M_BEQ(1 + 3); /* 6 bytes */
780 emit_cltd(cd); /* 1 byte */
781 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
784 emit_store_dst(jd, iptr, d);
785 dst = VAROP(iptr->dst);
786 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
787 M_MOV(REG_ITMP2, RDX); /* restore RDX */
790 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
792 s1 = emit_load_s1(jd, iptr, RAX);
793 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
794 d = codegen_reg_of_dst(jd, iptr, RDX);
797 M_INTMOVE(s2, REG_ITMP3);
798 emit_arithmetic_check(cd, iptr, REG_ITMP3);
800 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
802 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
804 M_CLR(RDX); /* 3 bytes */
805 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
806 M_BEQ(1 + 3); /* 6 bytes */
808 emit_cltd(cd); /* 1 byte */
809 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
812 emit_store_dst(jd, iptr, d);
813 dst = VAROP(iptr->dst);
814 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
815 M_MOV(REG_ITMP2, RDX); /* restore RDX */
818 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
819 /* sx.val.i = constant */
821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
823 M_INTMOVE(s1, REG_ITMP1);
824 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
825 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
826 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
827 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
828 emit_mov_reg_reg(cd, REG_ITMP1, d);
829 emit_store_dst(jd, iptr, d);
832 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
833 /* sx.val.i = constant */
835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
836 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
837 M_INTMOVE(s1, REG_ITMP1);
838 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
839 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
840 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
841 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
842 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
843 emit_mov_reg_reg(cd, REG_ITMP1, d);
844 emit_store_dst(jd, iptr, d);
848 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
850 s1 = emit_load_s1(jd, iptr, RAX);
851 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
852 d = codegen_reg_of_dst(jd, iptr, RAX);
855 M_INTMOVE(s2, REG_ITMP3);
856 emit_arithmetic_check(cd, iptr, REG_ITMP3);
858 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
860 /* check as described in jvm spec */
861 disp = dseg_add_s8(cd, 0x8000000000000000LL);
862 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
864 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
865 M_BEQ(2 + 3); /* 6 bytes */
867 emit_cqto(cd); /* 2 bytes */
868 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
871 emit_store_dst(jd, iptr, d);
872 dst = VAROP(iptr->dst);
873 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
874 M_MOV(REG_ITMP2, RDX); /* restore RDX */
877 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
879 s1 = emit_load_s1(jd, iptr, RAX);
880 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
881 d = codegen_reg_of_dst(jd, iptr, RDX);
884 M_INTMOVE(s2, REG_ITMP3);
885 emit_arithmetic_check(cd, iptr, REG_ITMP3);
887 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
889 /* check as described in jvm spec */
890 disp = dseg_add_s8(cd, 0x8000000000000000LL);
891 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
893 M_LXOR(RDX, RDX); /* 3 bytes */
894 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
895 M_BEQ(2 + 3); /* 6 bytes */
897 emit_cqto(cd); /* 2 bytes */
898 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
901 emit_store_dst(jd, iptr, d);
902 dst = VAROP(iptr->dst);
903 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
904 M_MOV(REG_ITMP2, RDX); /* restore RDX */
907 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
908 /* sx.val.i = constant */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
912 M_INTMOVE(s1, REG_ITMP1);
913 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
914 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
915 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
916 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
917 emit_mov_reg_reg(cd, REG_ITMP1, d);
918 emit_store_dst(jd, iptr, d);
921 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
922 /* sx.val.l = constant */
924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
926 M_INTMOVE(s1, REG_ITMP1);
927 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
928 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
929 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
930 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
931 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
932 emit_mov_reg_reg(cd, REG_ITMP1, d);
933 emit_store_dst(jd, iptr, d);
936 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
938 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
939 emit_ishift(jd, SHIFT_SHL, iptr);
942 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
943 /* sx.val.i = constant */
945 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
948 M_ISLL_IMM(iptr->sx.val.i, d);
949 emit_store_dst(jd, iptr, d);
952 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
954 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
955 emit_ishift(jd, SHIFT_SAR, iptr);
958 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
959 /* sx.val.i = constant */
961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
964 M_ISRA_IMM(iptr->sx.val.i, d);
965 emit_store_dst(jd, iptr, d);
968 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
970 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
971 emit_ishift(jd, SHIFT_SHR, iptr);
974 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
975 /* sx.val.i = constant */
977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
980 M_ISRL_IMM(iptr->sx.val.i, d);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
986 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
987 emit_lshift(jd, SHIFT_SHL, iptr);
990 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
991 /* sx.val.i = constant */
993 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
994 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
996 M_LSLL_IMM(iptr->sx.val.i, d);
997 emit_store_dst(jd, iptr, d);
1000 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1002 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1003 emit_lshift(jd, SHIFT_SAR, iptr);
1006 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1007 /* sx.val.i = constant */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1012 M_LSRA_IMM(iptr->sx.val.i, d);
1013 emit_store_dst(jd, iptr, d);
1016 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1018 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1019 emit_lshift(jd, SHIFT_SHR, iptr);
1022 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1023 /* sx.val.l = constant */
1025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1028 M_LSRL_IMM(iptr->sx.val.i, d);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1034 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1035 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1036 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1047 /* sx.val.i = constant */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1052 M_IAND_IMM(iptr->sx.val.i, d);
1053 emit_store_dst(jd, iptr, d);
1056 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1058 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1059 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1067 emit_store_dst(jd, iptr, d);
1070 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1071 /* sx.val.l = constant */
1073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1076 if (IS_IMM32(iptr->sx.val.l))
1077 M_LAND_IMM(iptr->sx.val.l, d);
1079 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1080 M_LAND(REG_ITMP2, d);
1082 emit_store_dst(jd, iptr, d);
1085 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1100 /* sx.val.i = constant */
1102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1105 M_IOR_IMM(iptr->sx.val.i, d);
1106 emit_store_dst(jd, iptr, d);
1109 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1113 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1120 emit_store_dst(jd, iptr, d);
1123 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1124 /* sx.val.l = constant */
1126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1127 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1129 if (IS_IMM32(iptr->sx.val.l))
1130 M_LOR_IMM(iptr->sx.val.l, d);
1132 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1133 M_LOR(REG_ITMP2, d);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1153 /* sx.val.i = constant */
1155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1156 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1158 M_IXOR_IMM(iptr->sx.val.i, d);
1159 emit_store_dst(jd, iptr, d);
1162 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1165 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1166 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1173 emit_store_dst(jd, iptr, d);
1176 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1177 /* sx.val.l = constant */
1179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1180 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1182 if (IS_IMM32(iptr->sx.val.l))
1183 M_LXOR_IMM(iptr->sx.val.l, d);
1185 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1186 M_LXOR(REG_ITMP2, d);
1188 emit_store_dst(jd, iptr, d);
1192 /* floating operations ************************************************/
1194 case ICMD_FNEG: /* ..., value ==> ..., - value */
1196 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1197 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1198 disp = dseg_add_s4(cd, 0x80000000);
1200 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1201 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_DNEG: /* ..., value ==> ..., - value */
1207 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1208 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1209 disp = dseg_add_s8(cd, 0x8000000000000000);
1211 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1212 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1218 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1219 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1220 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1227 emit_store_dst(jd, iptr, d);
1230 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1232 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1233 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1234 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1241 emit_store_dst(jd, iptr, d);
1244 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1246 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1247 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1248 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1250 M_FLTMOVE(s2, REG_FTMP2);
1255 emit_store_dst(jd, iptr, d);
1258 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1260 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1261 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1262 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1264 M_FLTMOVE(s2, REG_FTMP2);
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1274 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1275 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1276 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1283 emit_store_dst(jd, iptr, d);
1286 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1288 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1289 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1290 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1297 emit_store_dst(jd, iptr, d);
1300 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1302 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1303 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1304 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1306 M_FLTMOVE(s2, REG_FTMP2);
1311 emit_store_dst(jd, iptr, d);
1314 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1316 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1317 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1318 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1320 M_FLTMOVE(s2, REG_FTMP2);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1330 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1341 emit_store_dst(jd, iptr, d);
1344 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1347 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1349 emit_store_dst(jd, iptr, d);
1352 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1354 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1355 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1357 emit_store_dst(jd, iptr, d);
1360 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1362 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1363 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1365 M_ICMP_IMM(0x80000000, d); /* corner cases */
1366 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1367 ((REG_RESULT == d) ? 0 : 3);
1369 M_FLTMOVE(s1, REG_FTMP1);
1370 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1372 M_INTMOVE(REG_RESULT, d);
1373 emit_store_dst(jd, iptr, d);
1376 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1378 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1379 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1381 M_ICMP_IMM(0x80000000, d); /* corner cases */
1382 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1383 ((REG_RESULT == d) ? 0 : 3);
1385 M_FLTMOVE(s1, REG_FTMP1);
1386 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1388 M_INTMOVE(REG_RESULT, d);
1389 emit_store_dst(jd, iptr, d);
1392 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1394 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1397 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1398 M_LCMP(REG_ITMP2, d); /* corner cases */
1399 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1400 ((REG_RESULT == d) ? 0 : 3);
1402 M_FLTMOVE(s1, REG_FTMP1);
1403 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1405 M_INTMOVE(REG_RESULT, d);
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1411 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1412 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1414 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1415 M_LCMP(REG_ITMP2, d); /* corner cases */
1416 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1417 ((REG_RESULT == d) ? 0 : 3);
1419 M_FLTMOVE(s1, REG_FTMP1);
1420 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1422 M_INTMOVE(REG_RESULT, d);
1423 emit_store_dst(jd, iptr, d);
1426 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1428 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1429 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1431 emit_store_dst(jd, iptr, d);
1434 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1436 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1437 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1439 emit_store_dst(jd, iptr, d);
1442 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1443 /* == => 0, < => 1, > => -1 */
1445 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1446 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1449 M_MOV_IMM(1, REG_ITMP1);
1450 M_MOV_IMM(-1, REG_ITMP2);
1451 emit_ucomiss_reg_reg(cd, s1, s2);
1452 M_CMOVULT(REG_ITMP1, d);
1453 M_CMOVUGT(REG_ITMP2, d);
1454 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1455 emit_store_dst(jd, iptr, d);
1458 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1459 /* == => 0, < => 1, > => -1 */
1461 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1462 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1465 M_MOV_IMM(1, REG_ITMP1);
1466 M_MOV_IMM(-1, REG_ITMP2);
1467 emit_ucomiss_reg_reg(cd, s1, s2);
1468 M_CMOVULT(REG_ITMP1, d);
1469 M_CMOVUGT(REG_ITMP2, d);
1470 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1471 emit_store_dst(jd, iptr, d);
1474 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1475 /* == => 0, < => 1, > => -1 */
1477 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1478 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1481 M_MOV_IMM(1, REG_ITMP1);
1482 M_MOV_IMM(-1, REG_ITMP2);
1483 emit_ucomisd_reg_reg(cd, s1, s2);
1484 M_CMOVULT(REG_ITMP1, d);
1485 M_CMOVUGT(REG_ITMP2, d);
1486 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1487 emit_store_dst(jd, iptr, d);
1490 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1491 /* == => 0, < => 1, > => -1 */
1493 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1494 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1495 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1497 M_MOV_IMM(1, REG_ITMP1);
1498 M_MOV_IMM(-1, REG_ITMP2);
1499 emit_ucomisd_reg_reg(cd, s1, s2);
1500 M_CMOVULT(REG_ITMP1, d);
1501 M_CMOVUGT(REG_ITMP2, d);
1502 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1503 emit_store_dst(jd, iptr, d);
1507 /* memory operations **************************************************/
1509 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1513 /* implicit null-pointer check */
1514 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1515 emit_store_dst(jd, iptr, d);
1518 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1521 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1523 /* implicit null-pointer check */
1524 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1525 emit_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 /* implicit null-pointer check */
1535 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1536 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1537 emit_store_dst(jd, iptr, d);
1540 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1543 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1545 /* implicit null-pointer check */
1546 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1547 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1548 emit_store_dst(jd, iptr, d);
1551 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1554 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1556 /* implicit null-pointer check */
1557 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1558 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1559 emit_store_dst(jd, iptr, d);
1562 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1565 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1567 /* implicit null-pointer check */
1568 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1569 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1570 emit_store_dst(jd, iptr, d);
1573 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1578 /* implicit null-pointer check */
1579 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1580 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1581 emit_store_dst(jd, iptr, d);
1584 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1587 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1588 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1589 /* implicit null-pointer check */
1590 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1591 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1592 emit_store_dst(jd, iptr, d);
1595 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1597 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1598 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1600 /* implicit null-pointer check */
1601 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1602 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1603 emit_store_dst(jd, iptr, d);
1607 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1611 /* implicit null-pointer check */
1612 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1613 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1614 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1617 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621 /* implicit null-pointer check */
1622 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1623 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1624 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1627 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1631 /* implicit null-pointer check */
1632 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1633 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1634 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1637 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1641 /* implicit null-pointer check */
1642 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1643 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1644 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1647 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1651 /* implicit null-pointer check */
1652 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1653 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1654 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1657 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1660 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1661 /* implicit null-pointer check */
1662 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1663 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1664 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1667 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1671 /* implicit null-pointer check */
1672 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1673 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1674 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1677 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1681 /* implicit null-pointer check */
1682 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1683 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1687 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1689 emit_exception_check(cd, iptr);
1691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1692 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1693 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1694 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1698 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1702 /* implicit null-pointer check */
1703 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1704 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1707 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711 /* implicit null-pointer check */
1712 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1713 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1716 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1719 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1720 /* implicit null-pointer check */
1721 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1722 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1725 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1729 /* implicit null-pointer check */
1730 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1731 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1734 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1737 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1738 /* implicit null-pointer check */
1739 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1741 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1742 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1745 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1746 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1750 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1753 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1754 /* implicit null-pointer check */
1755 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1756 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1760 case ICMD_GETSTATIC: /* ... ==> ..., value */
1762 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1763 uf = iptr->sx.s23.s3.uf;
1764 fieldtype = uf->fieldref->parseddesc.fd->type;
1765 disp = dseg_add_unique_address(cd, NULL);
1766 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1768 /* must be calculated before codegen_add_patch_ref */
1771 disp -= PATCHER_CALL_SIZE;
1773 /* PROFILE_CYCLE_STOP; */
1775 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1777 /* PROFILE_CYCLE_START; */
1780 fi = iptr->sx.s23.s3.fmiref->p.field;
1781 fieldtype = fi->type;
1782 disp = dseg_add_address(cd, &(fi->value));
1783 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1785 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1788 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1790 PROFILE_CYCLE_START;
1793 disp -= PATCHER_CALL_SIZE;
1797 /* This approach is much faster than moving the field
1798 address inline into a register. */
1800 M_ALD(REG_ITMP1, RIP, disp);
1802 switch (fieldtype) {
1804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1805 M_ILD(d, REG_ITMP1, 0);
1809 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1810 M_LLD(d, REG_ITMP1, 0);
1813 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1814 M_FLD(d, REG_ITMP1, 0);
1817 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1818 M_DLD(d, REG_ITMP1, 0);
1821 emit_store_dst(jd, iptr, d);
1824 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1826 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1827 uf = iptr->sx.s23.s3.uf;
1828 fieldtype = uf->fieldref->parseddesc.fd->type;
1829 disp = dseg_add_unique_address(cd, NULL);
1830 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1832 /* must be calculated before codegen_add_patch_ref */
1835 disp -= PATCHER_CALL_SIZE;
1837 /* PROFILE_CYCLE_STOP; */
1839 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1841 /* PROFILE_CYCLE_START; */
1844 fi = iptr->sx.s23.s3.fmiref->p.field;
1845 fieldtype = fi->type;
1846 disp = dseg_add_address(cd, &(fi->value));
1847 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1849 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1852 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1854 PROFILE_CYCLE_START;
1857 disp -= PATCHER_CALL_SIZE;
1861 /* This approach is much faster than moving the field
1862 address inline into a register. */
1864 M_ALD(REG_ITMP1, RIP, disp);
1866 switch (fieldtype) {
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1869 M_IST(s1, REG_ITMP1, 0);
1873 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1874 M_LST(s1, REG_ITMP1, 0);
1877 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1878 M_FST(s1, REG_ITMP1, 0);
1881 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1882 M_DST(s1, REG_ITMP1, 0);
1887 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1888 /* val = value (in current instruction) */
1889 /* following NOP) */
1891 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1892 uf = iptr->sx.s23.s3.uf;
1893 fieldtype = uf->fieldref->parseddesc.fd->type;
1894 disp = dseg_add_unique_address(cd, NULL);
1895 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1897 /* must be calculated before codegen_add_patch_ref */
1900 disp -= PATCHER_CALL_SIZE;
1902 /* PROFILE_CYCLE_STOP; */
1904 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1906 /* PROFILE_CYCLE_START; */
1909 fi = iptr->sx.s23.s3.fmiref->p.field;
1910 fieldtype = fi->type;
1911 disp = dseg_add_address(cd, &(fi->value));
1912 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
1914 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1917 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
1919 PROFILE_CYCLE_START;
1922 disp -= PATCHER_CALL_SIZE;
1926 /* This approach is much faster than moving the field
1927 address inline into a register. */
1929 M_ALD(REG_ITMP1, RIP, disp);
1931 switch (fieldtype) {
1934 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1939 if (IS_IMM32(iptr->sx.s23.s2.constval))
1940 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1942 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1943 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1949 case ICMD_GETFIELD: /* ... ==> ..., value */
1951 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1954 uf = iptr->sx.s23.s3.uf;
1955 fieldtype = uf->fieldref->parseddesc.fd->type;
1958 /* PROFILE_CYCLE_STOP; */
1960 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1962 /* PROFILE_CYCLE_START; */
1965 fi = iptr->sx.s23.s3.fmiref->p.field;
1966 fieldtype = fi->type;
1970 /* implicit null-pointer check */
1971 switch (fieldtype) {
1973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1974 M_ILD32(d, s1, disp);
1978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1979 M_LLD32(d, s1, disp);
1982 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1983 M_FLD32(d, s1, disp);
1986 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1987 M_DLD32(d, s1, disp);
1990 emit_store_dst(jd, iptr, d);
1993 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1996 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1998 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1999 uf = iptr->sx.s23.s3.uf;
2000 fieldtype = uf->fieldref->parseddesc.fd->type;
2003 /* PROFILE_CYCLE_STOP; */
2005 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2007 /* PROFILE_CYCLE_START; */
2010 fi = iptr->sx.s23.s3.fmiref->p.field;
2011 fieldtype = fi->type;
2015 /* implicit null-pointer check */
2016 switch (fieldtype) {
2018 M_IST32(s2, s1, disp);
2022 M_LST32(s2, s1, disp);
2025 M_FST32(s2, s1, disp);
2028 M_DST32(s2, s1, disp);
2033 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2034 /* val = value (in current instruction) */
2035 /* following NOP) */
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2039 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2040 uf = iptr->sx.s23.s3.uf;
2041 fieldtype = uf->fieldref->parseddesc.fd->type;
2044 /* PROFILE_CYCLE_STOP; */
2046 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2048 /* PROFILE_CYCLE_START; */
2051 fi = iptr->sx.s23.s3.fmiref->p.field;
2052 fieldtype = fi->type;
2056 /* implicit null-pointer check */
2057 switch (fieldtype) {
2060 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2065 /* XXX why no check for IS_IMM32? */
2066 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2067 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2073 /* branch operations **************************************************/
2075 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2078 M_INTMOVE(s1, REG_ITMP1_XPTR);
2082 #ifdef ENABLE_VERIFIER
2083 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2084 uc = iptr->sx.s23.s2.uc;
2086 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2088 #endif /* ENABLE_VERIFIER */
2090 M_CALL_IMM(0); /* passing exception pc */
2091 M_POP(REG_ITMP2_XPC);
2093 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2097 case ICMD_GOTO: /* ... ==> ... */
2100 emit_br(cd, iptr->dst.block);
2104 case ICMD_JSR: /* ... ==> ... */
2106 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2110 case ICMD_IFNULL: /* ..., value ==> ... */
2111 case ICMD_IFNONNULL:
2113 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2115 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2118 case ICMD_IFEQ: /* ..., value ==> ... */
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 M_ICMP_IMM(iptr->sx.val.i, s1);
2127 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2130 case ICMD_IF_LEQ: /* ..., value ==> ... */
2137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2138 if (IS_IMM32(iptr->sx.val.l))
2139 M_LCMP_IMM(iptr->sx.val.l, s1);
2141 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2142 M_LCMP(REG_ITMP2, s1);
2144 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2147 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2148 case ICMD_IF_ICMPNE:
2149 case ICMD_IF_ICMPLT:
2150 case ICMD_IF_ICMPGE:
2151 case ICMD_IF_ICMPGT:
2152 case ICMD_IF_ICMPLE:
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2157 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2160 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2161 case ICMD_IF_ACMPNE:
2163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2164 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2166 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2169 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2170 case ICMD_IF_LCMPNE:
2171 case ICMD_IF_LCMPLT:
2172 case ICMD_IF_LCMPGE:
2173 case ICMD_IF_LCMPGT:
2174 case ICMD_IF_LCMPLE:
2176 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2177 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2179 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2182 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2185 REPLACEMENT_POINT_RETURN(cd, iptr);
2186 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2187 M_INTMOVE(s1, REG_RESULT);
2188 goto nowperformreturn;
2190 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2192 REPLACEMENT_POINT_RETURN(cd, iptr);
2193 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2194 M_INTMOVE(s1, REG_RESULT);
2196 #ifdef ENABLE_VERIFIER
2197 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2198 uc = iptr->sx.s23.s2.uc;
2202 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2204 PROFILE_CYCLE_START;
2206 #endif /* ENABLE_VERIFIER */
2207 goto nowperformreturn;
2209 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2212 REPLACEMENT_POINT_RETURN(cd, iptr);
2213 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2214 M_FLTMOVE(s1, REG_FRESULT);
2215 goto nowperformreturn;
2217 case ICMD_RETURN: /* ... ==> ... */
2219 REPLACEMENT_POINT_RETURN(cd, iptr);
2225 p = cd->stackframesize;
2227 #if !defined(NDEBUG)
2228 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2229 emit_verbosecall_exit(jd);
2230 #endif /* !defined(NDEBUG) */
2232 #if defined(ENABLE_THREADS)
2233 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2234 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2236 /* we need to save the proper return value */
2237 switch (iptr->opc) {
2241 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2245 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2249 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2252 /* and now restore the proper return value */
2253 switch (iptr->opc) {
2257 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2261 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2267 /* restore saved registers */
2269 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2270 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2272 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2273 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2276 /* deallocate stack */
2278 if (cd->stackframesize)
2279 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2281 /* generate method profiling code */
2290 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2293 branch_target_t *table;
2295 table = iptr->dst.table;
2297 l = iptr->sx.s23.s2.tablelow;
2298 i = iptr->sx.s23.s3.tablehigh;
2300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 M_INTMOVE(s1, REG_ITMP1);
2304 M_ISUB_IMM(l, REG_ITMP1);
2306 /* number of targets */
2311 M_ICMP_IMM(i - 1, REG_ITMP1);
2312 emit_bugt(cd, table[0].block);
2314 /* build jump table top down and use address of lowest entry */
2319 dseg_add_target(cd, table->block);
2323 /* length of dataseg after last dseg_add_target is used
2326 M_MOV_IMM(0, REG_ITMP2);
2328 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2334 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2337 lookup_target_t *lookup;
2339 lookup = iptr->dst.lookup;
2341 i = iptr->sx.s23.s2.lookupcount;
2343 MCODECHECK(8 + ((7 + 6) * i) + 5);
2344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2347 M_ICMP_IMM(lookup->value, s1);
2348 emit_beq(cd, lookup->target.block);
2352 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2358 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2360 bte = iptr->sx.s23.s3.bte;
2364 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2366 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2367 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2368 case ICMD_INVOKEINTERFACE:
2370 REPLACEMENT_POINT_INVOKE(cd, iptr);
2372 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2374 um = iptr->sx.s23.s3.um;
2375 md = um->methodref->parseddesc.md;
2378 lm = iptr->sx.s23.s3.fmiref->p.method;
2380 md = lm->parseddesc;
2384 s3 = md->paramcount;
2386 MCODECHECK((20 * s3) + 128);
2388 /* copy arguments to registers or stack location */
2390 for (s3 = s3 - 1; s3 >= 0; s3--) {
2391 var = VAR(iptr->sx.s23.s2.args[s3]);
2393 /* Already Preallocated (ARGVAR) ? */
2394 if (var->flags & PREALLOC)
2397 if (IS_INT_LNG_TYPE(var->type)) {
2398 if (!md->params[s3].inmemory) {
2399 s1 = rd->argintregs[md->params[s3].regoff];
2400 d = emit_load(jd, iptr, var, s1);
2404 d = emit_load(jd, iptr, var, REG_ITMP1);
2405 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2409 if (!md->params[s3].inmemory) {
2410 s1 = rd->argfltregs[md->params[s3].regoff];
2411 d = emit_load(jd, iptr, var, s1);
2415 d = emit_load(jd, iptr, var, REG_FTMP1);
2417 if (IS_2_WORD_TYPE(var->type))
2418 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2420 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2425 /* generate method profiling code */
2429 switch (iptr->opc) {
2431 M_MOV_IMM(bte->fp, REG_ITMP1);
2434 emit_exception_check(cd, iptr);
2437 case ICMD_INVOKESPECIAL:
2438 emit_nullpointer_check(cd, iptr, REG_A0);
2441 case ICMD_INVOKESTATIC:
2443 disp = dseg_add_unique_address(cd, NULL);
2444 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2446 /* must be calculated before codegen_add_patch_ref */
2449 disp -= PATCHER_CALL_SIZE;
2451 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2457 disp = dseg_add_functionptr(cd, lm->stubroutine);
2458 disp = disp + -((cd->mcodeptr + 7) - cd->mcodebase);
2460 /* a = (ptrint) lm->stubroutine; */
2463 /* M_MOV_IMM(a, REG_ITMP2); */
2464 M_ALD(REG_ITMP2, RIP, disp);
2468 case ICMD_INVOKEVIRTUAL:
2470 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2475 s1 = OFFSET(vftbl_t, table[0]) +
2476 sizeof(methodptr) * lm->vftblindex;
2479 /* implicit null-pointer check */
2480 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2481 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2485 case ICMD_INVOKEINTERFACE:
2487 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2493 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2494 sizeof(methodptr) * lm->class->index;
2496 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2499 /* implicit null-pointer check */
2500 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2501 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2502 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2507 /* generate method profiling code */
2509 PROFILE_CYCLE_START;
2511 /* store size of call code in replacement point */
2513 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2515 /* store return value */
2517 switch (md->returntype.type) {
2521 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2522 M_INTMOVE(REG_RESULT, s1);
2523 emit_store_dst(jd, iptr, s1);
2527 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2528 M_FLTMOVE(REG_FRESULT, s1);
2529 emit_store_dst(jd, iptr, s1);
2538 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2540 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2541 /* object type cast-check */
2544 vftbl_t *supervftbl;
2547 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2553 super = iptr->sx.s23.s3.c.cls;
2554 superindex = super->index;
2555 supervftbl = super->vftbl;
2558 #if defined(ENABLE_THREADS)
2559 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2563 /* if class is not resolved, check which code to call */
2565 if (super == NULL) {
2567 emit_label_beq(cd, BRANCH_LABEL_1);
2569 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2570 iptr->sx.s23.s3.c.ref, 0);
2572 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2573 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2574 emit_label_beq(cd, BRANCH_LABEL_2);
2577 /* interface checkcast code */
2579 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2580 if (super != NULL) {
2582 emit_label_beq(cd, BRANCH_LABEL_3);
2585 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2587 if (super == NULL) {
2588 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2589 iptr->sx.s23.s3.c.ref,
2594 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2595 M_ICMP_IMM32(superindex, REG_ITMP3);
2596 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2598 M_ALD32(REG_ITMP3, REG_ITMP2,
2599 OFFSET(vftbl_t, interfacetable[0]) -
2600 superindex * sizeof(methodptr*));
2602 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2605 emit_label_br(cd, BRANCH_LABEL_4);
2607 emit_label(cd, BRANCH_LABEL_3);
2610 /* class checkcast code */
2612 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2613 if (super == NULL) {
2614 emit_label(cd, BRANCH_LABEL_2);
2618 emit_label_beq(cd, BRANCH_LABEL_5);
2621 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2623 if (super == NULL) {
2624 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
2625 iptr->sx.s23.s3.c.ref,
2629 M_MOV_IMM(supervftbl, REG_ITMP3);
2630 #if defined(ENABLE_THREADS)
2631 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2633 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2635 /* if (s1 != REG_ITMP1) { */
2636 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2637 /* OFFSET(vftbl_t, baseval), */
2639 /* emit_movl_membase_reg(cd, REG_ITMP3, */
2640 /* OFFSET(vftbl_t, diffval), */
2642 /* #if defined(ENABLE_THREADS) */
2643 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2645 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
2649 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2650 M_ISUB(REG_ITMP3, REG_ITMP2);
2651 M_MOV_IMM(supervftbl, REG_ITMP3);
2652 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2654 #if defined(ENABLE_THREADS)
2655 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2657 M_ICMP(REG_ITMP3, REG_ITMP2);
2658 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
2661 emit_label(cd, BRANCH_LABEL_5);
2664 if (super == NULL) {
2665 emit_label(cd, BRANCH_LABEL_1);
2666 emit_label(cd, BRANCH_LABEL_4);
2669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2672 /* array type cast-check */
2674 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2675 M_INTMOVE(s1, REG_A0);
2677 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2678 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2679 iptr->sx.s23.s3.c.ref, 0);
2682 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2683 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2686 /* s1 may have been destroyed over the function call */
2687 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2689 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2695 emit_store_dst(jd, iptr, d);
2698 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2702 vftbl_t *supervftbl;
2705 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2711 super = iptr->sx.s23.s3.c.cls;
2712 superindex = super->index;
2713 supervftbl = super->vftbl;
2716 #if defined(ENABLE_THREADS)
2717 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2724 M_INTMOVE(s1, REG_ITMP1);
2730 /* if class is not resolved, check which code to call */
2732 if (super == NULL) {
2734 emit_label_beq(cd, BRANCH_LABEL_1);
2736 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2737 iptr->sx.s23.s3.c.ref, 0);
2739 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2740 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2741 emit_label_beq(cd, BRANCH_LABEL_2);
2744 /* interface instanceof code */
2746 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2747 if (super != NULL) {
2749 emit_label_beq(cd, BRANCH_LABEL_3);
2752 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2754 if (super == NULL) {
2755 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2756 iptr->sx.s23.s3.c.ref, 0);
2760 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2761 M_ICMP_IMM32(superindex, REG_ITMP3);
2763 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2766 M_ALD32(REG_ITMP1, REG_ITMP1,
2767 OFFSET(vftbl_t, interfacetable[0]) -
2768 superindex * sizeof(methodptr*));
2773 emit_label_br(cd, BRANCH_LABEL_4);
2775 emit_label(cd, BRANCH_LABEL_3);
2778 /* class instanceof code */
2780 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2781 if (super == NULL) {
2782 emit_label(cd, BRANCH_LABEL_2);
2786 emit_label_beq(cd, BRANCH_LABEL_5);
2789 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2791 if (super == NULL) {
2792 codegen_add_patch_ref(cd, PATCHER_instanceof_class,
2793 iptr->sx.s23.s3.c.ref, 0);
2796 M_MOV_IMM(supervftbl, REG_ITMP2);
2798 #if defined(ENABLE_THREADS)
2799 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2802 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2803 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
2804 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2806 #if defined(ENABLE_THREADS)
2807 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2810 M_ISUB(REG_ITMP2, REG_ITMP1);
2811 M_CLR(d); /* may be REG_ITMP2 */
2812 M_ICMP(REG_ITMP3, REG_ITMP1);
2816 emit_label(cd, BRANCH_LABEL_5);
2819 if (super == NULL) {
2820 emit_label(cd, BRANCH_LABEL_1);
2821 emit_label(cd, BRANCH_LABEL_4);
2824 emit_store_dst(jd, iptr, d);
2828 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2830 /* check for negative sizes and copy sizes to stack if necessary */
2832 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2834 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2836 /* copy SAVEDVAR sizes to stack */
2837 var = VAR(iptr->sx.s23.s2.args[s1]);
2839 /* Already Preallocated? */
2840 if (!(var->flags & PREALLOC)) {
2841 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2842 M_LST(s2, REG_SP, s1 * 8);
2846 /* is a patcher function set? */
2848 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2849 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2850 iptr->sx.s23.s3.c.ref, 0);
2853 /* a0 = dimension count */
2855 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2857 /* a1 = classinfo */
2859 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
2861 /* a2 = pointer to dimensions = stack pointer */
2863 M_MOV(REG_SP, REG_A2);
2865 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2868 /* check for exception before result assignment */
2870 emit_exception_check(cd, iptr);
2872 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2873 M_INTMOVE(REG_RESULT, s1);
2874 emit_store_dst(jd, iptr, s1);
2878 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2883 } /* for instruction */
2885 MCODECHECK(512); /* XXX require a lower number? */
2887 /* At the end of a basic block we may have to append some nops,
2888 because the patcher stub calling code might be longer than the
2889 actual instruction. So codepatching does not change the
2890 following block unintentionally. */
2892 if (cd->mcodeptr < cd->lastmcodeptr) {
2893 while (cd->mcodeptr < cd->lastmcodeptr) {
2898 } /* if (bptr -> flags >= BBREACHED) */
2899 } /* for basic block */
2901 dseg_createlinenumbertable(cd);
2903 /* generate stubs */
2905 emit_patcher_stubs(jd);
2906 REPLACEMENT_EMIT_STUBS(jd);
2908 /* everything's ok */
2914 /* codegen_emit_stub_compiler **************************************************
2916 Emit a stub routine which calls the compiler.
2918 *******************************************************************************/
2920 void codegen_emit_stub_compiler(jitdata *jd)
2925 /* get required compiler data */
2930 /* code for the stub */
2932 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
2933 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
2938 /* codegen_emit_stub_builtin ***************************************************
2940 Creates a stub routine which calls a builtin function.
2942 *******************************************************************************/
2944 void codegen_emit_stub_builtin(jitdata *jd, functionptr f)
2949 registerdata *rd; /* REMOVE ME */
2951 s4 i, j; /* count variables */
2954 /* get required compiler data */
2961 /* initialize variables */
2965 /* calculate stack frame size */
2967 cd->stackframesize =
2968 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2969 1; /* return value */
2971 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
2973 /* create method header */
2975 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2976 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2977 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2978 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2979 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2980 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2981 (void) dseg_addlinenumbertablesize(cd);
2982 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2984 /* generate stub code */
2986 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2988 #if defined(ENABLE_GC_CACAO)
2989 /* Save callee saved integer registers in stackframeinfo (GC may
2990 need to recover them during a collection). */
2992 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
2993 OFFSET(stackframeinfo, intregs);
2995 for (i = 0; i < INT_SAV_CNT; i++)
2996 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2999 /* save integer and float argument registers */
3001 for (i = 0, j = 0; i < md->paramcount; i++) {
3002 if (!md->params[i].inmemory) {
3003 s1 = md->params[i].regoff;
3005 switch (md->paramtypes[i].type) {
3009 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3013 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3021 /* create dynamic stack info */
3023 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3024 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3025 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3026 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3027 M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
3030 /* restore integer and float argument registers */
3032 for (i = 0, j = 0; i < md->paramcount; i++) {
3033 if (!md->params[i].inmemory) {
3034 s1 = md->params[i].regoff;
3036 switch (md->paramtypes[i].type) {
3040 M_LLD(abi_registers_integer_argument[s1], REG_SP, j * 8);
3044 M_DLD(abi_registers_integer_argument[s1], REG_SP, j * 8);
3052 /* call the builtin function */
3054 M_MOV_IMM(f, REG_ITMP3);
3057 /* save return value */
3059 switch (md->returntype.type) {
3063 M_LST(REG_RESULT, REG_SP, 0 * 8);
3067 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3073 /* remove native stackframe info */
3075 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3076 M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
3079 /* restore return value */
3081 switch (md->returntype.type) {
3085 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3089 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3095 #if defined(ENABLE_GC_CACAO)
3096 /* Restore callee saved integer registers from stackframeinfo (GC
3097 might have modified them during a collection). */
3099 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3100 OFFSET(stackframeinfo, intregs);
3102 for (i = 0; i < INT_SAV_CNT; i++)
3103 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3106 /* remove stackframe */
3108 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3113 /* codegen_emit_stub_native ****************************************************
3115 Emits a stub routine which calls a native method.
3117 *******************************************************************************/
3119 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3127 s4 i, j; /* count variables */
3131 /* get required compiler data */
3138 /* initialize variables */
3141 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3143 /* calculate stack frame size */
3145 cd->stackframesize =
3146 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3147 sizeof(localref_table) / SIZEOF_VOID_P +
3148 INT_ARG_CNT + FLT_ARG_CNT +
3149 1 + /* functionptr, TODO: store in data segment */
3152 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3154 /* create method header */
3156 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3157 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3158 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3159 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3160 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3161 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3162 (void) dseg_addlinenumbertablesize(cd);
3163 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3165 #if defined(ENABLE_PROFILING)
3166 /* generate native method profiling code */
3168 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3169 /* count frequency */
3171 M_MOV_IMM(code, REG_ITMP3);
3172 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3176 /* generate stub code */
3178 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3180 #if !defined(NDEBUG)
3181 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3182 emit_verbosecall_enter(jd);
3185 /* get function address (this must happen before the stackframeinfo) */
3187 #if !defined(WITH_STATIC_CLASSPATH)
3189 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3192 M_MOV_IMM(f, REG_ITMP3);
3194 #if defined(ENABLE_GC_CACAO)
3195 /* Save callee saved integer registers in stackframeinfo (GC may
3196 need to recover them during a collection). */
3198 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3199 OFFSET(stackframeinfo, intregs);
3201 for (i = 0; i < INT_SAV_CNT; i++)
3202 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3205 /* save integer and float argument registers */
3207 for (i = 0, j = 0; i < md->paramcount; i++) {
3208 if (!md->params[i].inmemory) {
3209 s1 = md->params[i].regoff;
3211 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3212 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3214 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3220 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3222 /* create dynamic stack info */
3224 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3225 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3226 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3227 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3228 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3231 /* restore integer and float argument registers */
3233 for (i = 0, j = 0; i < md->paramcount; i++) {
3234 if (!md->params[i].inmemory) {
3235 s1 = md->params[i].regoff;
3237 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3238 M_LLD(rd->argintregs[s1], REG_SP, j * 8);
3240 M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
3246 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3249 /* copy or spill arguments to new locations */
3251 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3252 t = md->paramtypes[i].type;
3254 if (IS_INT_LNG_TYPE(t)) {
3255 if (!md->params[i].inmemory) {
3256 s1 = rd->argintregs[md->params[i].regoff];
3258 if (!nmd->params[j].inmemory) {
3259 s2 = rd->argintregs[nmd->params[j].regoff];
3263 s2 = nmd->params[j].regoff;
3264 M_LST(s1, REG_SP, s2 * 8);
3268 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3269 s2 = nmd->params[j].regoff;
3270 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3271 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3275 /* We only copy spilled float arguments, as the float argument */
3276 /* registers keep unchanged. */
3278 if (md->params[i].inmemory) {
3279 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3280 s2 = nmd->params[j].regoff;
3282 if (IS_2_WORD_TYPE(t)) {
3283 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3284 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3286 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3287 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3293 /* put class into second argument register */
3295 if (m->flags & ACC_STATIC)
3296 M_MOV_IMM(m->class, REG_A1);
3298 /* put env into first argument register */
3300 M_MOV_IMM(_Jv_env, REG_A0);
3302 /* do the native function call */
3306 /* save return value */
3308 if (md->returntype.type != TYPE_VOID) {
3309 if (IS_INT_LNG_TYPE(md->returntype.type))
3310 M_LST(REG_RESULT, REG_SP, 0 * 8);
3312 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3315 #if !defined(NDEBUG)
3316 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3317 emit_verbosecall_exit(jd);
3320 /* remove native stackframe info */
3322 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3323 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3325 M_MOV(REG_RESULT, REG_ITMP3);
3327 /* restore return value */
3329 if (md->returntype.type != TYPE_VOID) {
3330 if (IS_INT_LNG_TYPE(md->returntype.type))
3331 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3333 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3336 #if defined(ENABLE_GC_CACAO)
3337 /* Restore callee saved integer registers from stackframeinfo (GC
3338 might have modified them during a collection). */
3340 disp = cd->stackframesize * 8 - sizeof(stackframeinfo) +
3341 OFFSET(stackframeinfo, intregs);
3343 for (i = 0; i < INT_SAV_CNT; i++)
3344 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3347 /* remove stackframe */
3349 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3351 /* test for exception */
3357 /* handle exception */
3359 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3360 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3361 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3363 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3366 /* generate patcher stubs */
3368 emit_patcher_stubs(jd);
3373 * These are local overrides for various environment variables in Emacs.
3374 * Please do not remove this and leave it at the end of the file, where
3375 * Emacs will automagically detect them.
3376 * ---------------------------------------------------------------------
3379 * indent-tabs-mode: t
3383 * vim:noexpandtab:sw=4:ts=4: