1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
30 Changes: Christian Ullrich
33 $Id: codegen.c 5830 2006-10-26 11:04:31Z twisti $
47 #include "vm/jit/x86_64/arch.h"
48 #include "vm/jit/x86_64/codegen.h"
49 #include "vm/jit/x86_64/emit.h"
51 #include "mm/memory.h"
52 #include "native/jni.h"
53 #include "native/native.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/lock.h"
59 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/stringlocal.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit-common.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/methodheader.h"
73 #include "vm/jit/parse.h"
74 #include "vm/jit/patcher.h"
75 #include "vm/jit/reg.h"
76 #include "vm/jit/replace.h"
78 #if defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
83 /* codegen *********************************************************************
85 Generates machine code.
87 *******************************************************************************/
89 bool codegen(jitdata *jd)
95 s4 len, s1, s2, s3, d, disp;
99 varinfo *var, *var1, *var2, *dst;
103 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
104 unresolved_method *um;
105 builtintable_entry *bte;
107 rplpoint *replacementpoint;
110 /* get required compiler data */
117 /* prevent compiler warnings */
130 /* space to save used callee saved registers */
132 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
133 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
135 cd->stackframesize = rd->memuse + savedregs_num;
137 #if defined(ENABLE_THREADS)
138 /* space to save argument of monitor_enter */
140 if (checksync && (m->flags & ACC_SYNCHRONIZED))
141 cd->stackframesize++;
144 /* Keep stack of non-leaf functions 16-byte aligned for calls into
145 native code e.g. libc or jni (alignment problems with
148 if (!jd->isleafmethod || opt_verbosecall)
149 cd->stackframesize |= 0x1;
151 /* create method header */
153 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
154 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
156 #if defined(ENABLE_THREADS)
157 /* IsSync contains the offset relative to the stack pointer for the
158 argument of monitor_exit used in the exception handler. Since the
159 offset could be zero and give a wrong meaning of the flag it is
163 if (checksync && (m->flags & ACC_SYNCHRONIZED))
164 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
167 (void) dseg_adds4(cd, 0); /* IsSync */
169 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
170 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
171 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
173 (void) dseg_addlinenumbertablesize(cd);
175 (void) dseg_adds4(cd, jd->exceptiontablelength); /* ExTableSize */
177 /* create exception table */
179 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
180 dseg_addtarget(cd, ex->start);
181 dseg_addtarget(cd, ex->end);
182 dseg_addtarget(cd, ex->handler);
183 (void) dseg_addaddress(cd, ex->catchtype.any);
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));
197 /* create stack frame (if necessary) */
199 if (cd->stackframesize)
200 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
202 /* save used callee saved registers */
204 p = cd->stackframesize;
205 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
206 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
208 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
209 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
212 /* take arguments out of register or stack frame */
216 for (p = 0, l = 0; p < md->paramcount; p++) {
217 t = md->paramtypes[p].type;
219 varindex = jd->local_map[l * 5 + t];
222 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
225 if (varindex == UNUSED)
230 s1 = md->params[p].regoff;
232 if (IS_INT_LNG_TYPE(t)) { /* integer args */
233 s2 = rd->argintregs[s1];
234 if (!md->params[p].inmemory) { /* register arguments */
235 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
236 M_INTMOVE(s2, var->vv.regoff);
238 } else { /* reg arg -> spilled */
239 M_LST(s2, REG_SP, var->vv.regoff * 8);
242 } else { /* stack arguments */
243 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
244 /* + 8 for return address */
245 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
247 } else { /* stack arg -> spilled */
248 var->vv.regoff = cd->stackframesize + s1 + 1;
252 } else { /* floating args */
253 if (!md->params[p].inmemory) { /* register arguments */
254 s2 = rd->argfltregs[s1];
255 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
256 M_FLTMOVE(s2, var->vv.regoff);
258 } else { /* reg arg -> spilled */
259 M_DST(s2, REG_SP, var->vv.regoff * 8);
262 } else { /* stack arguments */
263 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
264 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
267 var->vv.regoff = cd->stackframesize + s1 + 1;
273 /* save monitorenter argument */
275 #if defined(ENABLE_THREADS)
276 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
277 /* stack offset for monitor argument */
281 if (opt_verbosecall) {
282 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
284 for (p = 0; p < INT_ARG_CNT; p++)
285 M_LST(rd->argintregs[p], REG_SP, p * 8);
287 for (p = 0; p < FLT_ARG_CNT; p++)
288 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
290 s1 += INT_ARG_CNT + FLT_ARG_CNT;
293 /* decide which monitor enter function to call */
295 if (m->flags & ACC_STATIC) {
296 M_MOV_IMM(&m->class->object.header, REG_A0);
301 codegen_add_nullpointerexception_ref(cd);
304 M_AST(REG_A0, REG_SP, s1 * 8);
305 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
308 if (opt_verbosecall) {
309 for (p = 0; p < INT_ARG_CNT; p++)
310 M_LLD(rd->argintregs[p], REG_SP, p * 8);
312 for (p = 0; p < FLT_ARG_CNT; p++)
313 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
315 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
321 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
322 emit_verbosecall_enter(jd);
323 #endif /* !defined(NDEBUG) */
327 /* end of header generation */
329 replacementpoint = jd->code->rplpoints;
331 /* walk through all basic blocks */
333 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
335 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
337 if (bptr->flags >= BBREACHED) {
339 /* branch resolving */
342 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
343 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
348 /* handle replacement points */
351 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
352 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
356 assert(cd->lastmcodeptr <= cd->mcodeptr);
357 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
361 /* copy interface registers to their destination */
366 /* generate basicblock profiling code */
368 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
369 /* count frequency */
371 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
372 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
374 /* if this is an exception handler, start profiling again */
376 if (bptr->type == BBTYPE_EXH)
380 #if defined(ENABLE_LSRA)
384 src = bptr->invars[len];
385 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
386 if (bptr->type == BBTYPE_EXH) {
387 /* d = reg_of_var(rd, src, REG_ITMP1); */
388 if (!IS_INMEMORY(src->flags))
392 M_INTMOVE(REG_ITMP1, d);
393 emit_store(jd, NULL, src, d);
403 var = VAR(bptr->invars[len]);
404 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
405 if (bptr->type == BBTYPE_EXH) {
406 d = codegen_reg_of_var(0, var, REG_ITMP1);
407 M_INTMOVE(REG_ITMP1, d);
408 emit_store(jd, NULL, var, d);
412 assert((var->flags & INOUT));
415 #if defined(ENABLE_LSRA)
418 /* walk through all instructions */
423 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
424 if (iptr->line != currentline) {
425 dseg_addlinenumber(cd, iptr->line);
426 currentline = iptr->line;
429 MCODECHECK(1024); /* 1KB should be enough */
432 case ICMD_INLINE_START: /* internal ICMDs */
433 case ICMD_INLINE_END:
436 case ICMD_NOP: /* ... ==> ... */
439 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
444 codegen_add_nullpointerexception_ref(cd);
447 /* constant operations ************************************************/
449 case ICMD_ICONST: /* ... ==> ..., constant */
451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
452 ICONST(d, iptr->sx.val.i);
453 emit_store_dst(jd, iptr, d);
456 case ICMD_LCONST: /* ... ==> ..., constant */
458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
459 LCONST(d, iptr->sx.val.l);
460 emit_store_dst(jd, iptr, d);
463 case ICMD_FCONST: /* ... ==> ..., constant */
465 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
466 disp = dseg_addfloat(cd, iptr->sx.val.f);
467 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
468 emit_store_dst(jd, iptr, d);
471 case ICMD_DCONST: /* ... ==> ..., constant */
473 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
474 disp = dseg_adddouble(cd, iptr->sx.val.d);
475 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
476 emit_store_dst(jd, iptr, d);
479 case ICMD_ACONST: /* ... ==> ..., constant */
481 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
483 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
484 /* PROFILE_CYCLE_STOP; */
486 codegen_addpatchref(cd, PATCHER_aconst,
487 iptr->sx.val.c.ref, 0);
489 if (opt_showdisassemble) {
490 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
493 /* PROFILE_CYCLE_START; */
498 if (iptr->sx.val.anyptr == 0)
501 M_MOV_IMM(iptr->sx.val.anyptr, d);
503 emit_store_dst(jd, iptr, d);
507 /* load/store/copy/move operations ************************************/
509 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
510 case ICMD_ALOAD: /* s1 = local variable */
514 case ICMD_ISTORE: /* ..., value ==> ... */
515 case ICMD_ASTORE: /* dst = local variable */
522 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
526 /* pop operations *****************************************************/
528 /* attention: double and longs are only one entry in CACAO ICMDs */
530 case ICMD_POP: /* ..., value ==> ... */
531 case ICMD_POP2: /* ..., value, value ==> ... */
536 /* integer operations *************************************************/
538 case ICMD_INEG: /* ..., value ==> ..., - value */
540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
544 emit_store_dst(jd, iptr, d);
547 case ICMD_LNEG: /* ..., value ==> ..., - value */
549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
553 emit_store_dst(jd, iptr, d);
556 case ICMD_I2L: /* ..., value ==> ..., value */
558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
561 emit_store_dst(jd, iptr, d);
564 case ICMD_L2I: /* ..., value ==> ..., value */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
569 emit_store_dst(jd, iptr, d);
572 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
575 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
577 emit_store_dst(jd, iptr, d);
580 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
585 emit_store_dst(jd, iptr, d);
588 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
593 emit_store_dst(jd, iptr, d);
597 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 emit_store_dst(jd, iptr, d);
612 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
613 /* sx.val.i = constant */
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
618 /* Using inc and dec is not faster than add (tested with
622 M_IADD_IMM(iptr->sx.val.i, d);
623 emit_store_dst(jd, iptr, d);
626 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
629 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
637 emit_store_dst(jd, iptr, d);
640 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
641 /* sx.val.l = constant */
643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
646 if (IS_IMM32(iptr->sx.val.l))
647 M_LADD_IMM(iptr->sx.val.l, d);
649 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
650 M_LADD(REG_ITMP2, d);
652 emit_store_dst(jd, iptr, d);
655 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 M_INTMOVE(s1, REG_ITMP1);
662 M_ISUB(s2, REG_ITMP1);
663 M_INTMOVE(REG_ITMP1, d);
668 emit_store_dst(jd, iptr, d);
671 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
672 /* sx.val.i = constant */
674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
677 M_ISUB_IMM(iptr->sx.val.i, d);
678 emit_store_dst(jd, iptr, d);
681 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
687 M_INTMOVE(s1, REG_ITMP1);
688 M_LSUB(s2, REG_ITMP1);
689 M_INTMOVE(REG_ITMP1, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
698 /* sx.val.l = constant */
700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
703 if (IS_IMM32(iptr->sx.val.l))
704 M_LSUB_IMM(iptr->sx.val.l, d);
706 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
707 M_LSUB(REG_ITMP2, d);
709 emit_store_dst(jd, iptr, d);
712 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
715 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
716 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
723 emit_store_dst(jd, iptr, d);
726 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
727 /* sx.val.i = constant */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
731 if (iptr->sx.val.i == 2) {
735 M_IMUL_IMM(s1, iptr->sx.val.i, d);
736 emit_store_dst(jd, iptr, d);
739 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
750 emit_store_dst(jd, iptr, d);
753 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
754 /* sx.val.l = constant */
756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
757 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
758 if (IS_IMM32(iptr->sx.val.l))
759 M_LMUL_IMM(s1, iptr->sx.val.l, d);
761 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
763 M_LMUL(REG_ITMP2, d);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
770 var1 = VAROP(iptr->s1);
771 var2 = VAROP(iptr->sx.s23.s2);
772 dst = VAROP(iptr->dst);
774 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
775 if (IS_INMEMORY(var1->flags))
776 M_ILD(RAX, REG_SP, var1->vv.regoff * 8);
778 M_INTMOVE(var1->vv.regoff, RAX);
780 if (IS_INMEMORY(var2->flags))
781 M_ILD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
783 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
788 codegen_add_arithmeticexception_ref(cd);
791 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
792 emit_jcc(cd, CC_NE, 4 + 6);
793 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
794 emit_jcc(cd, CC_E, 3 + 1 + 3); /* 6 bytes */
796 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
798 emit_idivl_reg(cd, REG_ITMP3);
800 if (IS_INMEMORY(dst->flags)) {
801 emit_mov_reg_membase(cd, RAX, REG_SP, dst->vv.regoff * 8);
802 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
805 M_INTMOVE(RAX, dst->vv.regoff);
807 if (dst->vv.regoff != RDX) {
808 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
813 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
815 var1 = VAROP(iptr->s1);
816 var2 = VAROP(iptr->sx.s23.s2);
817 dst = VAROP(iptr->dst);
819 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
820 if (IS_INMEMORY(var1->flags))
821 M_ILD(RAX, REG_SP, var1->vv.regoff * 8);
823 M_INTMOVE(var1->vv.regoff, RAX);
825 if (IS_INMEMORY(var2->flags))
826 M_ILD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
828 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
833 codegen_add_arithmeticexception_ref(cd);
836 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
838 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
839 emit_jcc(cd, CC_NE, 2 + 4 + 6);
842 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
843 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
844 emit_jcc(cd, CC_E, 1 + 3); /* 6 bytes */
847 emit_idivl_reg(cd, REG_ITMP3);
849 if (IS_INMEMORY(dst->flags)) {
850 emit_mov_reg_membase(cd, RDX, REG_SP, dst->vv.regoff * 8);
851 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
854 M_INTMOVE(RDX, dst->vv.regoff);
856 if (dst->vv.regoff != RDX) {
857 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
862 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
863 /* sx.val.i = constant */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
867 M_INTMOVE(s1, REG_ITMP1);
868 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
869 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
870 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
871 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
872 emit_mov_reg_reg(cd, REG_ITMP1, d);
873 emit_store_dst(jd, iptr, d);
876 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
877 /* sx.val.i = constant */
879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
881 M_INTMOVE(s1, REG_ITMP1);
882 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
883 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
884 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
885 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
886 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
887 emit_mov_reg_reg(cd, REG_ITMP1, d);
888 emit_store_dst(jd, iptr, d);
892 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
894 var1 = VAROP(iptr->s1);
895 var2 = VAROP(iptr->sx.s23.s2);
896 dst = VAROP(iptr->dst);
898 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
900 if (IS_INMEMORY(var1->flags))
901 M_LLD(RAX, REG_SP, var1->vv.regoff * 8);
903 M_INTMOVE(var1->vv.regoff, RAX);
905 if (IS_INMEMORY(var2->flags))
906 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
908 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
913 codegen_add_arithmeticexception_ref(cd);
916 /* check as described in jvm spec */
917 disp = dseg_adds8(cd, 0x8000000000000000LL);
918 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
920 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
921 M_BEQ(3 + 2 + 3); /* 6 bytes */
923 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
925 emit_idiv_reg(cd, REG_ITMP3);
927 if (IS_INMEMORY(dst->flags)) {
928 M_LST(RAX, REG_SP, dst->vv.regoff * 8);
929 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
932 M_INTMOVE(RAX, dst->vv.regoff);
934 if (dst->vv.regoff != RDX) {
935 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
940 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
942 var1 = VAROP(iptr->s1);
943 var2 = VAROP(iptr->sx.s23.s2);
944 dst = VAROP(iptr->dst);
946 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
948 if (IS_INMEMORY(var1->flags))
949 M_LLD(REG_ITMP1, REG_SP, var1->vv.regoff * 8);
951 M_INTMOVE(var1->vv.regoff, REG_ITMP1);
953 if (IS_INMEMORY(var2->flags))
954 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
956 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
959 M_INTMOVE(s1, REG_ITMP1);
960 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
961 M_INTMOVE(s2, REG_ITMP3);
966 codegen_add_arithmeticexception_ref(cd);
969 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
971 /* check as described in jvm spec */
972 disp = dseg_adds8(cd, 0x8000000000000000LL);
973 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
977 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
979 M_LXOR(RDX, RDX); /* 3 bytes */
980 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
981 M_BEQ(2 + 3); /* 6 bytes */
984 emit_idiv_reg(cd, REG_ITMP3);
986 if (IS_INMEMORY(dst->flags)) {
987 M_LST(RDX, REG_SP, dst->vv.regoff * 8);
988 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
991 M_INTMOVE(RDX, dst->vv.regoff);
993 if (dst->vv.regoff != RDX) {
994 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
999 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1000 /* sx.val.i = constant */
1002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1004 M_INTMOVE(s1, REG_ITMP1);
1005 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1006 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
1007 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
1008 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
1009 emit_mov_reg_reg(cd, REG_ITMP1, d);
1010 emit_store_dst(jd, iptr, d);
1013 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1014 /* sx.val.l = constant */
1016 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1017 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1018 M_INTMOVE(s1, REG_ITMP1);
1019 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1020 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
1021 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
1022 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
1023 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
1024 emit_mov_reg_reg(cd, REG_ITMP1, d);
1025 emit_store_dst(jd, iptr, d);
1028 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1030 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1031 emit_ishift(jd, SHIFT_SHL, iptr);
1034 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1035 /* sx.val.i = constant */
1037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1038 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1040 M_ISLL_IMM(iptr->sx.val.i, d);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1046 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1047 emit_ishift(jd, SHIFT_SAR, iptr);
1050 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1051 /* sx.val.i = constant */
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056 M_ISRA_IMM(iptr->sx.val.i, d);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1062 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1063 emit_ishift(jd, SHIFT_SHR, iptr);
1066 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1067 /* sx.val.i = constant */
1069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1070 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 M_ISRL_IMM(iptr->sx.val.i, d);
1073 emit_store_dst(jd, iptr, d);
1076 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1078 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1079 emit_lshift(jd, SHIFT_SHL, iptr);
1082 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1083 /* sx.val.i = constant */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1088 M_LSLL_IMM(iptr->sx.val.i, d);
1089 emit_store_dst(jd, iptr, d);
1092 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1094 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1095 emit_lshift(jd, SHIFT_SAR, iptr);
1098 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1099 /* sx.val.i = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1104 M_LSRA_IMM(iptr->sx.val.i, d);
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1110 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1111 emit_lshift(jd, SHIFT_SHR, iptr);
1114 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1115 /* sx.val.l = constant */
1117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1120 M_LSRL_IMM(iptr->sx.val.i, d);
1121 emit_store_dst(jd, iptr, d);
1124 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1127 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1128 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1139 /* sx.val.i = constant */
1141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1144 M_IAND_IMM(iptr->sx.val.i, d);
1145 emit_store_dst(jd, iptr, d);
1148 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1152 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1159 emit_store_dst(jd, iptr, d);
1162 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1163 /* sx.val.l = constant */
1165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1166 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1168 if (IS_IMM32(iptr->sx.val.l))
1169 M_LAND_IMM(iptr->sx.val.l, d);
1171 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1172 M_LAND(REG_ITMP2, d);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1180 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1192 /* sx.val.i = constant */
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1195 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1197 M_IOR_IMM(iptr->sx.val.i, d);
1198 emit_store_dst(jd, iptr, d);
1201 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1203 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1204 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1205 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1216 /* sx.val.l = constant */
1218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1221 if (IS_IMM32(iptr->sx.val.l))
1222 M_LOR_IMM(iptr->sx.val.l, d);
1224 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1225 M_LOR(REG_ITMP2, d);
1227 emit_store_dst(jd, iptr, d);
1230 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1241 emit_store_dst(jd, iptr, d);
1244 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1245 /* sx.val.i = constant */
1247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1250 M_IXOR_IMM(iptr->sx.val.i, d);
1251 emit_store_dst(jd, iptr, d);
1254 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1256 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1257 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1258 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1269 /* sx.val.l = constant */
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1274 if (IS_IMM32(iptr->sx.val.l))
1275 M_LXOR_IMM(iptr->sx.val.l, d);
1277 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1278 M_LXOR(REG_ITMP2, d);
1280 emit_store_dst(jd, iptr, d);
1284 /* floating operations ************************************************/
1286 case ICMD_FNEG: /* ..., value ==> ..., - value */
1288 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1289 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1290 disp = dseg_adds4(cd, 0x80000000);
1292 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1293 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1294 emit_store_dst(jd, iptr, d);
1297 case ICMD_DNEG: /* ..., value ==> ..., - value */
1299 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1300 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1301 disp = dseg_adds8(cd, 0x8000000000000000);
1303 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1304 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1305 emit_store_dst(jd, iptr, d);
1308 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1310 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1311 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1312 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1319 emit_store_dst(jd, iptr, d);
1322 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1324 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1325 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1326 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1338 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1342 M_FLTMOVE(s2, REG_FTMP2);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1352 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1353 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1354 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1356 M_FLTMOVE(s2, REG_FTMP2);
1361 emit_store_dst(jd, iptr, d);
1364 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1366 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1367 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1368 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1375 emit_store_dst(jd, iptr, d);
1378 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1380 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1381 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1382 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1389 emit_store_dst(jd, iptr, d);
1392 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1394 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1395 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1396 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1398 M_FLTMOVE(s2, REG_FTMP2);
1403 emit_store_dst(jd, iptr, d);
1406 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1408 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1409 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1410 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1412 M_FLTMOVE(s2, REG_FTMP2);
1417 emit_store_dst(jd, iptr, d);
1420 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1422 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1423 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1433 emit_store_dst(jd, iptr, d);
1436 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1439 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1441 emit_store_dst(jd, iptr, d);
1444 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1447 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1449 emit_store_dst(jd, iptr, d);
1452 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1454 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1457 M_ICMP_IMM(0x80000000, d); /* corner cases */
1458 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1459 ((REG_RESULT == d) ? 0 : 3);
1461 M_FLTMOVE(s1, REG_FTMP1);
1462 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1464 M_INTMOVE(REG_RESULT, d);
1465 emit_store_dst(jd, iptr, d);
1468 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1470 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1473 M_ICMP_IMM(0x80000000, d); /* corner cases */
1474 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1475 ((REG_RESULT == d) ? 0 : 3);
1477 M_FLTMOVE(s1, REG_FTMP1);
1478 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1480 M_INTMOVE(REG_RESULT, d);
1481 emit_store_dst(jd, iptr, d);
1484 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1486 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1489 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1490 M_LCMP(REG_ITMP2, d); /* corner cases */
1491 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1492 ((REG_RESULT == d) ? 0 : 3);
1494 M_FLTMOVE(s1, REG_FTMP1);
1495 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1497 M_INTMOVE(REG_RESULT, d);
1498 emit_store_dst(jd, iptr, d);
1501 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1503 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1504 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1506 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1507 M_LCMP(REG_ITMP2, d); /* corner cases */
1508 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1509 ((REG_RESULT == d) ? 0 : 3);
1511 M_FLTMOVE(s1, REG_FTMP1);
1512 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1514 M_INTMOVE(REG_RESULT, d);
1515 emit_store_dst(jd, iptr, d);
1518 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1520 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1521 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1523 emit_store_dst(jd, iptr, d);
1526 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1528 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1529 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1531 emit_store_dst(jd, iptr, d);
1534 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1535 /* == => 0, < => 1, > => -1 */
1537 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1538 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1541 M_MOV_IMM(1, REG_ITMP1);
1542 M_MOV_IMM(-1, REG_ITMP2);
1543 emit_ucomiss_reg_reg(cd, s1, s2);
1544 M_CMOVB(REG_ITMP1, d);
1545 M_CMOVA(REG_ITMP2, d);
1546 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1547 emit_store_dst(jd, iptr, d);
1550 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1551 /* == => 0, < => 1, > => -1 */
1553 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1554 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1557 M_MOV_IMM(1, REG_ITMP1);
1558 M_MOV_IMM(-1, REG_ITMP2);
1559 emit_ucomiss_reg_reg(cd, s1, s2);
1560 M_CMOVB(REG_ITMP1, d);
1561 M_CMOVA(REG_ITMP2, d);
1562 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1563 emit_store_dst(jd, iptr, d);
1566 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1567 /* == => 0, < => 1, > => -1 */
1569 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1570 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1573 M_MOV_IMM(1, REG_ITMP1);
1574 M_MOV_IMM(-1, REG_ITMP2);
1575 emit_ucomisd_reg_reg(cd, s1, s2);
1576 M_CMOVB(REG_ITMP1, d);
1577 M_CMOVA(REG_ITMP2, d);
1578 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1579 emit_store_dst(jd, iptr, d);
1582 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1583 /* == => 0, < => 1, > => -1 */
1585 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1586 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1589 M_MOV_IMM(1, REG_ITMP1);
1590 M_MOV_IMM(-1, REG_ITMP2);
1591 emit_ucomisd_reg_reg(cd, s1, s2);
1592 M_CMOVB(REG_ITMP1, d);
1593 M_CMOVA(REG_ITMP2, d);
1594 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1595 emit_store_dst(jd, iptr, d);
1599 /* memory operations **************************************************/
1601 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1605 gen_nullptr_check(s1);
1606 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1607 emit_store_dst(jd, iptr, d);
1610 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1615 if (INSTRUCTION_MUST_CHECK(iptr)) {
1616 gen_nullptr_check(s1);
1619 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1620 emit_store_dst(jd, iptr, d);
1623 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1626 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1628 if (INSTRUCTION_MUST_CHECK(iptr)) {
1629 gen_nullptr_check(s1);
1632 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1633 emit_store_dst(jd, iptr, d);
1636 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1639 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1641 if (INSTRUCTION_MUST_CHECK(iptr)) {
1642 gen_nullptr_check(s1);
1645 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1646 emit_store_dst(jd, iptr, d);
1649 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1654 if (INSTRUCTION_MUST_CHECK(iptr)) {
1655 gen_nullptr_check(s1);
1658 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1659 emit_store_dst(jd, iptr, d);
1662 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1667 if (INSTRUCTION_MUST_CHECK(iptr)) {
1668 gen_nullptr_check(s1);
1671 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1672 emit_store_dst(jd, iptr, d);
1675 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1679 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1680 if (INSTRUCTION_MUST_CHECK(iptr)) {
1681 gen_nullptr_check(s1);
1684 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1685 emit_store_dst(jd, iptr, d);
1688 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1692 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1693 if (INSTRUCTION_MUST_CHECK(iptr)) {
1694 gen_nullptr_check(s1);
1697 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1698 emit_store_dst(jd, iptr, d);
1701 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1704 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1705 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1706 if (INSTRUCTION_MUST_CHECK(iptr)) {
1707 gen_nullptr_check(s1);
1710 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1711 emit_store_dst(jd, iptr, d);
1715 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1719 if (INSTRUCTION_MUST_CHECK(iptr)) {
1720 gen_nullptr_check(s1);
1723 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1724 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1727 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1731 if (INSTRUCTION_MUST_CHECK(iptr)) {
1732 gen_nullptr_check(s1);
1735 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1736 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1739 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1743 if (INSTRUCTION_MUST_CHECK(iptr)) {
1744 gen_nullptr_check(s1);
1747 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1748 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1751 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1755 if (INSTRUCTION_MUST_CHECK(iptr)) {
1756 gen_nullptr_check(s1);
1759 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1760 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1763 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1767 if (INSTRUCTION_MUST_CHECK(iptr)) {
1768 gen_nullptr_check(s1);
1771 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1772 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1775 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1779 if (INSTRUCTION_MUST_CHECK(iptr)) {
1780 gen_nullptr_check(s1);
1783 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1784 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1787 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1791 if (INSTRUCTION_MUST_CHECK(iptr)) {
1792 gen_nullptr_check(s1);
1795 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1796 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1799 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1802 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1803 if (INSTRUCTION_MUST_CHECK(iptr)) {
1804 gen_nullptr_check(s1);
1807 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1811 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1815 codegen_add_arraystoreexception_ref(cd);
1817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1818 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1819 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1820 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1824 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1827 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1828 if (INSTRUCTION_MUST_CHECK(iptr)) {
1829 gen_nullptr_check(s1);
1832 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1835 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1838 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1839 if (INSTRUCTION_MUST_CHECK(iptr)) {
1840 gen_nullptr_check(s1);
1843 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1846 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1850 if (INSTRUCTION_MUST_CHECK(iptr)) {
1851 gen_nullptr_check(s1);
1854 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1857 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1861 if (INSTRUCTION_MUST_CHECK(iptr)) {
1862 gen_nullptr_check(s1);
1865 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1868 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1871 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1872 if (INSTRUCTION_MUST_CHECK(iptr)) {
1873 gen_nullptr_check(s1);
1877 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1878 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1880 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1881 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1885 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1888 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1889 if (INSTRUCTION_MUST_CHECK(iptr)) {
1890 gen_nullptr_check(s1);
1893 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1897 case ICMD_GETSTATIC: /* ... ==> ..., value */
1899 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1900 unresolved_field *uf = iptr->sx.s23.s3.uf;
1902 fieldtype = uf->fieldref->parseddesc.fd->type;
1903 disp = dseg_addaddress(cd, NULL);
1904 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1906 /* must be calculated before codegen_addpatchref */
1908 if (opt_showdisassemble)
1909 disp -= PATCHER_CALL_SIZE;
1911 /* PROFILE_CYCLE_STOP; */
1913 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1915 if (opt_showdisassemble) {
1916 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
1919 /* PROFILE_CYCLE_START; */
1922 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1924 fieldtype = fi->type;
1926 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1929 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1931 if (opt_showdisassemble) {
1932 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
1935 PROFILE_CYCLE_START;
1938 disp = dseg_addaddress(cd, &(fi->value));
1939 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1942 /* This approach is much faster than moving the field
1943 address inline into a register. */
1945 M_ALD(REG_ITMP1, RIP, disp);
1947 switch (fieldtype) {
1949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1950 M_ILD(d, REG_ITMP1, 0);
1954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1955 M_LLD(d, REG_ITMP1, 0);
1958 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1959 M_FLD(d, REG_ITMP1, 0);
1962 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1963 M_DLD(d, REG_ITMP1, 0);
1966 emit_store_dst(jd, iptr, d);
1969 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1971 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1972 unresolved_field *uf = iptr->sx.s23.s3.uf;
1974 fieldtype = uf->fieldref->parseddesc.fd->type;
1975 disp = dseg_addaddress(cd, NULL);
1976 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1978 /* must be calculated before codegen_addpatchref */
1980 if (opt_showdisassemble)
1981 disp -= PATCHER_CALL_SIZE;
1983 /* PROFILE_CYCLE_STOP; */
1985 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1987 if (opt_showdisassemble) {
1988 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
1991 /* PROFILE_CYCLE_START; */
1994 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1996 fieldtype = fi->type;
1998 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2001 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2003 if (opt_showdisassemble) {
2004 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2005 disp -= PATCHER_CALL_SIZE;
2008 PROFILE_CYCLE_START;
2011 disp = dseg_addaddress(cd, &(fi->value));
2012 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2015 /* This approach is much faster than moving the field
2016 address inline into a register. */
2018 M_ALD(REG_ITMP1, RIP, disp);
2020 switch (fieldtype) {
2022 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2023 M_IST(s1, REG_ITMP1, 0);
2027 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2028 M_LST(s1, REG_ITMP1, 0);
2031 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2032 M_FST(s1, REG_ITMP1, 0);
2035 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2036 M_DST(s1, REG_ITMP1, 0);
2041 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2042 /* val = value (in current instruction) */
2043 /* following NOP) */
2045 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2046 unresolved_field *uf = iptr->sx.s23.s3.uf;
2048 fieldtype = uf->fieldref->parseddesc.fd->type;
2049 disp = dseg_addaddress(cd, NULL);
2050 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2052 /* must be calculated before codegen_addpatchref */
2054 if (opt_showdisassemble)
2055 disp -= PATCHER_CALL_SIZE;
2058 /* PROFILE_CYCLE_STOP; */
2060 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2062 if (opt_showdisassemble) {
2063 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2066 /* PROFILE_CYCLE_START; */
2069 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2071 fieldtype = fi->type;
2073 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2076 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2078 if (opt_showdisassemble) {
2079 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2082 PROFILE_CYCLE_START;
2085 disp = dseg_addaddress(cd, &(fi->value));
2086 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2089 /* This approach is much faster than moving the field
2090 address inline into a register. */
2092 M_ALD(REG_ITMP1, RIP, disp);
2094 switch (fieldtype) {
2097 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2102 if (IS_IMM32(iptr->sx.s23.s2.constval))
2103 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2105 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2106 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
2112 case ICMD_GETFIELD: /* ... ==> ..., value */
2114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2115 gen_nullptr_check(s1);
2117 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2118 unresolved_field *uf = iptr->sx.s23.s3.uf;
2120 /* PROFILE_CYCLE_STOP; */
2122 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2124 if (opt_showdisassemble) {
2125 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2128 /* PROFILE_CYCLE_START; */
2130 fieldtype = uf->fieldref->parseddesc.fd->type;
2134 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2136 fieldtype = fi->type;
2140 switch (fieldtype) {
2142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2143 M_ILD32(d, s1, disp);
2147 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2148 M_LLD32(d, s1, disp);
2151 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2152 M_FLD32(d, s1, disp);
2155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2156 M_DLD32(d, s1, disp);
2159 emit_store_dst(jd, iptr, d);
2162 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 gen_nullptr_check(s1);
2167 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2169 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2170 unresolved_field *uf = iptr->sx.s23.s3.uf;
2172 /* PROFILE_CYCLE_STOP; */
2174 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2176 if (opt_showdisassemble) {
2177 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2180 /* PROFILE_CYCLE_START; */
2182 fieldtype = uf->fieldref->parseddesc.fd->type;
2186 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2188 fieldtype = fi->type;
2192 switch (fieldtype) {
2194 M_IST32(s2, s1, disp);
2198 M_LST32(s2, s1, disp);
2201 M_FST32(s2, s1, disp);
2204 M_DST32(s2, s1, disp);
2209 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2210 /* val = value (in current instruction) */
2211 /* following NOP) */
2213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2214 gen_nullptr_check(s1);
2216 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2217 unresolved_field *uf = iptr->sx.s23.s3.uf;
2219 /* PROFILE_CYCLE_STOP; */
2221 codegen_addpatchref(cd, PATCHER_putfieldconst, uf, 0);
2223 if (opt_showdisassemble) {
2224 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2227 /* PROFILE_CYCLE_START; */
2229 fieldtype = uf->fieldref->parseddesc.fd->type;
2233 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2235 fieldtype = fi->type;
2239 switch (fieldtype) {
2242 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2247 /* XXX why no check for IS_IMM32? */
2248 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2249 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2255 /* branch operations **************************************************/
2257 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2259 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2260 M_INTMOVE(s1, REG_ITMP1_XPTR);
2264 #ifdef ENABLE_VERIFIER
2265 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2266 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2267 iptr->sx.s23.s2.uc, 0);
2269 if (opt_showdisassemble) {
2270 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2273 #endif /* ENABLE_VERIFIER */
2275 M_CALL_IMM(0); /* passing exception pc */
2276 M_POP(REG_ITMP2_XPC);
2278 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2282 case ICMD_GOTO: /* ... ==> ... */
2283 case ICMD_RET: /* ... ==> ... */
2286 codegen_addreference(cd, iptr->dst.block);
2289 case ICMD_JSR: /* ... ==> ... */
2292 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2295 case ICMD_IFNULL: /* ..., value ==> ... */
2297 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2300 codegen_addreference(cd, iptr->dst.block);
2303 case ICMD_IFNONNULL: /* ..., value ==> ... */
2305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2308 codegen_addreference(cd, iptr->dst.block);
2311 case ICMD_IFEQ: /* ..., value ==> ... */
2313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2314 M_ICMP_IMM(iptr->sx.val.i, s1);
2316 codegen_addreference(cd, iptr->dst.block);
2319 case ICMD_IFLT: /* ..., value ==> ... */
2321 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2322 M_ICMP_IMM(iptr->sx.val.i, s1);
2324 codegen_addreference(cd, iptr->dst.block);
2327 case ICMD_IFLE: /* ..., value ==> ... */
2329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2330 M_ICMP_IMM(iptr->sx.val.i, s1);
2332 codegen_addreference(cd, iptr->dst.block);
2335 case ICMD_IFNE: /* ..., value ==> ... */
2337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2338 M_ICMP_IMM(iptr->sx.val.i, s1);
2340 codegen_addreference(cd, iptr->dst.block);
2343 case ICMD_IFGT: /* ..., value ==> ... */
2345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2346 M_ICMP_IMM(iptr->sx.val.i, s1);
2348 codegen_addreference(cd, iptr->dst.block);
2351 case ICMD_IFGE: /* ..., value ==> ... */
2353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354 M_ICMP_IMM(iptr->sx.val.i, s1);
2356 codegen_addreference(cd, iptr->dst.block);
2359 case ICMD_IF_LEQ: /* ..., value ==> ... */
2361 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2362 if (IS_IMM32(iptr->sx.val.l))
2363 M_LCMP_IMM(iptr->sx.val.l, s1);
2365 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2366 M_LCMP(REG_ITMP2, s1);
2369 codegen_addreference(cd, iptr->dst.block);
2372 case ICMD_IF_LLT: /* ..., value ==> ... */
2374 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2375 if (IS_IMM32(iptr->sx.val.l))
2376 M_LCMP_IMM(iptr->sx.val.l, s1);
2378 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2379 M_LCMP(REG_ITMP2, s1);
2382 codegen_addreference(cd, iptr->dst.block);
2385 case ICMD_IF_LLE: /* ..., value ==> ... */
2387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2388 if (IS_IMM32(iptr->sx.val.l))
2389 M_LCMP_IMM(iptr->sx.val.l, s1);
2391 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2392 M_LCMP(REG_ITMP2, s1);
2395 codegen_addreference(cd, iptr->dst.block);
2398 case ICMD_IF_LNE: /* ..., value ==> ... */
2400 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2401 if (IS_IMM32(iptr->sx.val.l))
2402 M_LCMP_IMM(iptr->sx.val.l, s1);
2404 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2405 M_LCMP(REG_ITMP2, s1);
2408 codegen_addreference(cd, iptr->dst.block);
2411 case ICMD_IF_LGT: /* ..., value ==> ... */
2413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2414 if (IS_IMM32(iptr->sx.val.l))
2415 M_LCMP_IMM(iptr->sx.val.l, s1);
2417 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2418 M_LCMP(REG_ITMP2, s1);
2421 codegen_addreference(cd, iptr->dst.block);
2424 case ICMD_IF_LGE: /* ..., value ==> ... */
2426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2427 if (IS_IMM32(iptr->sx.val.l))
2428 M_LCMP_IMM(iptr->sx.val.l, s1);
2430 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2431 M_LCMP(REG_ITMP2, s1);
2434 codegen_addreference(cd, iptr->dst.block);
2437 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2443 codegen_addreference(cd, iptr->dst.block);
2446 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2447 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2453 codegen_addreference(cd, iptr->dst.block);
2456 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2458 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2459 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2462 codegen_addreference(cd, iptr->dst.block);
2465 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2466 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2468 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2469 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2472 codegen_addreference(cd, iptr->dst.block);
2475 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2478 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2481 codegen_addreference(cd, iptr->dst.block);
2484 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2487 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2490 codegen_addreference(cd, iptr->dst.block);
2493 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2499 codegen_addreference(cd, iptr->dst.block);
2502 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2505 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2508 codegen_addreference(cd, iptr->dst.block);
2511 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2517 codegen_addreference(cd, iptr->dst.block);
2520 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2523 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2526 codegen_addreference(cd, iptr->dst.block);
2529 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2535 codegen_addreference(cd, iptr->dst.block);
2538 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2541 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2544 codegen_addreference(cd, iptr->dst.block);
2547 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2550 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2551 M_INTMOVE(s1, REG_RESULT);
2552 goto nowperformreturn;
2554 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2556 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2557 M_INTMOVE(s1, REG_RESULT);
2559 #ifdef ENABLE_VERIFIER
2560 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2563 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2564 iptr->sx.s23.s2.uc, 0);
2566 if (opt_showdisassemble) {
2567 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2570 PROFILE_CYCLE_START;
2572 #endif /* ENABLE_VERIFIER */
2573 goto nowperformreturn;
2575 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2578 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2579 M_FLTMOVE(s1, REG_FRESULT);
2580 goto nowperformreturn;
2582 case ICMD_RETURN: /* ... ==> ... */
2588 p = cd->stackframesize;
2590 #if !defined(NDEBUG)
2591 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2592 emit_verbosecall_exit(jd);
2593 #endif /* !defined(NDEBUG) */
2595 #if defined(ENABLE_THREADS)
2596 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2597 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2599 /* we need to save the proper return value */
2600 switch (iptr->opc) {
2604 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2608 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2612 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2615 /* and now restore the proper return value */
2616 switch (iptr->opc) {
2620 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2624 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2630 /* restore saved registers */
2632 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2633 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2635 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2636 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2639 /* deallocate stack */
2641 if (cd->stackframesize)
2642 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2644 /* generate method profiling code */
2653 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2656 branch_target_t *table;
2658 table = iptr->dst.table;
2660 l = iptr->sx.s23.s2.tablelow;
2661 i = iptr->sx.s23.s3.tablehigh;
2663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2664 M_INTMOVE(s1, REG_ITMP1);
2667 M_ISUB_IMM(l, REG_ITMP1);
2669 /* number of targets */
2673 M_ICMP_IMM(i - 1, REG_ITMP1);
2676 codegen_addreference(cd, table[0].block); /* default target */
2678 /* build jump table top down and use address of lowest entry */
2683 dseg_addtarget(cd, table->block);
2687 /* length of dataseg after last dseg_addtarget is used
2690 M_MOV_IMM(0, REG_ITMP2);
2692 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2698 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2701 lookup_target_t *lookup;
2703 lookup = iptr->dst.lookup;
2705 i = iptr->sx.s23.s2.lookupcount;
2707 MCODECHECK(8 + ((7 + 6) * i) + 5);
2708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2711 M_ICMP_IMM(lookup->value, s1);
2713 codegen_addreference(cd, lookup->target.block);
2719 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2724 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2726 bte = iptr->sx.s23.s3.bte;
2730 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2732 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2733 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2734 case ICMD_INVOKEINTERFACE:
2736 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2738 um = iptr->sx.s23.s3.um;
2739 md = um->methodref->parseddesc.md;
2742 lm = iptr->sx.s23.s3.fmiref->p.method;
2744 md = lm->parseddesc;
2748 s3 = md->paramcount;
2750 MCODECHECK((20 * s3) + 128);
2752 /* copy arguments to registers or stack location */
2754 for (s3 = s3 - 1; s3 >= 0; s3--) {
2755 var = VAR(iptr->sx.s23.s2.args[s3]);
2757 /* Already Preallocated (ARGVAR) ? */
2758 if (var->flags & PREALLOC)
2761 if (IS_INT_LNG_TYPE(var->type)) {
2762 if (!md->params[s3].inmemory) {
2763 s1 = rd->argintregs[md->params[s3].regoff];
2764 d = emit_load(jd, iptr, var, s1);
2768 d = emit_load(jd, iptr, var, REG_ITMP1);
2769 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2773 if (!md->params[s3].inmemory) {
2774 s1 = rd->argfltregs[md->params[s3].regoff];
2775 d = emit_load(jd, iptr, var, s1);
2779 d = emit_load(jd, iptr, var, REG_FTMP1);
2781 if (IS_2_WORD_TYPE(var->type))
2782 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2784 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2789 /* generate method profiling code */
2793 switch (iptr->opc) {
2795 M_MOV_IMM(bte->fp, REG_ITMP1);
2798 if (INSTRUCTION_MUST_CHECK(iptr)) {
2801 codegen_add_fillinstacktrace_ref(cd);
2805 case ICMD_INVOKESPECIAL:
2808 codegen_add_nullpointerexception_ref(cd);
2812 case ICMD_INVOKESTATIC:
2814 disp = dseg_addaddress(cd, NULL);
2815 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2817 /* must be calculated before codegen_addpatchref */
2819 if (opt_showdisassemble)
2820 disp -= PATCHER_CALL_SIZE;
2822 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2825 if (opt_showdisassemble) {
2826 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2832 disp = dseg_addaddress(cd, lm->stubroutine);
2833 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2835 /* a = (ptrint) lm->stubroutine; */
2838 /* M_MOV_IMM(a, REG_ITMP2); */
2839 M_ALD(REG_ITMP2, RIP, disp);
2843 case ICMD_INVOKEVIRTUAL:
2844 gen_nullptr_check(REG_A0);
2847 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2849 if (opt_showdisassemble) {
2850 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2856 s1 = OFFSET(vftbl_t, table[0]) +
2857 sizeof(methodptr) * lm->vftblindex;
2859 M_ALD(REG_METHODPTR, REG_A0,
2860 OFFSET(java_objectheader, vftbl));
2861 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2865 case ICMD_INVOKEINTERFACE:
2866 gen_nullptr_check(REG_A0);
2869 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2871 if (opt_showdisassemble) {
2872 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2879 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2880 sizeof(methodptr) * lm->class->index;
2882 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2885 M_ALD(REG_METHODPTR, REG_A0,
2886 OFFSET(java_objectheader, vftbl));
2887 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2888 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2893 /* generate method profiling code */
2895 PROFILE_CYCLE_START;
2897 /* store return value */
2899 d = md->returntype.type;
2901 if (d != TYPE_VOID) {
2902 if (IS_INT_LNG_TYPE(d)) {
2903 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2904 M_INTMOVE(REG_RESULT, s1);
2907 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2908 M_FLTMOVE(REG_FRESULT, s1);
2910 emit_store_dst(jd, iptr, s1);
2915 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2917 /* val.a: (classinfo *) superclass */
2919 /* superclass is an interface:
2921 * OK if ((sub == NULL) ||
2922 * (sub->vftbl->interfacetablelength > super->index) &&
2923 * (sub->vftbl->interfacetable[-super->index] != NULL));
2925 * superclass is a class:
2927 * OK if ((sub == NULL) || (0
2928 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2929 * super->vftbl->diffval));
2932 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2933 /* object type cast-check */
2936 vftbl_t *supervftbl;
2939 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2945 super = iptr->sx.s23.s3.c.cls;
2946 superindex = super->index;
2947 supervftbl = super->vftbl;
2950 #if defined(ENABLE_THREADS)
2951 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2955 /* calculate interface checkcast code size */
2957 s2 = 3; /* mov_membase_reg */
2958 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
2960 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
2961 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
2962 3 /* test */ + 6 /* jcc */;
2965 s2 += (opt_showdisassemble ? 5 : 0);
2967 /* calculate class checkcast code size */
2969 s3 = 3; /* mov_membase_reg */
2970 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
2971 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
2974 if (s1 != REG_ITMP1) {
2975 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
2976 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
2977 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
2978 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
2984 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
2985 10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
2986 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2989 s3 += 3 /* cmp */ + 6 /* jcc */;
2992 s3 += (opt_showdisassemble ? 5 : 0);
2994 /* if class is not resolved, check which code to call */
2996 if (super == NULL) {
2998 M_BEQ(6 + (opt_showdisassemble ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
3000 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3001 iptr->sx.s23.s3.c.ref, 0);
3003 if (opt_showdisassemble) {
3004 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3007 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
3008 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
3012 /* interface checkcast code */
3014 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3015 if (super != NULL) {
3020 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3022 if (super == NULL) {
3023 codegen_addpatchref(cd,
3024 PATCHER_checkcast_instanceof_interface,
3025 iptr->sx.s23.s3.c.ref,
3028 if (opt_showdisassemble) {
3029 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3033 emit_movl_membase32_reg(cd, REG_ITMP2,
3034 OFFSET(vftbl_t, interfacetablelength),
3036 /* XXX TWISTI: should this be int arithmetic? */
3037 M_LSUB_IMM32(superindex, REG_ITMP3);
3040 codegen_add_classcastexception_ref(cd, s1);
3041 emit_mov_membase32_reg(cd, REG_ITMP2,
3042 OFFSET(vftbl_t, interfacetable[0]) -
3043 superindex * sizeof(methodptr*),
3047 codegen_add_classcastexception_ref(cd, s1);
3053 /* class checkcast code */
3055 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3056 if (super != NULL) {
3061 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3063 if (super == NULL) {
3064 codegen_addpatchref(cd, PATCHER_checkcast_class,
3065 iptr->sx.s23.s3.c.ref,
3068 if (opt_showdisassemble) {
3069 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3073 M_MOV_IMM(supervftbl, REG_ITMP3);
3074 #if defined(ENABLE_THREADS)
3075 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3077 emit_movl_membase32_reg(cd, REG_ITMP2,
3078 OFFSET(vftbl_t, baseval),
3080 /* if (s1 != REG_ITMP1) { */
3081 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3082 /* OFFSET(vftbl_t, baseval), */
3084 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3085 /* OFFSET(vftbl_t, diffval), */
3087 /* #if defined(ENABLE_THREADS) */
3088 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3090 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3093 emit_movl_membase32_reg(cd, REG_ITMP3,
3094 OFFSET(vftbl_t, baseval),
3096 M_LSUB(REG_ITMP3, REG_ITMP2);
3097 M_MOV_IMM(supervftbl, REG_ITMP3);
3098 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3100 #if defined(ENABLE_THREADS)
3101 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3103 M_LCMP(REG_ITMP3, REG_ITMP2);
3104 M_BA(0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
3105 codegen_add_classcastexception_ref(cd, s1);
3108 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3111 /* array type cast-check */
3113 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3114 M_INTMOVE(s1, REG_A0);
3116 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3117 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3118 iptr->sx.s23.s3.c.ref, 0);
3120 if (opt_showdisassemble) {
3121 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3125 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3126 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
3129 /* s1 may have been destroyed over the function call */
3130 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3133 codegen_add_classcastexception_ref(cd, s1);
3135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3139 emit_store_dst(jd, iptr, d);
3142 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3144 /* val.a: (classinfo *) superclass */
3146 /* superclass is an interface:
3148 * return (sub != NULL) &&
3149 * (sub->vftbl->interfacetablelength > super->index) &&
3150 * (sub->vftbl->interfacetable[-super->index] != NULL);
3152 * superclass is a class:
3154 * return ((sub != NULL) && (0
3155 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3156 * super->vftbl->diffvall));
3161 vftbl_t *supervftbl;
3164 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3170 super = iptr->sx.s23.s3.c.cls;
3171 superindex = super->index;
3172 supervftbl = super->vftbl;
3175 #if defined(ENABLE_THREADS)
3176 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3180 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3182 M_INTMOVE(s1, REG_ITMP1);
3186 /* calculate interface instanceof code size */
3188 s2 = 3; /* mov_membase_reg */
3189 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3190 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub_imm32 */ +
3191 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3192 3 /* test */ + 4 /* setcc */;
3195 s2 += (opt_showdisassemble ? 5 : 0);
3197 /* calculate class instanceof code size */
3199 s3 = 3; /* mov_membase_reg */
3200 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3201 s3 += 10; /* mov_imm_reg */
3202 s3 += 2; /* movl_membase_reg - only if REG_ITMP1 == RAX */
3203 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3204 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
3205 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3206 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
3207 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3208 s3 += 3 /* sub */ + 3 /* xor */ + 3 /* cmp */ + 4 /* setcc */;
3211 s3 += (opt_showdisassemble ? 5 : 0);
3213 emit_alu_reg_reg(cd, ALU_XOR, d, d);
3215 /* if class is not resolved, check which code to call */
3218 emit_test_reg_reg(cd, s1, s1);
3219 emit_jcc(cd, CC_Z, (6 + (opt_showdisassemble ? 5 : 0) +
3220 7 + 6 + s2 + 5 + s3));
3222 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3223 iptr->sx.s23.s3.c.ref, 0);
3225 if (opt_showdisassemble) {
3226 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3229 emit_movl_imm_reg(cd, 0, REG_ITMP3); /* super->flags */
3230 emit_alul_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP3);
3231 emit_jcc(cd, CC_Z, s2 + 5);
3234 /* interface instanceof code */
3236 if (!super || (super->flags & ACC_INTERFACE)) {
3238 emit_test_reg_reg(cd, s1, s1);
3239 emit_jcc(cd, CC_Z, s2);
3242 emit_mov_membase_reg(cd, s1,
3243 OFFSET(java_objectheader, vftbl),
3246 codegen_addpatchref(cd,
3247 PATCHER_checkcast_instanceof_interface,
3248 iptr->sx.s23.s3.c.ref, 0);
3250 if (opt_showdisassemble) {
3251 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3255 emit_movl_membase32_reg(cd, REG_ITMP1,
3256 OFFSET(vftbl_t, interfacetablelength),
3258 emit_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
3259 emit_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
3261 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
3263 emit_jcc(cd, CC_LE, a);
3264 emit_mov_membase32_reg(cd, REG_ITMP1,
3265 OFFSET(vftbl_t, interfacetable[0]) -
3266 superindex * sizeof(methodptr*),
3268 emit_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3269 emit_setcc_reg(cd, CC_NE, d);
3272 emit_jmp_imm(cd, s3);
3275 /* class instanceof code */
3277 if (!super || !(super->flags & ACC_INTERFACE)) {
3279 emit_test_reg_reg(cd, s1, s1);
3280 emit_jcc(cd, CC_E, s3);
3283 emit_mov_membase_reg(cd, s1,
3284 OFFSET(java_objectheader, vftbl),
3288 codegen_addpatchref(cd, PATCHER_instanceof_class,
3289 iptr->sx.s23.s3.c.ref, 0);
3291 if (opt_showdisassemble) {
3292 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3296 emit_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP2);
3297 #if defined(ENABLE_THREADS)
3298 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3300 emit_movl_membase_reg(cd, REG_ITMP1,
3301 OFFSET(vftbl_t, baseval),
3303 emit_movl_membase_reg(cd, REG_ITMP2,
3304 OFFSET(vftbl_t, diffval),
3306 emit_movl_membase_reg(cd, REG_ITMP2,
3307 OFFSET(vftbl_t, baseval),
3309 #if defined(ENABLE_THREADS)
3310 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3312 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
3313 emit_alu_reg_reg(cd, ALU_XOR, d, d); /* may be REG_ITMP2 */
3314 emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP1);
3315 emit_setcc_reg(cd, CC_BE, d);
3317 emit_store_dst(jd, iptr, d);
3321 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3323 /* check for negative sizes and copy sizes to stack if necessary */
3325 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3327 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3329 /* copy SAVEDVAR sizes to stack */
3330 var = VAR(iptr->sx.s23.s2.args[s1]);
3332 /* Already Preallocated? */
3333 if (!(var->flags & PREALLOC)) {
3334 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3335 M_LST(s2, REG_SP, s1 * 8);
3339 /* is a patcher function set? */
3341 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3342 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3343 iptr->sx.s23.s3.c.ref, 0);
3345 if (opt_showdisassemble) {
3346 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3350 /* a0 = dimension count */
3352 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3354 /* a1 = classinfo */
3356 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3358 /* a2 = pointer to dimensions = stack pointer */
3360 M_MOV(REG_SP, REG_A2);
3362 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3365 /* check for exception before result assignment */
3369 codegen_add_fillinstacktrace_ref(cd);
3371 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3372 M_INTMOVE(REG_RESULT, s1);
3373 emit_store_dst(jd, iptr, s1);
3377 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3381 } /* for instruction */
3383 MCODECHECK(512); /* XXX require a lower number? */
3385 /* At the end of a basic block we may have to append some nops,
3386 because the patcher stub calling code might be longer than the
3387 actual instruction. So codepatching does not change the
3388 following block unintentionally. */
3390 if (cd->mcodeptr < cd->lastmcodeptr) {
3391 while (cd->mcodeptr < cd->lastmcodeptr) {
3396 } /* if (bptr -> flags >= BBREACHED) */
3397 } /* for basic block */
3399 dseg_createlinenumbertable(cd);
3401 /* generate stubs */
3403 emit_exception_stubs(jd);
3404 emit_patcher_stubs(jd);
3406 emit_replacement_stubs(jd);
3411 /* everything's ok */
3417 /* createcompilerstub **********************************************************
3419 Creates a stub routine which calls the compiler.
3421 *******************************************************************************/
3423 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3424 #define COMPILERSTUB_CODESIZE 7 + 7 + 3
3426 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3429 u1 *createcompilerstub(methodinfo *m)
3431 u1 *s; /* memory to hold the stub */
3437 s = CNEW(u1, COMPILERSTUB_SIZE);
3439 /* set data pointer and code pointer */
3442 s = s + COMPILERSTUB_DATASIZE;
3444 /* mark start of dump memory area */
3446 dumpsize = dump_size();
3448 cd = DNEW(codegendata);
3451 /* Store the codeinfo pointer in the same place as in the
3452 methodheader for compiled methods. */
3454 code = code_codeinfo_new(m);
3456 d[0] = (ptrint) asm_call_jit_compiler;
3458 d[2] = (ptrint) code;
3460 /* code for the stub */
3462 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
3463 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
3466 #if defined(ENABLE_STATISTICS)
3468 count_cstub_len += COMPILERSTUB_SIZE;
3471 /* release dump area */
3473 dump_release(dumpsize);
3479 /* createnativestub ************************************************************
3481 Creates a stub routine which calls a native method.
3483 *******************************************************************************/
3485 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3493 s4 i, j; /* count variables */
3497 /* get required compiler data */
3504 /* initialize variables */
3507 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3509 /* calculate stack frame size */
3511 cd->stackframesize =
3512 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3513 sizeof(localref_table) / SIZEOF_VOID_P +
3514 INT_ARG_CNT + FLT_ARG_CNT +
3515 1 + /* functionptr, TODO: store in data segment */
3518 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3520 /* create method header */
3522 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3523 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3524 (void) dseg_adds4(cd, 0); /* IsSync */
3525 (void) dseg_adds4(cd, 0); /* IsLeaf */
3526 (void) dseg_adds4(cd, 0); /* IntSave */
3527 (void) dseg_adds4(cd, 0); /* FltSave */
3528 (void) dseg_addlinenumbertablesize(cd);
3529 (void) dseg_adds4(cd, 0); /* ExTableSize */
3531 /* generate native method profiling code */
3533 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3534 /* count frequency */
3536 M_MOV_IMM(code, REG_ITMP3);
3537 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3540 /* generate stub code */
3542 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3544 #if !defined(NDEBUG)
3545 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3546 emit_verbosecall_enter(jd);
3549 /* get function address (this must happen before the stackframeinfo) */
3551 #if !defined(WITH_STATIC_CLASSPATH)
3553 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
3555 if (opt_showdisassemble) {
3556 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3561 M_MOV_IMM(f, REG_ITMP3);
3564 /* save integer and float argument registers */
3566 for (i = 0, j = 0; i < md->paramcount; i++) {
3567 if (!md->params[i].inmemory) {
3568 s1 = md->params[i].regoff;
3570 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3571 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3573 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3579 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3581 /* create dynamic stack info */
3583 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3584 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3585 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3586 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3587 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3590 /* restore integer and float argument registers */
3592 for (i = 0, j = 0; i < md->paramcount; i++) {
3593 if (!md->params[i].inmemory) {
3594 s1 = md->params[i].regoff;
3596 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3597 M_LLD(rd->argintregs[s1], REG_SP, j * 8);
3599 M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
3605 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3608 /* copy or spill arguments to new locations */
3610 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3611 t = md->paramtypes[i].type;
3613 if (IS_INT_LNG_TYPE(t)) {
3614 if (!md->params[i].inmemory) {
3615 s1 = rd->argintregs[md->params[i].regoff];
3617 if (!nmd->params[j].inmemory) {
3618 s2 = rd->argintregs[nmd->params[j].regoff];
3622 s2 = nmd->params[j].regoff;
3623 M_LST(s1, REG_SP, s2 * 8);
3627 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3628 s2 = nmd->params[j].regoff;
3629 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3630 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3634 /* We only copy spilled float arguments, as the float argument */
3635 /* registers keep unchanged. */
3637 if (md->params[i].inmemory) {
3638 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3639 s2 = nmd->params[j].regoff;
3641 if (IS_2_WORD_TYPE(t)) {
3642 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3643 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3645 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3646 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3652 /* put class into second argument register */
3654 if (m->flags & ACC_STATIC)
3655 M_MOV_IMM(m->class, REG_A1);
3657 /* put env into first argument register */
3659 M_MOV_IMM(_Jv_env, REG_A0);
3661 /* do the native function call */
3665 /* save return value */
3667 if (md->returntype.type != TYPE_VOID) {
3668 if (IS_INT_LNG_TYPE(md->returntype.type))
3669 M_LST(REG_RESULT, REG_SP, 0 * 8);
3671 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3674 #if !defined(NDEBUG)
3675 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3676 emit_verbosecall_exit(jd);
3679 /* remove native stackframe info */
3681 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3682 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3684 M_MOV(REG_RESULT, REG_ITMP3);
3686 /* restore return value */
3688 if (md->returntype.type != TYPE_VOID) {
3689 if (IS_INT_LNG_TYPE(md->returntype.type))
3690 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3692 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3695 /* remove stackframe */
3697 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3699 /* test for exception */
3705 /* handle exception */
3707 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3708 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3709 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3711 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3714 /* generate patcher stubs */
3716 emit_patcher_stubs(jd);
3720 return code->entrypoint;
3725 * These are local overrides for various environment variables in Emacs.
3726 * Please do not remove this and leave it at the end of the file, where
3727 * Emacs will automagically detect them.
3728 * ---------------------------------------------------------------------
3731 * indent-tabs-mode: t
3735 * vim:noexpandtab:sw=4:ts=4: