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
38 #include "vm/jit/x86_64/arch.h"
39 #include "vm/jit/x86_64/codegen.h"
40 #include "vm/jit/x86_64/emit.h"
42 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/localref.h"
46 #include "native/native.h"
48 #include "threads/lock-common.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/primitive.h"
54 #include "vm/stringlocal.h"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/code.h"
60 #include "vm/jit/codegen-common.h"
61 #include "vm/jit/dseg.h"
62 #include "vm/jit/emit-common.h"
63 #include "vm/jit/jit.h"
64 #include "vm/jit/linenumbertable.h"
65 #include "vm/jit/methodheader.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher-common.h"
68 #include "vm/jit/reg.h"
69 #include "vm/jit/replace.h"
70 #include "vm/jit/stacktrace.h"
71 #include "vm/jit/trap.h"
73 #if defined(ENABLE_LSRA)
74 # include "vm/jit/allocator/lsra.h"
77 #include "vmcore/loader.h"
78 #include "vmcore/options.h"
79 #include "vmcore/statistics.h"
82 /* codegen_emit ****************************************************************
84 Generates machine code.
86 *******************************************************************************/
88 bool codegen_emit(jitdata *jd)
94 s4 len, s1, s2, s3, d, disp;
100 constant_classref *cr;
101 unresolved_class *uc;
102 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
103 unresolved_method *um;
104 builtintable_entry *bte;
107 unresolved_field *uf;
111 /* get required compiler data */
118 /* prevent compiler warnings */
131 /* space to save used callee saved registers */
133 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
134 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
136 cd->stackframesize = rd->memuse + savedregs_num;
138 #if defined(ENABLE_THREADS)
139 /* space to save argument of monitor_enter */
141 if (checksync && code_is_synchronized(code))
142 cd->stackframesize++;
145 /* Keep stack of non-leaf functions 16-byte aligned for calls into
146 native code e.g. libc or jni (alignment problems with
149 if (!code_is_leafmethod(code) || opt_verbosecall)
150 cd->stackframesize |= 0x1;
152 /* create method header */
154 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
155 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
157 code->synchronizedoffset = rd->memuse * 8;
159 if (code_is_leafmethod(code))
160 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
162 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
164 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
165 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
167 #if defined(ENABLE_PROFILING)
168 /* generate method profiling code */
170 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
171 /* count frequency */
173 M_MOV_IMM(code, REG_ITMP3);
174 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
180 /* create stack frame (if necessary) */
182 if (cd->stackframesize)
183 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
185 /* save used callee saved registers */
187 p = cd->stackframesize;
188 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
189 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
191 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
192 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
195 /* take arguments out of register or stack frame */
199 for (p = 0, l = 0; p < md->paramcount; p++) {
200 t = md->paramtypes[p].type;
202 varindex = jd->local_map[l * 5 + t];
205 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
208 if (varindex == UNUSED)
213 s1 = md->params[p].regoff;
215 if (IS_INT_LNG_TYPE(t)) { /* integer args */
216 if (!md->params[p].inmemory) { /* register arguments */
217 if (!IS_INMEMORY(var->flags))
218 M_INTMOVE(s1, var->vv.regoff);
220 M_LST(s1, REG_SP, var->vv.regoff);
222 else { /* stack arguments */
223 if (!IS_INMEMORY(var->flags))
224 /* + 8 for return address */
225 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
227 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
230 else { /* floating args */
231 if (!md->params[p].inmemory) { /* register arguments */
232 if (!IS_INMEMORY(var->flags))
233 M_FLTMOVE(s1, var->vv.regoff);
235 M_DST(s1, REG_SP, var->vv.regoff);
237 else { /* stack arguments */
238 if (!IS_INMEMORY(var->flags))
239 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
241 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
246 /* save monitorenter argument */
248 #if defined(ENABLE_THREADS)
249 if (checksync && code_is_synchronized(code)) {
250 /* stack offset for monitor argument */
254 if (opt_verbosecall) {
255 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
257 for (p = 0; p < INT_ARG_CNT; p++)
258 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
260 for (p = 0; p < FLT_ARG_CNT; p++)
261 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
263 s1 += INT_ARG_CNT + FLT_ARG_CNT;
266 /* decide which monitor enter function to call */
268 if (m->flags & ACC_STATIC) {
269 M_MOV_IMM(&m->clazz->object.header, REG_A0);
274 M_ALD_MEM(REG_A0, TRAP_NullPointerException);
277 M_AST(REG_A0, REG_SP, s1 * 8);
278 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
281 if (opt_verbosecall) {
282 for (p = 0; p < INT_ARG_CNT; p++)
283 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
285 for (p = 0; p < FLT_ARG_CNT; p++)
286 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
288 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
294 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
295 emit_verbosecall_enter(jd);
296 #endif /* !defined(NDEBUG) */
300 /* end of header generation */
302 /* create replacement points */
304 REPLACEMENT_POINTS_INIT(cd, jd);
306 /* walk through all basic blocks */
308 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
310 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
312 if (bptr->flags >= BBREACHED) {
314 /* branch resolving */
316 codegen_resolve_branchrefs(cd, bptr);
318 /* handle replacement points */
320 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
322 /* copy interface registers to their destination */
327 #if defined(ENABLE_PROFILING)
328 /* generate basicblock profiling code */
330 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
331 /* count frequency */
333 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
334 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
336 /* if this is an exception handler, start profiling again */
338 if (bptr->type == BBTYPE_EXH)
343 #if defined(ENABLE_LSRA)
347 src = bptr->invars[len];
348 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
349 if (bptr->type == BBTYPE_EXH) {
350 /* d = reg_of_var(rd, src, REG_ITMP1); */
351 if (!IS_INMEMORY(src->flags))
355 M_INTMOVE(REG_ITMP1, d);
356 emit_store(jd, NULL, src, d);
366 var = VAR(bptr->invars[len]);
367 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
368 if (bptr->type == BBTYPE_EXH) {
369 d = codegen_reg_of_var(0, var, REG_ITMP1);
370 M_INTMOVE(REG_ITMP1, d);
371 emit_store(jd, NULL, var, d);
375 assert((var->flags & INOUT));
378 #if defined(ENABLE_LSRA)
381 /* walk through all instructions */
386 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
387 if (iptr->line != currentline) {
388 linenumbertable_list_entry_add(cd, iptr->line);
389 currentline = iptr->line;
392 MCODECHECK(1024); /* 1KB should be enough */
395 case ICMD_NOP: /* ... ==> ... */
396 case ICMD_POP: /* ..., value ==> ... */
397 case ICMD_POP2: /* ..., value, value ==> ... */
400 case ICMD_INLINE_START:
402 REPLACEMENT_POINT_INLINE_START(cd, iptr);
405 case ICMD_INLINE_BODY:
407 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
408 linenumbertable_list_entry_add_inline_start(cd, iptr);
409 linenumbertable_list_entry_add(cd, iptr->line);
412 case ICMD_INLINE_END:
414 linenumbertable_list_entry_add_inline_end(cd, iptr);
415 linenumbertable_list_entry_add(cd, iptr->line);
418 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
421 emit_nullpointer_check(cd, iptr, s1);
424 /* constant operations ************************************************/
426 case ICMD_ICONST: /* ... ==> ..., constant */
428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
429 ICONST(d, iptr->sx.val.i);
430 emit_store_dst(jd, iptr, d);
433 case ICMD_LCONST: /* ... ==> ..., constant */
435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
436 LCONST(d, iptr->sx.val.l);
437 emit_store_dst(jd, iptr, d);
440 case ICMD_FCONST: /* ... ==> ..., constant */
442 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
443 disp = dseg_add_float(cd, iptr->sx.val.f);
444 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
445 emit_store_dst(jd, iptr, d);
448 case ICMD_DCONST: /* ... ==> ..., constant */
450 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
451 disp = dseg_add_double(cd, iptr->sx.val.d);
452 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
453 emit_store_dst(jd, iptr, d);
456 case ICMD_ACONST: /* ... ==> ..., constant */
458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
460 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
461 cr = iptr->sx.val.c.ref;
462 disp = dseg_add_unique_address(cd, cr);
464 /* PROFILE_CYCLE_STOP; */
466 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
469 /* PROFILE_CYCLE_START; */
474 if (iptr->sx.val.anyptr == 0) {
478 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
482 emit_store_dst(jd, iptr, d);
486 /* load/store/copy/move operations ************************************/
488 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
489 case ICMD_ALOAD: /* s1 = local variable */
493 case ICMD_ISTORE: /* ..., value ==> ... */
504 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
508 /* integer operations *************************************************/
510 case ICMD_INEG: /* ..., value ==> ..., - value */
512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
513 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
516 emit_store_dst(jd, iptr, d);
519 case ICMD_LNEG: /* ..., value ==> ..., - value */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
525 emit_store_dst(jd, iptr, d);
528 case ICMD_I2L: /* ..., value ==> ..., value */
530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
533 emit_store_dst(jd, iptr, d);
536 case ICMD_L2I: /* ..., value ==> ..., value */
538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
541 emit_store_dst(jd, iptr, d);
544 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
557 emit_store_dst(jd, iptr, d);
560 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
565 emit_store_dst(jd, iptr, d);
569 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
573 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580 emit_store_dst(jd, iptr, d);
584 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
585 /* sx.val.i = constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
590 /* Using inc and dec is not faster than add (tested with
594 M_IADD_IMM(iptr->sx.val.i, d);
595 emit_store_dst(jd, iptr, d);
598 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
609 emit_store_dst(jd, iptr, d);
612 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
613 /* sx.val.l = constant */
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
618 if (IS_IMM32(iptr->sx.val.l))
619 M_LADD_IMM(iptr->sx.val.l, d);
621 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
622 M_LADD(REG_ITMP2, d);
624 emit_store_dst(jd, iptr, d);
627 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
631 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
633 M_INTMOVE(s1, REG_ITMP1);
634 M_ISUB(s2, REG_ITMP1);
635 M_INTMOVE(REG_ITMP1, d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
644 /* sx.val.i = constant */
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
649 M_ISUB_IMM(iptr->sx.val.i, d);
650 emit_store_dst(jd, iptr, d);
653 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
656 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
659 M_INTMOVE(s1, REG_ITMP1);
660 M_LSUB(s2, REG_ITMP1);
661 M_INTMOVE(REG_ITMP1, d);
666 emit_store_dst(jd, iptr, d);
669 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
670 /* sx.val.l = constant */
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
675 if (IS_IMM32(iptr->sx.val.l))
676 M_LSUB_IMM(iptr->sx.val.l, d);
678 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
679 M_LSUB(REG_ITMP2, d);
681 emit_store_dst(jd, iptr, d);
684 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695 emit_store_dst(jd, iptr, d);
698 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
699 /* sx.val.i = constant */
701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
703 if (iptr->sx.val.i == 2) {
707 M_IMUL_IMM(s1, iptr->sx.val.i, d);
708 emit_store_dst(jd, iptr, d);
711 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
713 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
714 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
715 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
722 emit_store_dst(jd, iptr, d);
725 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
726 /* sx.val.l = constant */
728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
729 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
730 if (IS_IMM32(iptr->sx.val.l))
731 M_LMUL_IMM(s1, iptr->sx.val.l, d);
733 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
735 M_LMUL(REG_ITMP2, d);
737 emit_store_dst(jd, iptr, d);
740 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
742 s1 = emit_load_s1(jd, iptr, RAX);
743 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
744 d = codegen_reg_of_dst(jd, iptr, RAX);
747 M_INTMOVE(s2, REG_ITMP3);
748 emit_arithmetic_check(cd, iptr, REG_ITMP3);
750 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
752 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
754 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
755 M_BEQ(1 + 3); /* 6 bytes */
757 emit_cltd(cd); /* 1 byte */
758 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
761 emit_store_dst(jd, iptr, d);
762 dst = VAROP(iptr->dst);
763 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
764 M_MOV(REG_ITMP2, RDX); /* restore RDX */
767 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
769 s1 = emit_load_s1(jd, iptr, RAX);
770 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
771 d = codegen_reg_of_dst(jd, iptr, RDX);
774 M_INTMOVE(s2, REG_ITMP3);
775 emit_arithmetic_check(cd, iptr, REG_ITMP3);
777 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
779 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
781 M_CLR(RDX); /* 3 bytes */
782 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
783 M_BEQ(1 + 3); /* 6 bytes */
785 emit_cltd(cd); /* 1 byte */
786 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
789 emit_store_dst(jd, iptr, d);
790 dst = VAROP(iptr->dst);
791 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
792 M_MOV(REG_ITMP2, RDX); /* restore RDX */
795 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
796 /* sx.val.i = constant */
798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
800 M_INTMOVE(s1, REG_ITMP1);
801 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
802 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
803 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
804 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
805 emit_mov_reg_reg(cd, REG_ITMP1, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
810 /* sx.val.i = constant */
812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
814 M_INTMOVE(s1, REG_ITMP1);
815 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
816 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
817 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
818 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
819 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
820 emit_mov_reg_reg(cd, REG_ITMP1, d);
821 emit_store_dst(jd, iptr, d);
825 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
827 s1 = emit_load_s1(jd, iptr, RAX);
828 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
829 d = codegen_reg_of_dst(jd, iptr, RAX);
832 M_INTMOVE(s2, REG_ITMP3);
833 emit_arithmetic_check(cd, iptr, REG_ITMP3);
835 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
837 /* check as described in jvm spec */
838 disp = dseg_add_s8(cd, 0x8000000000000000LL);
839 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
841 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
842 M_BEQ(2 + 3); /* 6 bytes */
844 emit_cqto(cd); /* 2 bytes */
845 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
848 emit_store_dst(jd, iptr, d);
849 dst = VAROP(iptr->dst);
850 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
851 M_MOV(REG_ITMP2, RDX); /* restore RDX */
854 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
856 s1 = emit_load_s1(jd, iptr, RAX);
857 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
858 d = codegen_reg_of_dst(jd, iptr, RDX);
861 M_INTMOVE(s2, REG_ITMP3);
862 emit_arithmetic_check(cd, iptr, REG_ITMP3);
864 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
866 /* check as described in jvm spec */
867 disp = dseg_add_s8(cd, 0x8000000000000000LL);
868 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
870 M_LXOR(RDX, RDX); /* 3 bytes */
871 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
872 M_BEQ(2 + 3); /* 6 bytes */
874 emit_cqto(cd); /* 2 bytes */
875 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
878 emit_store_dst(jd, iptr, d);
879 dst = VAROP(iptr->dst);
880 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
881 M_MOV(REG_ITMP2, RDX); /* restore RDX */
884 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
885 /* sx.val.i = constant */
887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
889 M_INTMOVE(s1, REG_ITMP1);
890 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
891 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
892 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
893 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
894 emit_mov_reg_reg(cd, REG_ITMP1, d);
895 emit_store_dst(jd, iptr, d);
898 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
899 /* sx.val.l = constant */
901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
902 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
903 M_INTMOVE(s1, REG_ITMP1);
904 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
905 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
906 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
907 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
908 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
909 emit_mov_reg_reg(cd, REG_ITMP1, d);
910 emit_store_dst(jd, iptr, d);
913 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
915 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
916 emit_ishift(jd, SHIFT_SHL, iptr);
919 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
920 /* sx.val.i = constant */
922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
925 M_ISLL_IMM(iptr->sx.val.i, d);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
931 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
932 emit_ishift(jd, SHIFT_SAR, iptr);
935 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
936 /* sx.val.i = constant */
938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
939 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
941 M_ISRA_IMM(iptr->sx.val.i, d);
942 emit_store_dst(jd, iptr, d);
945 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
947 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
948 emit_ishift(jd, SHIFT_SHR, iptr);
951 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
952 /* sx.val.i = constant */
954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
955 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
957 M_ISRL_IMM(iptr->sx.val.i, d);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
963 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
964 emit_lshift(jd, SHIFT_SHL, iptr);
967 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
968 /* sx.val.i = constant */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
973 M_LSLL_IMM(iptr->sx.val.i, d);
974 emit_store_dst(jd, iptr, d);
977 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
979 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
980 emit_lshift(jd, SHIFT_SAR, iptr);
983 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
984 /* sx.val.i = constant */
986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
987 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
989 M_LSRA_IMM(iptr->sx.val.i, d);
990 emit_store_dst(jd, iptr, d);
993 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
995 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
996 emit_lshift(jd, SHIFT_SHR, iptr);
999 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1000 /* sx.val.l = constant */
1002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1005 M_LSRL_IMM(iptr->sx.val.i, d);
1006 emit_store_dst(jd, iptr, d);
1009 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1012 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1013 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1020 emit_store_dst(jd, iptr, d);
1023 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1024 /* sx.val.i = constant */
1026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1027 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1029 M_IAND_IMM(iptr->sx.val.i, d);
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1044 emit_store_dst(jd, iptr, d);
1047 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1048 /* sx.val.l = constant */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1053 if (IS_IMM32(iptr->sx.val.l))
1054 M_LAND_IMM(iptr->sx.val.l, d);
1056 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1057 M_LAND(REG_ITMP2, d);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1065 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1073 emit_store_dst(jd, iptr, d);
1076 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1077 /* sx.val.i = constant */
1079 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1080 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1082 M_IOR_IMM(iptr->sx.val.i, d);
1083 emit_store_dst(jd, iptr, d);
1086 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1097 emit_store_dst(jd, iptr, d);
1100 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1101 /* sx.val.l = constant */
1103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1104 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1106 if (IS_IMM32(iptr->sx.val.l))
1107 M_LOR_IMM(iptr->sx.val.l, d);
1109 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1110 M_LOR(REG_ITMP2, d);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1119 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1126 emit_store_dst(jd, iptr, d);
1129 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1130 /* sx.val.i = constant */
1132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1135 M_IXOR_IMM(iptr->sx.val.i, d);
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1150 emit_store_dst(jd, iptr, d);
1153 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1154 /* sx.val.l = constant */
1156 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1157 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1159 if (IS_IMM32(iptr->sx.val.l))
1160 M_LXOR_IMM(iptr->sx.val.l, d);
1162 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1163 M_LXOR(REG_ITMP2, d);
1165 emit_store_dst(jd, iptr, d);
1169 /* floating operations ************************************************/
1171 case ICMD_FNEG: /* ..., value ==> ..., - value */
1173 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1174 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1175 disp = dseg_add_s4(cd, 0x80000000);
1177 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1178 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1179 emit_store_dst(jd, iptr, d);
1182 case ICMD_DNEG: /* ..., value ==> ..., - value */
1184 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1185 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1186 disp = dseg_add_s8(cd, 0x8000000000000000);
1188 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1189 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1197 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 emit_store_dst(jd, iptr, d);
1207 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1209 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1210 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1211 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1218 emit_store_dst(jd, iptr, d);
1221 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1223 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1224 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1225 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1227 M_FLTMOVE(s2, REG_FTMP2);
1232 emit_store_dst(jd, iptr, d);
1235 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1237 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1238 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1239 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1241 M_FLTMOVE(s2, REG_FTMP2);
1246 emit_store_dst(jd, iptr, d);
1249 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1251 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1252 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1253 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1260 emit_store_dst(jd, iptr, d);
1263 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1267 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1274 emit_store_dst(jd, iptr, d);
1277 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1279 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1280 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1281 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1283 M_FLTMOVE(s2, REG_FTMP2);
1288 emit_store_dst(jd, iptr, d);
1291 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1293 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1294 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1295 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1297 M_FLTMOVE(s2, REG_FTMP2);
1302 emit_store_dst(jd, iptr, d);
1305 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1308 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1310 emit_store_dst(jd, iptr, d);
1313 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1316 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1326 emit_store_dst(jd, iptr, d);
1329 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1331 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1332 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1339 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1342 M_ICMP_IMM(0x80000000, d); /* corner cases */
1343 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1344 ((REG_RESULT == d) ? 0 : 3);
1346 M_FLTMOVE(s1, REG_FTMP1);
1347 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1349 M_INTMOVE(REG_RESULT, d);
1350 emit_store_dst(jd, iptr, d);
1353 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1355 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1356 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1358 M_ICMP_IMM(0x80000000, d); /* corner cases */
1359 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1360 ((REG_RESULT == d) ? 0 : 3);
1362 M_FLTMOVE(s1, REG_FTMP1);
1363 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1365 M_INTMOVE(REG_RESULT, d);
1366 emit_store_dst(jd, iptr, d);
1369 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1371 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1374 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1375 M_LCMP(REG_ITMP2, d); /* corner cases */
1376 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1377 ((REG_RESULT == d) ? 0 : 3);
1379 M_FLTMOVE(s1, REG_FTMP1);
1380 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1382 M_INTMOVE(REG_RESULT, d);
1383 emit_store_dst(jd, iptr, d);
1386 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1388 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1391 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1392 M_LCMP(REG_ITMP2, d); /* corner cases */
1393 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1394 ((REG_RESULT == d) ? 0 : 3);
1396 M_FLTMOVE(s1, REG_FTMP1);
1397 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1399 M_INTMOVE(REG_RESULT, d);
1400 emit_store_dst(jd, iptr, d);
1403 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1405 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1408 emit_store_dst(jd, iptr, d);
1411 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1413 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1414 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1416 emit_store_dst(jd, iptr, d);
1419 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1420 /* == => 0, < => 1, > => -1 */
1422 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1423 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1426 M_MOV_IMM(1, REG_ITMP1);
1427 M_MOV_IMM(-1, REG_ITMP2);
1428 emit_ucomiss_reg_reg(cd, s1, s2);
1429 M_CMOVULT(REG_ITMP1, d);
1430 M_CMOVUGT(REG_ITMP2, d);
1431 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1432 emit_store_dst(jd, iptr, d);
1435 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1436 /* == => 0, < => 1, > => -1 */
1438 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1440 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1442 M_MOV_IMM(1, REG_ITMP1);
1443 M_MOV_IMM(-1, REG_ITMP2);
1444 emit_ucomiss_reg_reg(cd, s1, s2);
1445 M_CMOVULT(REG_ITMP1, d);
1446 M_CMOVUGT(REG_ITMP2, d);
1447 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1452 /* == => 0, < => 1, > => -1 */
1454 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1455 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1458 M_MOV_IMM(1, REG_ITMP1);
1459 M_MOV_IMM(-1, REG_ITMP2);
1460 emit_ucomisd_reg_reg(cd, s1, s2);
1461 M_CMOVULT(REG_ITMP1, d);
1462 M_CMOVUGT(REG_ITMP2, d);
1463 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1464 emit_store_dst(jd, iptr, d);
1467 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1468 /* == => 0, < => 1, > => -1 */
1470 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1472 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1474 M_MOV_IMM(1, REG_ITMP1);
1475 M_MOV_IMM(-1, REG_ITMP2);
1476 emit_ucomisd_reg_reg(cd, s1, s2);
1477 M_CMOVULT(REG_ITMP1, d);
1478 M_CMOVUGT(REG_ITMP2, d);
1479 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1480 emit_store_dst(jd, iptr, d);
1484 /* memory operations **************************************************/
1486 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1490 /* implicit null-pointer check */
1491 M_ILD(d, s1, OFFSET(java_array_t, size));
1492 emit_store_dst(jd, iptr, d);
1495 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1498 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1499 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1500 /* implicit null-pointer check */
1501 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1502 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1503 emit_store_dst(jd, iptr, d);
1506 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1509 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1511 /* implicit null-pointer check */
1512 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1513 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_SALOAD: /* ..., 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 /* implicit null-pointer check */
1523 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1524 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1525 emit_store_dst(jd, iptr, d);
1528 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1533 /* implicit null-pointer check */
1534 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1535 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1536 emit_store_dst(jd, iptr, d);
1539 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1544 /* implicit null-pointer check */
1545 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1546 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1547 emit_store_dst(jd, iptr, d);
1550 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1554 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1555 /* implicit null-pointer check */
1556 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1557 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1558 emit_store_dst(jd, iptr, d);
1561 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1565 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1566 /* implicit null-pointer check */
1567 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1568 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1569 emit_store_dst(jd, iptr, d);
1572 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1575 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1577 /* implicit null-pointer check */
1578 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1579 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1580 emit_store_dst(jd, iptr, d);
1584 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1587 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1588 /* implicit null-pointer check */
1589 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1590 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1591 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1594 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1598 /* implicit null-pointer check */
1599 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1600 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1601 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1604 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1607 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1608 /* implicit null-pointer check */
1609 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1610 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1611 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1614 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1617 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1618 /* implicit null-pointer check */
1619 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1620 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1621 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1624 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1627 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1628 /* implicit null-pointer check */
1629 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1630 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1631 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1634 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1637 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1638 /* implicit null-pointer check */
1639 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1640 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1641 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1644 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1647 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1648 /* implicit null-pointer check */
1649 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1650 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1651 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1654 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1657 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1658 /* implicit null-pointer check */
1659 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1660 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1664 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1666 emit_arraystore_check(cd, iptr);
1668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1670 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1671 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1675 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1679 /* implicit null-pointer check */
1680 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1681 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1684 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1688 /* implicit null-pointer check */
1689 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1690 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1693 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 /* implicit null-pointer check */
1698 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1699 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1702 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1706 /* implicit null-pointer check */
1707 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1708 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1711 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1713 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1714 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1715 /* implicit null-pointer check */
1716 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1718 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1719 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1722 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1723 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1727 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1731 /* implicit null-pointer check */
1732 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1733 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1737 case ICMD_GETSTATIC: /* ... ==> ..., value */
1739 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1740 uf = iptr->sx.s23.s3.uf;
1741 fieldtype = uf->fieldref->parseddesc.fd->type;
1742 disp = dseg_add_unique_address(cd, uf);
1744 /* PROFILE_CYCLE_STOP; */
1746 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1748 /* PROFILE_CYCLE_START; */
1751 fi = iptr->sx.s23.s3.fmiref->p.field;
1752 fieldtype = fi->type;
1753 disp = dseg_add_address(cd, fi->value);
1755 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1758 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1761 PROFILE_CYCLE_START;
1765 /* This approach is much faster than moving the field
1766 address inline into a register. */
1768 M_ALD(REG_ITMP1, RIP, disp);
1770 switch (fieldtype) {
1772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1773 M_ILD(d, REG_ITMP1, 0);
1777 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1778 M_LLD(d, REG_ITMP1, 0);
1781 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1782 M_FLD(d, REG_ITMP1, 0);
1785 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1786 M_DLD(d, REG_ITMP1, 0);
1789 emit_store_dst(jd, iptr, d);
1792 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1794 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1795 uf = iptr->sx.s23.s3.uf;
1796 fieldtype = uf->fieldref->parseddesc.fd->type;
1797 disp = dseg_add_unique_address(cd, uf);
1799 /* PROFILE_CYCLE_STOP; */
1801 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1803 /* PROFILE_CYCLE_START; */
1806 fi = iptr->sx.s23.s3.fmiref->p.field;
1807 fieldtype = fi->type;
1808 disp = dseg_add_address(cd, fi->value);
1810 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1813 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1816 PROFILE_CYCLE_START;
1820 /* This approach is much faster than moving the field
1821 address inline into a register. */
1823 M_ALD(REG_ITMP1, RIP, disp);
1825 switch (fieldtype) {
1827 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1828 M_IST(s1, REG_ITMP1, 0);
1832 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1833 M_LST(s1, REG_ITMP1, 0);
1836 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1837 M_FST(s1, REG_ITMP1, 0);
1840 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1841 M_DST(s1, REG_ITMP1, 0);
1846 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1847 /* val = value (in current instruction) */
1848 /* following NOP) */
1850 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1851 uf = iptr->sx.s23.s3.uf;
1852 fieldtype = uf->fieldref->parseddesc.fd->type;
1853 disp = dseg_add_unique_address(cd, uf);
1855 /* PROFILE_CYCLE_STOP; */
1857 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1859 /* PROFILE_CYCLE_START; */
1862 fi = iptr->sx.s23.s3.fmiref->p.field;
1863 fieldtype = fi->type;
1864 disp = dseg_add_address(cd, fi->value);
1866 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1869 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1872 PROFILE_CYCLE_START;
1876 /* This approach is much faster than moving the field
1877 address inline into a register. */
1879 M_ALD(REG_ITMP1, RIP, disp);
1881 switch (fieldtype) {
1884 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1889 if (IS_IMM32(iptr->sx.s23.s2.constval))
1890 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1892 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1893 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
1899 case ICMD_GETFIELD: /* ... ==> ..., value */
1901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1903 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1904 uf = iptr->sx.s23.s3.uf;
1905 fieldtype = uf->fieldref->parseddesc.fd->type;
1908 /* PROFILE_CYCLE_STOP; */
1910 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1912 /* PROFILE_CYCLE_START; */
1915 fi = iptr->sx.s23.s3.fmiref->p.field;
1916 fieldtype = fi->type;
1920 /* implicit null-pointer check */
1921 switch (fieldtype) {
1923 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1924 M_ILD32(d, s1, disp);
1928 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1929 M_LLD32(d, s1, disp);
1932 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1933 M_FLD32(d, s1, disp);
1936 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1937 M_DLD32(d, s1, disp);
1940 emit_store_dst(jd, iptr, d);
1943 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1945 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1946 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1948 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1949 uf = iptr->sx.s23.s3.uf;
1950 fieldtype = uf->fieldref->parseddesc.fd->type;
1953 /* PROFILE_CYCLE_STOP; */
1955 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1957 /* PROFILE_CYCLE_START; */
1960 fi = iptr->sx.s23.s3.fmiref->p.field;
1961 fieldtype = fi->type;
1965 /* implicit null-pointer check */
1966 switch (fieldtype) {
1968 M_IST32(s2, s1, disp);
1972 M_LST32(s2, s1, disp);
1975 M_FST32(s2, s1, disp);
1978 M_DST32(s2, s1, disp);
1983 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1984 /* val = value (in current instruction) */
1985 /* following NOP) */
1987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1989 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1990 uf = iptr->sx.s23.s3.uf;
1991 fieldtype = uf->fieldref->parseddesc.fd->type;
1994 /* PROFILE_CYCLE_STOP; */
1996 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1998 /* PROFILE_CYCLE_START; */
2001 fi = iptr->sx.s23.s3.fmiref->p.field;
2002 fieldtype = fi->type;
2006 /* implicit null-pointer check */
2007 switch (fieldtype) {
2010 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2015 /* XXX why no check for IS_IMM32? */
2016 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2017 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2023 /* branch operations **************************************************/
2025 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2028 M_INTMOVE(s1, REG_ITMP1_XPTR);
2032 #ifdef ENABLE_VERIFIER
2033 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2034 uc = iptr->sx.s23.s2.uc;
2036 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2038 #endif /* ENABLE_VERIFIER */
2040 M_CALL_IMM(0); /* passing exception pc */
2041 M_POP(REG_ITMP2_XPC);
2043 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2047 case ICMD_GOTO: /* ... ==> ... */
2050 emit_br(cd, iptr->dst.block);
2054 case ICMD_JSR: /* ... ==> ... */
2056 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2060 case ICMD_IFNULL: /* ..., value ==> ... */
2061 case ICMD_IFNONNULL:
2063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2065 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2068 case ICMD_IFEQ: /* ..., value ==> ... */
2075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2076 M_ICMP_IMM(iptr->sx.val.i, s1);
2077 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2080 case ICMD_IF_LEQ: /* ..., value ==> ... */
2087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2088 if (IS_IMM32(iptr->sx.val.l))
2089 M_LCMP_IMM(iptr->sx.val.l, s1);
2091 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2092 M_LCMP(REG_ITMP2, s1);
2094 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
2097 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2098 case ICMD_IF_ICMPNE:
2099 case ICMD_IF_ICMPLT:
2100 case ICMD_IF_ICMPGE:
2101 case ICMD_IF_ICMPGT:
2102 case ICMD_IF_ICMPLE:
2104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2105 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2107 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2110 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2111 case ICMD_IF_ACMPNE:
2113 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2114 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2116 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2119 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2120 case ICMD_IF_LCMPNE:
2121 case ICMD_IF_LCMPLT:
2122 case ICMD_IF_LCMPGE:
2123 case ICMD_IF_LCMPGT:
2124 case ICMD_IF_LCMPLE:
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2129 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
2132 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2135 REPLACEMENT_POINT_RETURN(cd, iptr);
2136 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2137 M_INTMOVE(s1, REG_RESULT);
2138 goto nowperformreturn;
2140 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2142 REPLACEMENT_POINT_RETURN(cd, iptr);
2143 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2144 M_INTMOVE(s1, REG_RESULT);
2146 #ifdef ENABLE_VERIFIER
2147 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2148 uc = iptr->sx.s23.s2.uc;
2152 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2154 PROFILE_CYCLE_START;
2156 #endif /* ENABLE_VERIFIER */
2157 goto nowperformreturn;
2159 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2162 REPLACEMENT_POINT_RETURN(cd, iptr);
2163 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2164 M_FLTMOVE(s1, REG_FRESULT);
2165 goto nowperformreturn;
2167 case ICMD_RETURN: /* ... ==> ... */
2169 REPLACEMENT_POINT_RETURN(cd, iptr);
2175 p = cd->stackframesize;
2177 #if !defined(NDEBUG)
2178 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2179 emit_verbosecall_exit(jd);
2180 #endif /* !defined(NDEBUG) */
2182 #if defined(ENABLE_THREADS)
2183 if (checksync && code_is_synchronized(code)) {
2184 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2186 /* we need to save the proper return value */
2187 switch (iptr->opc) {
2191 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2195 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2199 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2202 /* and now restore the proper return value */
2203 switch (iptr->opc) {
2207 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2211 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2217 /* restore saved registers */
2219 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2220 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2222 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2223 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2226 /* deallocate stack */
2228 if (cd->stackframesize)
2229 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2231 /* generate method profiling code */
2240 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2243 branch_target_t *table;
2245 table = iptr->dst.table;
2247 l = iptr->sx.s23.s2.tablelow;
2248 i = iptr->sx.s23.s3.tablehigh;
2250 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2251 M_INTMOVE(s1, REG_ITMP1);
2254 M_ISUB_IMM(l, REG_ITMP1);
2256 /* number of targets */
2261 M_ICMP_IMM(i - 1, REG_ITMP1);
2262 emit_bugt(cd, table[0].block);
2264 /* build jump table top down and use address of lowest entry */
2269 dseg_add_target(cd, table->block);
2273 /* length of dataseg after last dseg_add_target is used
2276 M_MOV_IMM(0, REG_ITMP2);
2278 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2284 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2287 lookup_target_t *lookup;
2289 lookup = iptr->dst.lookup;
2291 i = iptr->sx.s23.s2.lookupcount;
2293 MCODECHECK(8 + ((7 + 6) * i) + 5);
2294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2297 M_ICMP_IMM(lookup->value, s1);
2298 emit_beq(cd, lookup->target.block);
2302 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2308 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2310 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2312 bte = iptr->sx.s23.s3.bte;
2316 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2318 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2319 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2320 case ICMD_INVOKEINTERFACE:
2322 REPLACEMENT_POINT_INVOKE(cd, iptr);
2324 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2326 um = iptr->sx.s23.s3.um;
2327 md = um->methodref->parseddesc.md;
2330 lm = iptr->sx.s23.s3.fmiref->p.method;
2332 md = lm->parseddesc;
2336 s3 = md->paramcount;
2338 MCODECHECK((20 * s3) + 128);
2340 /* copy arguments to registers or stack location */
2342 for (s3 = s3 - 1; s3 >= 0; s3--) {
2343 var = VAR(iptr->sx.s23.s2.args[s3]);
2344 d = md->params[s3].regoff;
2346 /* already preallocated (ARGVAR)? */
2348 if (var->flags & PREALLOC)
2351 if (IS_INT_LNG_TYPE(var->type)) {
2352 if (!md->params[s3].inmemory) {
2353 s1 = emit_load(jd, iptr, var, d);
2357 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2358 M_LST(s1, REG_SP, d);
2362 if (!md->params[s3].inmemory) {
2363 s1 = emit_load(jd, iptr, var, d);
2367 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2369 if (IS_2_WORD_TYPE(var->type))
2370 M_DST(s1, REG_SP, d);
2372 M_FST(s1, REG_SP, d);
2377 /* generate method profiling code */
2381 switch (iptr->opc) {
2383 if (bte->stub == NULL) {
2384 M_MOV_IMM(bte->fp, REG_ITMP1);
2387 M_MOV_IMM(bte->stub, REG_ITMP1);
2392 case ICMD_INVOKESPECIAL:
2393 emit_nullpointer_check(cd, iptr, REG_A0);
2396 case ICMD_INVOKESTATIC:
2398 disp = dseg_add_unique_address(cd, um);
2400 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2404 disp = dseg_add_functionptr(cd, lm->stubroutine);
2407 M_ALD(REG_ITMP2, RIP, disp);
2411 case ICMD_INVOKEVIRTUAL:
2413 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2418 s1 = OFFSET(vftbl_t, table[0]) +
2419 sizeof(methodptr) * lm->vftblindex;
2422 /* implicit null-pointer check */
2423 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2424 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2428 case ICMD_INVOKEINTERFACE:
2430 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2436 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2437 sizeof(methodptr) * lm->clazz->index;
2439 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2442 /* implicit null-pointer check */
2443 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2444 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2445 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2450 /* generate method profiling code */
2452 PROFILE_CYCLE_START;
2454 /* store size of call code in replacement point */
2456 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2457 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2459 /* store return value */
2461 switch (md->returntype.type) {
2465 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2466 M_INTMOVE(REG_RESULT, s1);
2467 emit_store_dst(jd, iptr, s1);
2471 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2472 M_FLTMOVE(REG_FRESULT, s1);
2473 emit_store_dst(jd, iptr, s1);
2482 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2484 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2485 /* object type cast-check */
2490 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2495 super = iptr->sx.s23.s3.c.cls;
2496 superindex = super->index;
2499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2501 /* if class is not resolved, check which code to call */
2503 if (super == NULL) {
2505 emit_label_beq(cd, BRANCH_LABEL_1);
2507 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2508 iptr->sx.s23.s3.c.ref, 0);
2510 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
2511 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2512 emit_label_beq(cd, BRANCH_LABEL_2);
2515 /* interface checkcast code */
2517 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2518 if (super != NULL) {
2520 emit_label_beq(cd, BRANCH_LABEL_3);
2523 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2525 if (super == NULL) {
2526 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2527 iptr->sx.s23.s3.c.ref,
2532 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2533 M_ICMP_IMM32(superindex, REG_ITMP3);
2534 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2536 M_ALD32(REG_ITMP3, REG_ITMP2,
2537 OFFSET(vftbl_t, interfacetable[0]) -
2538 superindex * sizeof(methodptr*));
2540 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2543 emit_label_br(cd, BRANCH_LABEL_4);
2545 emit_label(cd, BRANCH_LABEL_3);
2548 /* class checkcast code */
2550 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2551 if (super == NULL) {
2552 emit_label(cd, BRANCH_LABEL_2);
2554 cr = iptr->sx.s23.s3.c.ref;
2555 disp = dseg_add_unique_address(cd, cr);
2557 patcher_add_patch_ref(jd,
2558 PATCHER_resolve_classref_to_vftbl,
2563 emit_label_beq(cd, BRANCH_LABEL_5);
2565 disp = dseg_add_address(cd, super->vftbl);
2568 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2569 M_ALD(REG_ITMP3, RIP, disp);
2571 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2572 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2574 *(cd->mcodeptr++) = 0x4d;
2575 *(cd->mcodeptr++) = 0x3b;
2576 *(cd->mcodeptr++) = 0x1c;
2577 *(cd->mcodeptr++) = 0x02;
2578 /* cmp (ITMP2, ITMP1, 1), ITMP3 */
2580 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
2582 if (super == NULL) {
2583 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2584 emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
2587 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2588 *(cd->mcodeptr++) = 0x41;
2589 *(cd->mcodeptr++) = 0x39;
2590 *(cd->mcodeptr++) = 0x42;
2591 *(cd->mcodeptr++) = OFFSET(vftbl_t, subtype_depth);
2592 /* cmpl ITMP1, subtype_depth(ITMP2) */
2593 emit_label_blt(cd, BRANCH_LABEL_9); /* throw */
2595 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2597 *(cd->mcodeptr++) = 0x4d;
2598 *(cd->mcodeptr++) = 0x3b;
2599 *(cd->mcodeptr++) = 0x5c;
2600 *(cd->mcodeptr++) = 0xc2;
2601 *(cd->mcodeptr++) = -8*DISPLAY_SIZE;
2602 /* cmp -8*DISPL(ITMP2, ITMP1, 8), ITMP3 */
2604 emit_label_beq(cd, BRANCH_LABEL_7); /* good */
2606 emit_label(cd, BRANCH_LABEL_9);
2608 emit_label(cd, BRANCH_LABEL_10);
2610 /* reload s1, might have been destroyed */
2611 emit_load_s1(jd, iptr, REG_ITMP1);
2612 M_ALD_MEM(s1, TRAP_ClassCastException);
2614 emit_label(cd, BRANCH_LABEL_7);
2615 emit_label(cd, BRANCH_LABEL_6);
2616 /* reload s1, might have been destroyed */
2617 emit_load_s1(jd, iptr, REG_ITMP1);
2620 assert(super->vftbl->subtype_offset < 0x80);
2621 *(cd->mcodeptr++) = 0x4d;
2622 *(cd->mcodeptr++) = 0x3b;
2623 *(cd->mcodeptr++) = 0x5a;
2624 *(cd->mcodeptr++) = super->vftbl->subtype_offset;
2625 /* cmp off(ITMP2), ITMP3 */
2627 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2631 emit_label(cd, BRANCH_LABEL_5);
2634 if (super == NULL) {
2635 emit_label(cd, BRANCH_LABEL_1);
2636 emit_label(cd, BRANCH_LABEL_4);
2639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2642 /* array type cast-check */
2644 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2645 M_INTMOVE(s1, REG_A0);
2647 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2648 cr = iptr->sx.s23.s3.c.ref;
2649 disp = dseg_add_unique_address(cd, cr);
2651 patcher_add_patch_ref(jd,
2652 PATCHER_resolve_classref_to_classinfo,
2656 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2659 M_ALD(REG_A1, RIP, disp);
2660 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2663 /* s1 may have been destroyed over the function call */
2664 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2666 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2672 emit_store_dst(jd, iptr, d);
2675 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2681 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2686 super = iptr->sx.s23.s3.c.cls;
2687 superindex = super->index;
2690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2694 M_INTMOVE(s1, REG_ITMP1);
2700 /* if class is not resolved, check which code to call */
2702 if (super == NULL) {
2704 emit_label_beq(cd, BRANCH_LABEL_1);
2706 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2707 iptr->sx.s23.s3.c.ref, 0);
2709 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2710 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2711 emit_label_beq(cd, BRANCH_LABEL_2);
2714 /* interface instanceof code */
2716 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2717 if (super != NULL) {
2719 emit_label_beq(cd, BRANCH_LABEL_3);
2722 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2724 if (super == NULL) {
2725 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2726 iptr->sx.s23.s3.c.ref, 0);
2730 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2731 M_ICMP_IMM32(superindex, REG_ITMP3);
2733 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2736 M_ALD32(REG_ITMP1, REG_ITMP1,
2737 OFFSET(vftbl_t, interfacetable[0]) -
2738 superindex * sizeof(methodptr*));
2743 emit_label_br(cd, BRANCH_LABEL_4);
2745 emit_label(cd, BRANCH_LABEL_3);
2748 /* class instanceof code */
2750 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2751 if (super == NULL) {
2752 emit_label(cd, BRANCH_LABEL_2);
2754 cr = iptr->sx.s23.s3.c.ref;
2755 disp = dseg_add_unique_address(cd, cr);
2757 patcher_add_patch_ref(jd,
2758 PATCHER_resolve_classref_to_vftbl,
2763 emit_label_beq(cd, BRANCH_LABEL_5);
2765 disp = dseg_add_address(cd, super->vftbl);
2768 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2769 M_ALD(REG_ITMP3, RIP, disp);
2771 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2772 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2774 *(cd->mcodeptr++) = 0x4d;
2775 *(cd->mcodeptr++) = 0x3b;
2776 *(cd->mcodeptr++) = 0x1c;
2777 *(cd->mcodeptr++) = 0x02;
2778 /* cmp (ITMP2, ITMP1, 1), ITMP3 */
2780 emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2781 if (d == REG_ITMP2) {
2786 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2787 emit_label(cd, BRANCH_LABEL_8);
2789 if (super == NULL) {
2790 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2791 emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2794 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2795 *(cd->mcodeptr++) = 0x41;
2796 *(cd->mcodeptr++) = 0x39;
2797 *(cd->mcodeptr++) = 0x42;
2798 *(cd->mcodeptr++) = OFFSET(vftbl_t, subtype_depth);
2799 /* cmpl ITMP1, subtype_depth(ITMP2) */
2800 emit_label_blt(cd, BRANCH_LABEL_9); /* false */
2802 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2804 *(cd->mcodeptr++) = 0x4d;
2805 *(cd->mcodeptr++) = 0x3b;
2806 *(cd->mcodeptr++) = 0x5c;
2807 *(cd->mcodeptr++) = 0xc2;
2808 *(cd->mcodeptr++) = -8*DISPLAY_SIZE;
2809 /* cmp -8*DISPL(ITMP2, ITMP1, 8), ITMP3 */
2812 if (d == REG_ITMP2) {
2815 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2818 emit_label(cd, BRANCH_LABEL_9);
2820 emit_label(cd, BRANCH_LABEL_10);
2821 if (d == REG_ITMP2) {
2824 emit_label(cd, BRANCH_LABEL_7);
2826 emit_label(cd, BRANCH_LABEL_6);
2829 assert(super->vftbl->subtype_offset < 0x80);
2830 *(cd->mcodeptr++) = 0x4d;
2831 *(cd->mcodeptr++) = 0x3b;
2832 *(cd->mcodeptr++) = 0x5a;
2833 *(cd->mcodeptr++) = super->vftbl->subtype_offset;
2834 /* cmp off(ITMP2), ITMP3 */
2842 emit_label(cd, BRANCH_LABEL_5);
2845 if (super == NULL) {
2846 emit_label(cd, BRANCH_LABEL_1);
2847 emit_label(cd, BRANCH_LABEL_4);
2850 emit_store_dst(jd, iptr, d);
2854 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2856 /* check for negative sizes and copy sizes to stack if necessary */
2858 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2860 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2862 /* copy SAVEDVAR sizes to stack */
2863 var = VAR(iptr->sx.s23.s2.args[s1]);
2865 /* Already Preallocated? */
2866 if (!(var->flags & PREALLOC)) {
2867 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2868 M_LST(s2, REG_SP, s1 * 8);
2872 /* a0 = dimension count */
2874 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2876 /* is a patcher function set? */
2878 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2879 cr = iptr->sx.s23.s3.c.ref;
2880 disp = dseg_add_unique_address(cd, cr);
2882 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2886 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2889 /* a1 = classinfo */
2891 M_ALD(REG_A1, RIP, disp);
2893 /* a2 = pointer to dimensions = stack pointer */
2895 M_MOV(REG_SP, REG_A2);
2897 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2900 /* check for exception before result assignment */
2902 emit_exception_check(cd, iptr);
2904 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2905 M_INTMOVE(REG_RESULT, s1);
2906 emit_store_dst(jd, iptr, s1);
2910 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2915 } /* for instruction */
2917 MCODECHECK(512); /* XXX require a lower number? */
2919 /* At the end of a basic block we may have to append some nops,
2920 because the patcher stub calling code might be longer than the
2921 actual instruction. So codepatching does not change the
2922 following block unintentionally. */
2924 if (cd->mcodeptr < cd->lastmcodeptr) {
2925 while (cd->mcodeptr < cd->lastmcodeptr) {
2930 } /* if (bptr -> flags >= BBREACHED) */
2931 } /* for basic block */
2933 /* Generate patcher traps. */
2935 emit_patcher_traps(jd);
2937 /* everything's ok */
2943 /* codegen_emit_stub_native ****************************************************
2945 Emits a stub routine which calls a native method.
2947 *******************************************************************************/
2949 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2963 /* Get required compiler data. */
2969 /* initialize variables */
2973 /* calculate stack frame size */
2975 cd->stackframesize =
2976 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2977 sizeof(localref_table) / SIZEOF_VOID_P +
2979 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2982 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2984 /* create method header */
2986 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2987 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2988 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2989 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2990 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2992 #if defined(ENABLE_PROFILING)
2993 /* generate native method profiling code */
2995 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2996 /* count frequency */
2998 M_MOV_IMM(code, REG_ITMP3);
2999 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3003 /* generate stub code */
3005 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3007 #if defined(ENABLE_GC_CACAO)
3008 /* Save callee saved integer registers in stackframeinfo (GC may
3009 need to recover them during a collection). */
3011 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3012 OFFSET(stackframeinfo_t, intregs);
3014 for (i = 0; i < INT_SAV_CNT; i++)
3015 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3018 /* save integer and float argument registers */
3020 for (i = 0; i < md->paramcount; i++) {
3021 if (!md->params[i].inmemory) {
3022 s1 = md->params[i].regoff;
3024 switch (md->paramtypes[i].type) {
3028 M_LST(s1, REG_SP, i * 8);
3032 M_DST(s1, REG_SP, i * 8);
3038 /* create dynamic stack info */
3040 M_MOV(REG_SP, REG_A0);
3041 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3042 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3045 /* remember class argument */
3047 if (m->flags & ACC_STATIC)
3048 M_MOV(REG_RESULT, REG_ITMP2);
3050 /* restore integer and float argument registers */
3052 for (i = 0; i < md->paramcount; i++) {
3053 if (!md->params[i].inmemory) {
3054 s1 = md->params[i].regoff;
3056 switch (md->paramtypes[i].type) {
3060 M_LLD(s1, REG_SP, i * 8);
3064 M_DLD(s1, REG_SP, i * 8);
3070 /* Copy or spill arguments to new locations. */
3072 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3073 s2 = nmd->params[j].regoff;
3075 switch (md->paramtypes[i].type) {
3079 if (!md->params[i].inmemory) {
3080 s1 = md->params[i].regoff;
3082 if (!nmd->params[j].inmemory)
3085 M_LST(s1, REG_SP, s2);
3088 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3089 M_LLD(REG_ITMP1, REG_SP, s1);
3090 M_LST(REG_ITMP1, REG_SP, s2);
3094 /* We only copy spilled float arguments, as the float
3095 argument registers keep unchanged. */
3097 if (md->params[i].inmemory) {
3098 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3100 M_FLD(REG_FTMP1, REG_SP, s1);
3101 M_FST(REG_FTMP1, REG_SP, s2);
3105 if (md->params[i].inmemory) {
3106 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
3107 M_DLD(REG_FTMP1, REG_SP, s1);
3108 M_DST(REG_FTMP1, REG_SP, s2);
3114 /* Handle native Java methods. */
3116 if (m->flags & ACC_NATIVE) {
3117 /* put class into second argument register */
3119 if (m->flags & ACC_STATIC)
3120 M_MOV(REG_ITMP2, REG_A1);
3122 /* put env into first argument register */
3124 M_MOV_IMM(_Jv_env, REG_A0);
3127 /* Call the native function. */
3129 disp = dseg_add_functionptr(cd, f);
3130 M_ALD(REG_ITMP1, RIP, disp);
3133 /* save return value */
3135 switch (md->returntype.type) {
3139 switch (md->returntype.decltype) {
3140 case PRIMITIVETYPE_BOOLEAN:
3141 M_BZEXT(REG_RESULT, REG_RESULT);
3143 case PRIMITIVETYPE_BYTE:
3144 M_BSEXT(REG_RESULT, REG_RESULT);
3146 case PRIMITIVETYPE_CHAR:
3147 M_CZEXT(REG_RESULT, REG_RESULT);
3149 case PRIMITIVETYPE_SHORT:
3150 M_SSEXT(REG_RESULT, REG_RESULT);
3153 M_LST(REG_RESULT, REG_SP, 0 * 8);
3157 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3163 /* remove native stackframe info */
3165 M_MOV(REG_SP, REG_A0);
3166 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3167 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3169 M_MOV(REG_RESULT, REG_ITMP3);
3171 /* restore return value */
3173 switch (md->returntype.type) {
3177 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3181 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3187 #if defined(ENABLE_GC_CACAO)
3188 /* Restore callee saved integer registers from stackframeinfo (GC
3189 might have modified them during a collection). */
3191 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3192 OFFSET(stackframeinfo_t, intregs);
3194 for (i = 0; i < INT_SAV_CNT; i++)
3195 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3198 /* remove stackframe */
3200 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3202 /* test for exception */
3208 /* handle exception */
3210 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3211 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3212 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3214 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3220 * These are local overrides for various environment variables in Emacs.
3221 * Please do not remove this and leave it at the end of the file, where
3222 * Emacs will automagically detect them.
3223 * ---------------------------------------------------------------------
3226 * indent-tabs-mode: t
3230 * vim:noexpandtab:sw=4:ts=4: