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 5507 2006-09-15 09:19:11Z christian $
48 #include "vm/jit/x86_64/arch.h"
49 #include "vm/jit/x86_64/codegen.h"
50 #include "vm/jit/x86_64/md-emit.h"
52 #include "mm/memory.h"
53 #include "native/jni.h"
54 #include "native/native.h"
56 #if defined(ENABLE_THREADS)
57 # include "threads/native/lock.h"
60 #include "vm/builtin.h"
61 #include "vm/exceptions.h"
62 #include "vm/global.h"
63 #include "vm/loader.h"
64 #include "vm/options.h"
65 #include "vm/statistics.h"
66 #include "vm/stringlocal.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/methodheader.h"
74 #include "vm/jit/parse.h"
75 #include "vm/jit/patcher.h"
76 #include "vm/jit/reg.h"
77 #include "vm/jit/replace.h"
79 #if defined(ENABLE_LSRA)
80 # include "vm/jit/allocator/lsra.h"
84 /* codegen *********************************************************************
86 Generates machine code.
88 *******************************************************************************/
90 bool codegen(jitdata *jd)
96 s4 len, s1, s2, s3, d, disp;
100 varinfo *var, *var1, *var2, *dst;
104 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
105 unresolved_method *um;
106 builtintable_entry *bte;
108 rplpoint *replacementpoint;
111 /* get required compiler data */
118 /* 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, cd->exceptiontablelength); /* ExTableSize */
177 /* create exception table */
179 for (ex = cd->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)
228 var = jd->var + varindex;
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->new_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 == 0) && (bptr->type != BBTYPE_STD)) {
386 if (bptr->type == BBTYPE_SBR) {
387 /* d = reg_of_var(rd, src, REG_ITMP1); */
388 if (!IS_INMEMORY(src->flags))
393 emit_store(jd, NULL, src, d);
395 } else if (bptr->type == BBTYPE_EXH) {
396 /* d = reg_of_var(rd, src, REG_ITMP1); */
397 if (!IS_INMEMORY(src->flags))
401 M_INTMOVE(REG_ITMP1, d);
402 emit_store(jd, NULL, src, d);
412 varindex = bptr->invars[len];
413 var = jd->var + varindex;
414 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
415 if (bptr->type == BBTYPE_SBR) {
416 d = codegen_reg_of_var(0, var, REG_ITMP1);
418 emit_store(jd, NULL, var, d);
421 else if (bptr->type == BBTYPE_EXH) {
422 d = codegen_reg_of_var(0, var, REG_ITMP1);
423 M_INTMOVE(REG_ITMP1, d);
424 emit_store(jd, NULL, var, d);
428 assert((var->flags & OUTVAR));
429 d = codegen_reg_of_var(0, var, REG_ITMP1);
432 #if defined(ENABLE_LSRA)
435 /* walk through all instructions */
440 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
441 if (iptr->line != currentline) {
442 dseg_addlinenumber(cd, iptr->line);
443 currentline = iptr->line;
446 MCODECHECK(1024); /* 1KB should be enough */
449 case ICMD_INLINE_START: /* internal ICMDs */
450 case ICMD_INLINE_END:
453 case ICMD_NOP: /* ... ==> ... */
456 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
458 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
461 codegen_add_nullpointerexception_ref(cd);
464 /* constant operations ************************************************/
466 case ICMD_ICONST: /* ... ==> ..., constant */
468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
469 ICONST(d, iptr->sx.val.i);
470 emit_store_dst(jd, iptr, d);
473 case ICMD_LCONST: /* ... ==> ..., constant */
475 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
476 LCONST(d, iptr->sx.val.l);
477 emit_store_dst(jd, iptr, d);
480 case ICMD_FCONST: /* ... ==> ..., constant */
482 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
483 disp = dseg_addfloat(cd, iptr->sx.val.f);
484 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
485 emit_store_dst(jd, iptr, d);
488 case ICMD_DCONST: /* ... ==> ..., constant */
490 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
491 disp = dseg_adddouble(cd, iptr->sx.val.d);
492 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
493 emit_store_dst(jd, iptr, d);
496 case ICMD_ACONST: /* ... ==> ..., constant */
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
500 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
501 /* PROFILE_CYCLE_STOP; */
503 codegen_addpatchref(cd, PATCHER_aconst,
504 iptr->sx.val.c.ref, 0);
506 if (opt_showdisassemble) {
507 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
510 /* PROFILE_CYCLE_START; */
515 if (iptr->sx.val.anyptr == 0)
518 M_MOV_IMM(iptr->sx.val.anyptr, d);
520 emit_store_dst(jd, iptr, d);
524 /* load/store operations **********************************************/
537 emit_copy(jd, iptr, jd->var + iptr->s1.varindex,
538 jd->var + iptr->dst.varindex);
541 /* pop/copy/move operations *******************************************/
543 /* attention: double and longs are only one entry in CACAO ICMDs */
545 case ICMD_POP: /* ..., value ==> ... */
546 case ICMD_POP2: /* ..., value, value ==> ... */
553 M_COPY(iptr->s1.varindex, iptr->dst.varindex);
556 /* integer operations *************************************************/
558 case ICMD_INEG: /* ..., value ==> ..., - value */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
564 emit_store_dst(jd, iptr, d);
567 case ICMD_LNEG: /* ..., value ==> ..., - value */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
573 emit_store_dst(jd, iptr, d);
576 case ICMD_I2L: /* ..., value ==> ..., value */
578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
581 emit_store_dst(jd, iptr, d);
584 case ICMD_L2I: /* ..., value ==> ..., value */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
589 emit_store_dst(jd, iptr, d);
592 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
597 emit_store_dst(jd, iptr, d);
600 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
605 emit_store_dst(jd, iptr, d);
608 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
613 emit_store_dst(jd, iptr, d);
617 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628 emit_store_dst(jd, iptr, d);
631 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
632 /* sx.val.i = constant */
634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
637 M_IADD_IMM(iptr->sx.val.i, d);
638 emit_store_dst(jd, iptr, d);
641 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
644 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
645 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
652 emit_store_dst(jd, iptr, d);
655 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
656 /* sx.val.l = constant */
658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
661 if (IS_IMM32(iptr->sx.val.l))
662 M_LADD_IMM(iptr->sx.val.l, d);
664 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
665 M_LADD(REG_ITMP2, d);
667 emit_store_dst(jd, iptr, d);
670 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
676 M_INTMOVE(s1, REG_ITMP1);
677 M_ISUB(s2, REG_ITMP1);
678 M_INTMOVE(REG_ITMP1, d);
683 emit_store_dst(jd, iptr, d);
686 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
687 /* sx.val.i = constant */
689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
692 M_ISUB_IMM(iptr->sx.val.i, d);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
702 M_INTMOVE(s1, REG_ITMP1);
703 M_LSUB(s2, REG_ITMP1);
704 M_INTMOVE(REG_ITMP1, d);
709 emit_store_dst(jd, iptr, d);
712 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
713 /* sx.val.l = constant */
715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
716 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
718 if (IS_IMM32(iptr->sx.val.l))
719 M_LSUB_IMM(iptr->sx.val.l, d);
721 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
722 M_LSUB(REG_ITMP2, d);
724 emit_store_dst(jd, iptr, d);
727 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
738 emit_store_dst(jd, iptr, d);
741 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
742 /* sx.val.i = constant */
744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
745 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
746 if (iptr->sx.val.i == 2) {
750 M_IMUL_IMM(s1, iptr->sx.val.i, d);
751 emit_store_dst(jd, iptr, d);
754 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
757 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
769 /* sx.val.l = constant */
771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
773 if (IS_IMM32(iptr->sx.val.l))
774 M_LMUL_IMM(s1, iptr->sx.val.l, d);
776 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
778 M_LMUL(REG_ITMP2, d);
780 emit_store_dst(jd, iptr, d);
783 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
785 var1 = jd->var + iptr->s1.varindex;
786 var2 = jd->var + iptr->sx.s23.s2.varindex;
787 dst = jd->var + iptr->dst.varindex;
789 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
790 if (IS_INMEMORY(var1->flags))
791 M_ILD(RAX, REG_SP, var1->vv.regoff * 8);
793 M_INTMOVE(var1->vv.regoff, RAX);
795 if (IS_INMEMORY(var2->flags))
796 M_ILD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
798 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
803 codegen_add_arithmeticexception_ref(cd);
806 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
807 emit_jcc(cd, CC_NE, 4 + 6);
808 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
809 emit_jcc(cd, CC_E, 3 + 1 + 3); /* 6 bytes */
811 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
813 emit_idivl_reg(cd, REG_ITMP3);
815 if (IS_INMEMORY(dst->flags)) {
816 emit_mov_reg_membase(cd, RAX, REG_SP, dst->vv.regoff * 8);
817 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
820 M_INTMOVE(RAX, dst->vv.regoff);
822 if (dst->vv.regoff != RDX) {
823 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
828 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
830 var1 = jd->var + iptr->s1.varindex;
831 var2 = jd->var + iptr->sx.s23.s2.varindex;
832 dst = jd->var + iptr->dst.varindex;
834 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
835 if (IS_INMEMORY(var1->flags))
836 M_ILD(RAX, REG_SP, var1->vv.regoff * 8);
838 M_INTMOVE(var1->vv.regoff, RAX);
840 if (IS_INMEMORY(var2->flags))
841 M_ILD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
843 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
848 codegen_add_arithmeticexception_ref(cd);
851 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
853 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
854 emit_jcc(cd, CC_NE, 2 + 4 + 6);
857 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
858 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
859 emit_jcc(cd, CC_E, 1 + 3); /* 6 bytes */
862 emit_idivl_reg(cd, REG_ITMP3);
864 if (IS_INMEMORY(dst->flags)) {
865 emit_mov_reg_membase(cd, RDX, REG_SP, dst->vv.regoff * 8);
866 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
869 M_INTMOVE(RDX, dst->vv.regoff);
871 if (dst->vv.regoff != RDX) {
872 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
877 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
878 /* sx.val.i = constant */
880 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
882 M_INTMOVE(s1, REG_ITMP1);
883 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
884 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
885 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
886 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
887 emit_mov_reg_reg(cd, REG_ITMP1, d);
888 emit_store_dst(jd, iptr, d);
891 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
892 /* sx.val.i = constant */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
896 M_INTMOVE(s1, REG_ITMP1);
897 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
898 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
899 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
900 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
901 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
902 emit_mov_reg_reg(cd, REG_ITMP1, d);
903 emit_store_dst(jd, iptr, d);
907 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
909 var1 = jd->var + iptr->s1.varindex;
910 var2 = jd->var + iptr->sx.s23.s2.varindex;
911 dst = jd->var + iptr->dst.varindex;
913 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
915 if (IS_INMEMORY(var1->flags))
916 M_LLD(RAX, REG_SP, var1->vv.regoff * 8);
918 M_INTMOVE(var1->vv.regoff, RAX);
920 if (IS_INMEMORY(var2->flags))
921 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
923 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
928 codegen_add_arithmeticexception_ref(cd);
931 /* check as described in jvm spec */
932 disp = dseg_adds8(cd, 0x8000000000000000LL);
933 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
935 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
936 M_BEQ(3 + 2 + 3); /* 6 bytes */
938 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
940 emit_idiv_reg(cd, REG_ITMP3);
942 if (IS_INMEMORY(dst->flags)) {
943 M_LST(RAX, REG_SP, dst->vv.regoff * 8);
944 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
947 M_INTMOVE(RAX, dst->vv.regoff);
949 if (dst->vv.regoff != RDX) {
950 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
955 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
957 var1 = jd->var + iptr->s1.varindex;
958 var2 = jd->var + iptr->sx.s23.s2.varindex;
959 dst = jd->var + iptr->dst.varindex;
961 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
963 if (IS_INMEMORY(var1->flags))
964 M_LLD(REG_ITMP1, REG_SP, var1->vv.regoff * 8);
966 M_INTMOVE(var1->vv.regoff, REG_ITMP1);
968 if (IS_INMEMORY(var2->flags))
969 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
971 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974 M_INTMOVE(s1, REG_ITMP1);
975 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
976 M_INTMOVE(s2, REG_ITMP3);
981 codegen_add_arithmeticexception_ref(cd);
984 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
986 /* check as described in jvm spec */
987 disp = dseg_adds8(cd, 0x8000000000000000LL);
988 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
992 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
994 M_LXOR(RDX, RDX); /* 3 bytes */
995 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
996 M_BEQ(2 + 3); /* 6 bytes */
999 emit_idiv_reg(cd, REG_ITMP3);
1001 if (IS_INMEMORY(dst->flags)) {
1002 M_LST(RDX, REG_SP, dst->vv.regoff * 8);
1003 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1006 M_INTMOVE(RDX, dst->vv.regoff);
1008 if (dst->vv.regoff != RDX) {
1009 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1014 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1015 /* sx.val.i = constant */
1017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1018 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1019 M_INTMOVE(s1, REG_ITMP1);
1020 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1021 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
1022 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
1023 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
1024 emit_mov_reg_reg(cd, REG_ITMP1, d);
1025 emit_store_dst(jd, iptr, d);
1028 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1029 /* sx.val.l = constant */
1031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1032 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1033 M_INTMOVE(s1, REG_ITMP1);
1034 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1035 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
1036 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
1037 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
1038 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
1039 emit_mov_reg_reg(cd, REG_ITMP1, d);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1045 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1046 emit_ishift(jd, SHIFT_SHL, iptr);
1049 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1050 /* sx.val.i = constant */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1055 M_ISLL_IMM(iptr->sx.val.i, d);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1061 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1062 emit_ishift(jd, SHIFT_SAR, iptr);
1065 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1066 /* sx.val.i = constant */
1068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1069 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 M_ISRA_IMM(iptr->sx.val.i, d);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1077 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1078 emit_ishift(jd, SHIFT_SHR, iptr);
1081 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1082 /* sx.val.i = constant */
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1085 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1087 M_ISRL_IMM(iptr->sx.val.i, d);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1093 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1094 emit_lshift(jd, SHIFT_SHL, iptr);
1097 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1098 /* sx.val.i = constant */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1103 M_LSLL_IMM(iptr->sx.val.i, d);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1109 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1110 emit_lshift(jd, SHIFT_SAR, iptr);
1113 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1114 /* sx.val.i = constant */
1116 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119 M_LSRA_IMM(iptr->sx.val.i, d);
1120 emit_store_dst(jd, iptr, d);
1123 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1125 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1126 emit_lshift(jd, SHIFT_SHR, iptr);
1129 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1130 /* sx.val.l = constant */
1132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1135 M_LSRL_IMM(iptr->sx.val.i, d);
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_IAND: /* ..., 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_IANDCONST: /* ..., value ==> ..., value & constant */
1154 /* sx.val.i = constant */
1156 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1157 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1159 M_IAND_IMM(iptr->sx.val.i, d);
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1166 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1167 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1178 /* sx.val.l = constant */
1180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1183 if (IS_IMM32(iptr->sx.val.l))
1184 M_LAND_IMM(iptr->sx.val.l, d);
1186 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1187 M_LAND(REG_ITMP2, d);
1189 emit_store_dst(jd, iptr, d);
1192 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1196 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1207 /* sx.val.i = constant */
1209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1210 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1212 M_IOR_IMM(iptr->sx.val.i, d);
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1227 emit_store_dst(jd, iptr, d);
1230 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1231 /* sx.val.l = constant */
1233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1236 if (IS_IMM32(iptr->sx.val.l))
1237 M_LOR_IMM(iptr->sx.val.l, d);
1239 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1240 M_LOR(REG_ITMP2, d);
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1260 /* sx.val.i = constant */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1265 M_IXOR_IMM(iptr->sx.val.i, d);
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1273 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1280 emit_store_dst(jd, iptr, d);
1283 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1284 /* sx.val.l = constant */
1286 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1287 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1289 if (IS_IMM32(iptr->sx.val.l))
1290 M_LXOR_IMM(iptr->sx.val.l, d);
1292 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1293 M_LXOR(REG_ITMP2, d);
1295 emit_store_dst(jd, iptr, d);
1299 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1300 /* s1.localindex = variable, sx.val.i = constant */
1302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1303 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1305 /* Using inc and dec is not faster than add (tested with
1309 M_IADD_IMM(iptr->sx.val.i, d);
1311 emit_store_dst(jd, iptr, d);
1315 /* floating operations ************************************************/
1317 case ICMD_FNEG: /* ..., value ==> ..., - value */
1319 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1320 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1321 disp = dseg_adds4(cd, 0x80000000);
1323 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1324 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_DNEG: /* ..., value ==> ..., - value */
1330 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1332 disp = dseg_adds8(cd, 0x8000000000000000);
1334 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1335 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1336 emit_store_dst(jd, iptr, d);
1339 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1341 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1342 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1343 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1350 emit_store_dst(jd, iptr, d);
1353 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1355 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1356 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1357 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1364 emit_store_dst(jd, iptr, d);
1367 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1369 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1370 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1371 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1373 M_FLTMOVE(s2, REG_FTMP2);
1378 emit_store_dst(jd, iptr, d);
1381 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1383 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1384 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1385 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1387 M_FLTMOVE(s2, REG_FTMP2);
1392 emit_store_dst(jd, iptr, d);
1395 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1397 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1398 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1399 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1411 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1413 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1420 emit_store_dst(jd, iptr, d);
1423 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1425 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1426 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1427 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1429 M_FLTMOVE(s2, REG_FTMP2);
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1439 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1443 M_FLTMOVE(s2, REG_FTMP2);
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1453 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1454 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1456 emit_store_dst(jd, iptr, d);
1459 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1462 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1464 emit_store_dst(jd, iptr, d);
1467 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1469 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1472 emit_store_dst(jd, iptr, d);
1475 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1480 emit_store_dst(jd, iptr, d);
1483 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1485 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1486 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1488 M_ICMP_IMM(0x80000000, d); /* corner cases */
1489 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1490 ((REG_RESULT == d) ? 0 : 3);
1492 M_FLTMOVE(s1, REG_FTMP1);
1493 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1495 M_INTMOVE(REG_RESULT, d);
1496 emit_store_dst(jd, iptr, d);
1499 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1501 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1502 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1504 M_ICMP_IMM(0x80000000, d); /* corner cases */
1505 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1506 ((REG_RESULT == d) ? 0 : 3);
1508 M_FLTMOVE(s1, REG_FTMP1);
1509 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1511 M_INTMOVE(REG_RESULT, d);
1512 emit_store_dst(jd, iptr, d);
1515 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1517 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1520 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1521 M_LCMP(REG_ITMP2, d); /* corner cases */
1522 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1523 ((REG_RESULT == d) ? 0 : 3);
1525 M_FLTMOVE(s1, REG_FTMP1);
1526 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1528 M_INTMOVE(REG_RESULT, d);
1529 emit_store_dst(jd, iptr, d);
1532 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1534 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1537 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1538 M_LCMP(REG_ITMP2, d); /* corner cases */
1539 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1540 ((REG_RESULT == d) ? 0 : 3);
1542 M_FLTMOVE(s1, REG_FTMP1);
1543 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1545 M_INTMOVE(REG_RESULT, d);
1546 emit_store_dst(jd, iptr, d);
1549 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1551 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1552 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1554 emit_store_dst(jd, iptr, d);
1557 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1559 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1560 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1562 emit_store_dst(jd, iptr, d);
1565 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1566 /* == => 0, < => 1, > => -1 */
1568 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1572 M_MOV_IMM(1, REG_ITMP1);
1573 M_MOV_IMM(-1, REG_ITMP2);
1574 emit_ucomiss_reg_reg(cd, s1, s2);
1575 M_CMOVB(REG_ITMP1, d);
1576 M_CMOVA(REG_ITMP2, d);
1577 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1578 emit_store_dst(jd, iptr, d);
1581 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1582 /* == => 0, < => 1, > => -1 */
1584 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1585 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1588 M_MOV_IMM(1, REG_ITMP1);
1589 M_MOV_IMM(-1, REG_ITMP2);
1590 emit_ucomiss_reg_reg(cd, s1, s2);
1591 M_CMOVB(REG_ITMP1, d);
1592 M_CMOVA(REG_ITMP2, d);
1593 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1594 emit_store_dst(jd, iptr, d);
1597 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1598 /* == => 0, < => 1, > => -1 */
1600 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1604 M_MOV_IMM(1, REG_ITMP1);
1605 M_MOV_IMM(-1, REG_ITMP2);
1606 emit_ucomisd_reg_reg(cd, s1, s2);
1607 M_CMOVB(REG_ITMP1, d);
1608 M_CMOVA(REG_ITMP2, d);
1609 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1610 emit_store_dst(jd, iptr, d);
1613 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1614 /* == => 0, < => 1, > => -1 */
1616 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1617 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1620 M_MOV_IMM(1, REG_ITMP1);
1621 M_MOV_IMM(-1, REG_ITMP2);
1622 emit_ucomisd_reg_reg(cd, s1, s2);
1623 M_CMOVB(REG_ITMP1, d);
1624 M_CMOVA(REG_ITMP2, d);
1625 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1626 emit_store_dst(jd, iptr, d);
1630 /* memory operations **************************************************/
1632 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1636 gen_nullptr_check(s1);
1637 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1638 emit_store_dst(jd, iptr, d);
1641 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1644 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1645 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1646 if (INSTRUCTION_MUST_CHECK(iptr)) {
1647 gen_nullptr_check(s1);
1650 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1651 emit_store_dst(jd, iptr, d);
1654 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1657 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1659 if (INSTRUCTION_MUST_CHECK(iptr)) {
1660 gen_nullptr_check(s1);
1663 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1664 emit_store_dst(jd, iptr, d);
1667 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1672 if (INSTRUCTION_MUST_CHECK(iptr)) {
1673 gen_nullptr_check(s1);
1676 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1677 emit_store_dst(jd, iptr, d);
1680 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1683 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1685 if (INSTRUCTION_MUST_CHECK(iptr)) {
1686 gen_nullptr_check(s1);
1689 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1690 emit_store_dst(jd, iptr, d);
1693 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1698 if (INSTRUCTION_MUST_CHECK(iptr)) {
1699 gen_nullptr_check(s1);
1702 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1703 emit_store_dst(jd, iptr, d);
1706 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1710 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1711 if (INSTRUCTION_MUST_CHECK(iptr)) {
1712 gen_nullptr_check(s1);
1715 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1716 emit_store_dst(jd, iptr, d);
1719 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1722 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1723 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1724 if (INSTRUCTION_MUST_CHECK(iptr)) {
1725 gen_nullptr_check(s1);
1728 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1729 emit_store_dst(jd, iptr, d);
1732 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1737 if (INSTRUCTION_MUST_CHECK(iptr)) {
1738 gen_nullptr_check(s1);
1741 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1742 emit_store_dst(jd, iptr, d);
1746 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1750 if (INSTRUCTION_MUST_CHECK(iptr)) {
1751 gen_nullptr_check(s1);
1754 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1755 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1758 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1761 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1762 if (INSTRUCTION_MUST_CHECK(iptr)) {
1763 gen_nullptr_check(s1);
1766 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1767 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1770 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1774 if (INSTRUCTION_MUST_CHECK(iptr)) {
1775 gen_nullptr_check(s1);
1778 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1779 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1782 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1786 if (INSTRUCTION_MUST_CHECK(iptr)) {
1787 gen_nullptr_check(s1);
1790 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1791 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1794 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1797 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1798 if (INSTRUCTION_MUST_CHECK(iptr)) {
1799 gen_nullptr_check(s1);
1802 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1803 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1806 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1810 if (INSTRUCTION_MUST_CHECK(iptr)) {
1811 gen_nullptr_check(s1);
1814 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1815 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1818 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1822 if (INSTRUCTION_MUST_CHECK(iptr)) {
1823 gen_nullptr_check(s1);
1826 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1827 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1830 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1834 if (INSTRUCTION_MUST_CHECK(iptr)) {
1835 gen_nullptr_check(s1);
1838 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1842 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1846 codegen_add_arraystoreexception_ref(cd);
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1850 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1851 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1855 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1858 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1859 if (INSTRUCTION_MUST_CHECK(iptr)) {
1860 gen_nullptr_check(s1);
1863 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1866 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1870 if (INSTRUCTION_MUST_CHECK(iptr)) {
1871 gen_nullptr_check(s1);
1874 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
1877 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1880 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1881 if (INSTRUCTION_MUST_CHECK(iptr)) {
1882 gen_nullptr_check(s1);
1885 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1888 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1891 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1892 if (INSTRUCTION_MUST_CHECK(iptr)) {
1893 gen_nullptr_check(s1);
1896 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
1899 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1902 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1903 if (INSTRUCTION_MUST_CHECK(iptr)) {
1904 gen_nullptr_check(s1);
1908 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1909 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1911 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
1912 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
1916 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1920 if (INSTRUCTION_MUST_CHECK(iptr)) {
1921 gen_nullptr_check(s1);
1924 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
1928 case ICMD_GETSTATIC: /* ... ==> ..., value */
1930 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1931 unresolved_field *uf = iptr->sx.s23.s3.uf;
1933 fieldtype = uf->fieldref->parseddesc.fd->type;
1934 disp = dseg_addaddress(cd, NULL);
1935 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1937 /* must be calculated before codegen_addpatchref */
1939 if (opt_showdisassemble)
1940 disp -= PATCHER_CALL_SIZE;
1942 /* PROFILE_CYCLE_STOP; */
1944 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1946 if (opt_showdisassemble) {
1947 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
1950 /* PROFILE_CYCLE_START; */
1953 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1955 fieldtype = fi->type;
1957 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1960 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1962 if (opt_showdisassemble) {
1963 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
1966 PROFILE_CYCLE_START;
1969 disp = dseg_addaddress(cd, &(fi->value));
1970 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
1973 /* This approach is much faster than moving the field
1974 address inline into a register. */
1976 M_ALD(REG_ITMP1, RIP, disp);
1978 switch (fieldtype) {
1980 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1981 M_ILD(d, REG_ITMP1, 0);
1985 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1986 M_LLD(d, REG_ITMP1, 0);
1989 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1990 M_FLD(d, REG_ITMP1, 0);
1993 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1994 M_DLD(d, REG_ITMP1, 0);
1997 emit_store_dst(jd, iptr, d);
2000 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2002 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2003 unresolved_field *uf = iptr->sx.s23.s3.uf;
2005 fieldtype = uf->fieldref->parseddesc.fd->type;
2006 disp = dseg_addaddress(cd, NULL);
2007 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2009 /* must be calculated before codegen_addpatchref */
2011 if (opt_showdisassemble)
2012 disp -= PATCHER_CALL_SIZE;
2014 /* PROFILE_CYCLE_STOP; */
2016 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2018 if (opt_showdisassemble) {
2019 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2022 /* PROFILE_CYCLE_START; */
2025 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2027 fieldtype = fi->type;
2029 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2032 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2034 if (opt_showdisassemble) {
2035 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2036 disp -= PATCHER_CALL_SIZE;
2039 PROFILE_CYCLE_START;
2042 disp = dseg_addaddress(cd, &(fi->value));
2043 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2046 /* This approach is much faster than moving the field
2047 address inline into a register. */
2049 M_ALD(REG_ITMP1, RIP, disp);
2051 switch (fieldtype) {
2053 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2054 M_IST(s1, REG_ITMP1, 0);
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2059 M_LST(s1, REG_ITMP1, 0);
2062 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2063 M_FST(s1, REG_ITMP1, 0);
2066 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2067 M_DST(s1, REG_ITMP1, 0);
2072 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2073 /* val = value (in current instruction) */
2074 /* following NOP) */
2076 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2077 unresolved_field *uf = iptr->sx.s23.s3.uf;
2079 fieldtype = uf->fieldref->parseddesc.fd->type;
2080 disp = dseg_addaddress(cd, NULL);
2081 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2083 /* must be calculated before codegen_addpatchref */
2085 if (opt_showdisassemble)
2086 disp -= PATCHER_CALL_SIZE;
2089 /* PROFILE_CYCLE_STOP; */
2091 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2093 if (opt_showdisassemble) {
2094 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2097 /* PROFILE_CYCLE_START; */
2100 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2102 fieldtype = fi->type;
2104 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2107 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2109 if (opt_showdisassemble) {
2110 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2113 PROFILE_CYCLE_START;
2116 disp = dseg_addaddress(cd, &(fi->value));
2117 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2120 /* This approach is much faster than moving the field
2121 address inline into a register. */
2123 M_ALD(REG_ITMP1, RIP, disp);
2125 switch (fieldtype) {
2128 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2133 if (IS_IMM32(iptr->sx.s23.s2.constval))
2134 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2136 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2137 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
2143 case ICMD_GETFIELD: /* ... ==> ..., value */
2145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2146 gen_nullptr_check(s1);
2148 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2149 unresolved_field *uf = iptr->sx.s23.s3.uf;
2151 /* PROFILE_CYCLE_STOP; */
2153 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2155 if (opt_showdisassemble) {
2156 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2159 /* PROFILE_CYCLE_START; */
2161 fieldtype = uf->fieldref->parseddesc.fd->type;
2165 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2167 fieldtype = fi->type;
2171 switch (fieldtype) {
2173 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2174 M_ILD32(d, s1, disp);
2178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2179 M_LLD32(d, s1, disp);
2182 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2183 M_FLD32(d, s1, disp);
2186 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2187 M_DLD32(d, s1, disp);
2190 emit_store_dst(jd, iptr, d);
2193 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2195 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2196 gen_nullptr_check(s1);
2198 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2200 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2201 unresolved_field *uf = iptr->sx.s23.s3.uf;
2203 /* PROFILE_CYCLE_STOP; */
2205 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2207 if (opt_showdisassemble) {
2208 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2211 /* PROFILE_CYCLE_START; */
2213 fieldtype = uf->fieldref->parseddesc.fd->type;
2217 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2219 fieldtype = fi->type;
2223 switch (fieldtype) {
2225 M_IST32(s2, s1, disp);
2229 M_LST32(s2, s1, disp);
2232 M_FST32(s2, s1, disp);
2235 M_DST32(s2, s1, disp);
2240 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2241 /* val = value (in current instruction) */
2242 /* following NOP) */
2244 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2245 gen_nullptr_check(s1);
2247 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2248 unresolved_field *uf = iptr->sx.s23.s3.uf;
2250 /* PROFILE_CYCLE_STOP; */
2252 codegen_addpatchref(cd, PATCHER_putfieldconst, uf, 0);
2254 if (opt_showdisassemble) {
2255 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2258 /* PROFILE_CYCLE_START; */
2260 fieldtype = uf->fieldref->parseddesc.fd->type;
2264 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2266 fieldtype = fi->type;
2270 switch (fieldtype) {
2273 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2278 /* XXX why no check for IS_IMM32? */
2279 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2280 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2286 /* branch operations **************************************************/
2288 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2291 M_INTMOVE(s1, REG_ITMP1_XPTR);
2295 #ifdef ENABLE_VERIFIER
2296 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2297 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2298 iptr->sx.s23.s2.uc, 0);
2300 if (opt_showdisassemble) {
2301 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2304 #endif /* ENABLE_VERIFIER */
2306 M_CALL_IMM(0); /* passing exception pc */
2307 M_POP(REG_ITMP2_XPC);
2309 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2313 case ICMD_GOTO: /* ... ==> ... */
2316 codegen_addreference(cd, iptr->dst.block);
2319 case ICMD_JSR: /* ... ==> ... */
2322 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2325 case ICMD_RET: /* ... ==> ... */
2326 /* s1.localindex = local variable */
2329 codegen_addreference(cd, iptr->dst.block);
2332 case ICMD_IFNULL: /* ..., value ==> ... */
2334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 codegen_addreference(cd, iptr->dst.block);
2340 case ICMD_IFNONNULL: /* ..., value ==> ... */
2342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2345 codegen_addreference(cd, iptr->dst.block);
2348 case ICMD_IFEQ: /* ..., value ==> ... */
2350 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2351 M_ICMP_IMM(iptr->sx.val.i, s1);
2353 codegen_addreference(cd, iptr->dst.block);
2356 case ICMD_IFLT: /* ..., value ==> ... */
2358 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2359 M_ICMP_IMM(iptr->sx.val.i, s1);
2361 codegen_addreference(cd, iptr->dst.block);
2364 case ICMD_IFLE: /* ..., value ==> ... */
2366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2367 M_ICMP_IMM(iptr->sx.val.i, s1);
2369 codegen_addreference(cd, iptr->dst.block);
2372 case ICMD_IFNE: /* ..., value ==> ... */
2374 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2375 M_ICMP_IMM(iptr->sx.val.i, s1);
2377 codegen_addreference(cd, iptr->dst.block);
2380 case ICMD_IFGT: /* ..., value ==> ... */
2382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2383 M_ICMP_IMM(iptr->sx.val.i, s1);
2385 codegen_addreference(cd, iptr->dst.block);
2388 case ICMD_IFGE: /* ..., value ==> ... */
2390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2391 M_ICMP_IMM(iptr->sx.val.i, s1);
2393 codegen_addreference(cd, iptr->dst.block);
2396 case ICMD_IF_LEQ: /* ..., value ==> ... */
2398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2399 if (IS_IMM32(iptr->sx.val.l))
2400 M_LCMP_IMM(iptr->sx.val.l, s1);
2402 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2403 M_LCMP(REG_ITMP2, s1);
2406 codegen_addreference(cd, iptr->dst.block);
2409 case ICMD_IF_LLT: /* ..., value ==> ... */
2411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2412 if (IS_IMM32(iptr->sx.val.l))
2413 M_LCMP_IMM(iptr->sx.val.l, s1);
2415 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2416 M_LCMP(REG_ITMP2, s1);
2419 codegen_addreference(cd, iptr->dst.block);
2422 case ICMD_IF_LLE: /* ..., value ==> ... */
2424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2425 if (IS_IMM32(iptr->sx.val.l))
2426 M_LCMP_IMM(iptr->sx.val.l, s1);
2428 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2429 M_LCMP(REG_ITMP2, s1);
2432 codegen_addreference(cd, iptr->dst.block);
2435 case ICMD_IF_LNE: /* ..., value ==> ... */
2437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2438 if (IS_IMM32(iptr->sx.val.l))
2439 M_LCMP_IMM(iptr->sx.val.l, s1);
2441 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2442 M_LCMP(REG_ITMP2, s1);
2445 codegen_addreference(cd, iptr->dst.block);
2448 case ICMD_IF_LGT: /* ..., value ==> ... */
2450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2451 if (IS_IMM32(iptr->sx.val.l))
2452 M_LCMP_IMM(iptr->sx.val.l, s1);
2454 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2455 M_LCMP(REG_ITMP2, s1);
2458 codegen_addreference(cd, iptr->dst.block);
2461 case ICMD_IF_LGE: /* ..., value ==> ... */
2463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2464 if (IS_IMM32(iptr->sx.val.l))
2465 M_LCMP_IMM(iptr->sx.val.l, s1);
2467 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2468 M_LCMP(REG_ITMP2, s1);
2471 codegen_addreference(cd, iptr->dst.block);
2474 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2476 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2477 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2480 codegen_addreference(cd, iptr->dst.block);
2483 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2484 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
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_ICMPNE: /* ..., 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_LCMPNE: /* ..., value, value ==> ... */
2503 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2509 codegen_addreference(cd, iptr->dst.block);
2512 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2515 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2518 codegen_addreference(cd, iptr->dst.block);
2521 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2524 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2527 codegen_addreference(cd, iptr->dst.block);
2530 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2533 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2536 codegen_addreference(cd, iptr->dst.block);
2539 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2545 codegen_addreference(cd, iptr->dst.block);
2548 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2551 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2554 codegen_addreference(cd, iptr->dst.block);
2557 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2563 codegen_addreference(cd, iptr->dst.block);
2566 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2572 codegen_addreference(cd, iptr->dst.block);
2575 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2578 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2581 codegen_addreference(cd, iptr->dst.block);
2584 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2587 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2588 M_INTMOVE(s1, REG_RESULT);
2589 goto nowperformreturn;
2591 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2593 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2594 M_INTMOVE(s1, REG_RESULT);
2596 #ifdef ENABLE_VERIFIER
2597 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2600 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2601 iptr->sx.s23.s2.uc, 0);
2603 if (opt_showdisassemble) {
2604 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2607 PROFILE_CYCLE_START;
2609 #endif /* ENABLE_VERIFIER */
2610 goto nowperformreturn;
2612 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2615 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2616 M_FLTMOVE(s1, REG_FRESULT);
2617 goto nowperformreturn;
2619 case ICMD_RETURN: /* ... ==> ... */
2625 p = cd->stackframesize;
2627 #if !defined(NDEBUG)
2628 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2629 emit_verbosecall_exit(jd);
2630 #endif /* !defined(NDEBUG) */
2632 #if defined(ENABLE_THREADS)
2633 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2634 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2636 /* we need to save the proper return value */
2637 switch (iptr->opc) {
2641 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2645 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2649 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2652 /* and now restore the proper return value */
2653 switch (iptr->opc) {
2657 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2661 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2667 /* restore saved registers */
2669 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2670 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2672 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2673 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2676 /* deallocate stack */
2678 if (cd->stackframesize)
2679 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2681 /* generate method profiling code */
2690 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2693 branch_target_t *table;
2695 table = iptr->dst.table;
2697 l = iptr->sx.s23.s2.tablelow;
2698 i = iptr->sx.s23.s3.tablehigh;
2700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2701 M_INTMOVE(s1, REG_ITMP1);
2704 M_ISUB_IMM(l, REG_ITMP1);
2706 /* number of targets */
2710 M_ICMP_IMM(i - 1, REG_ITMP1);
2713 codegen_addreference(cd, table[0].block); /* default target */
2715 /* build jump table top down and use address of lowest entry */
2720 dseg_addtarget(cd, table->block);
2724 /* length of dataseg after last dseg_addtarget is used
2727 M_MOV_IMM(0, REG_ITMP2);
2729 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2735 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2738 lookup_target_t *lookup;
2740 lookup = iptr->dst.lookup;
2742 i = iptr->sx.s23.s2.lookupcount;
2744 MCODECHECK(8 + ((7 + 6) * i) + 5);
2745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2748 M_ICMP_IMM(lookup->value, s1);
2750 codegen_addreference(cd, lookup->target.block);
2756 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2761 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2763 bte = iptr->sx.s23.s3.bte;
2767 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2769 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2770 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2771 case ICMD_INVOKEINTERFACE:
2773 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2775 um = iptr->sx.s23.s3.um;
2776 md = um->methodref->parseddesc.md;
2779 lm = iptr->sx.s23.s3.fmiref->p.method;
2781 md = lm->parseddesc;
2785 s3 = md->paramcount;
2787 MCODECHECK((20 * s3) + 128);
2789 /* copy arguments to registers or stack location */
2791 for (s3 = s3 - 1; s3 >= 0; s3--) {
2792 s1 = iptr->sx.s23.s2.args[s3];
2793 var1 = jd->var + s1;
2795 /* Already Preallocated (ARGVAR) ? */
2796 if (var1->flags & PREALLOC)
2799 if (IS_INT_LNG_TYPE(var1->type)) {
2800 if (!md->params[s3].inmemory) {
2801 s1 = rd->argintregs[md->params[s3].regoff];
2802 d = emit_load(jd, iptr, var1, s1);
2806 d = emit_load(jd, iptr, var1, REG_ITMP1);
2807 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2811 if (!md->params[s3].inmemory) {
2812 s1 = rd->argfltregs[md->params[s3].regoff];
2813 d = emit_load(jd, iptr, var1, s1);
2817 d = emit_load(jd, iptr, var1, REG_FTMP1);
2819 if (IS_2_WORD_TYPE(var1->type))
2820 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2822 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2827 /* generate method profiling code */
2831 switch (iptr->opc) {
2833 M_MOV_IMM(bte->fp, REG_ITMP1);
2836 if (INSTRUCTION_MUST_CHECK(iptr)) {
2839 codegen_add_fillinstacktrace_ref(cd);
2843 case ICMD_INVOKESPECIAL:
2846 codegen_add_nullpointerexception_ref(cd);
2850 case ICMD_INVOKESTATIC:
2852 disp = dseg_addaddress(cd, NULL);
2853 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2855 /* must be calculated before codegen_addpatchref */
2857 if (opt_showdisassemble)
2858 disp -= PATCHER_CALL_SIZE;
2860 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2863 if (opt_showdisassemble) {
2864 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2870 disp = dseg_addaddress(cd, lm->stubroutine);
2871 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2873 /* a = (ptrint) lm->stubroutine; */
2876 /* M_MOV_IMM(a, REG_ITMP2); */
2877 M_ALD(REG_ITMP2, RIP, disp);
2881 case ICMD_INVOKEVIRTUAL:
2882 gen_nullptr_check(REG_A0);
2885 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2887 if (opt_showdisassemble) {
2888 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2894 s1 = OFFSET(vftbl_t, table[0]) +
2895 sizeof(methodptr) * lm->vftblindex;
2897 M_ALD(REG_METHODPTR, REG_A0,
2898 OFFSET(java_objectheader, vftbl));
2899 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2903 case ICMD_INVOKEINTERFACE:
2904 gen_nullptr_check(REG_A0);
2907 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2909 if (opt_showdisassemble) {
2910 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2917 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2918 sizeof(methodptr) * lm->class->index;
2920 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2923 M_ALD(REG_METHODPTR, REG_A0,
2924 OFFSET(java_objectheader, vftbl));
2925 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2926 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2931 /* generate method profiling code */
2933 PROFILE_CYCLE_START;
2935 /* store return value */
2937 d = md->returntype.type;
2939 if (d != TYPE_VOID) {
2940 if (IS_INT_LNG_TYPE(d)) {
2941 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2942 M_INTMOVE(REG_RESULT, s1);
2945 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2946 M_FLTMOVE(REG_FRESULT, s1);
2948 emit_store_dst(jd, iptr, s1);
2953 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2955 /* val.a: (classinfo *) superclass */
2957 /* superclass is an interface:
2959 * OK if ((sub == NULL) ||
2960 * (sub->vftbl->interfacetablelength > super->index) &&
2961 * (sub->vftbl->interfacetable[-super->index] != NULL));
2963 * superclass is a class:
2965 * OK if ((sub == NULL) || (0
2966 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2967 * super->vftbl->diffval));
2970 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2971 /* object type cast-check */
2974 vftbl_t *supervftbl;
2977 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2983 super = iptr->sx.s23.s3.c.cls;
2984 superindex = super->index;
2985 supervftbl = super->vftbl;
2988 #if defined(ENABLE_THREADS)
2989 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2993 /* calculate interface checkcast code size */
2995 s2 = 3; /* mov_membase_reg */
2996 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
2998 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
2999 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3000 3 /* test */ + 6 /* jcc */;
3003 s2 += (opt_showdisassemble ? 5 : 0);
3005 /* calculate class checkcast code size */
3007 s3 = 3; /* mov_membase_reg */
3008 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3009 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
3012 if (s1 != REG_ITMP1) {
3013 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
3014 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3015 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
3016 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3022 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
3023 10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
3024 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3027 s3 += 3 /* cmp */ + 6 /* jcc */;
3030 s3 += (opt_showdisassemble ? 5 : 0);
3032 /* if class is not resolved, check which code to call */
3034 if (super == NULL) {
3036 M_BEQ(6 + (opt_showdisassemble ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
3038 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3039 iptr->sx.s23.s3.c.ref, 0);
3041 if (opt_showdisassemble) {
3042 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3045 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
3046 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
3050 /* interface checkcast code */
3052 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3053 if (super != NULL) {
3058 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3060 if (super == NULL) {
3061 codegen_addpatchref(cd,
3062 PATCHER_checkcast_instanceof_interface,
3063 iptr->sx.s23.s3.c.ref,
3066 if (opt_showdisassemble) {
3067 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3071 emit_movl_membase32_reg(cd, REG_ITMP2,
3072 OFFSET(vftbl_t, interfacetablelength),
3074 /* XXX TWISTI: should this be int arithmetic? */
3075 M_LSUB_IMM32(superindex, REG_ITMP3);
3078 codegen_add_classcastexception_ref(cd, s1);
3079 emit_mov_membase32_reg(cd, REG_ITMP2,
3080 OFFSET(vftbl_t, interfacetable[0]) -
3081 superindex * sizeof(methodptr*),
3085 codegen_add_classcastexception_ref(cd, s1);
3091 /* class checkcast code */
3093 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3094 if (super != NULL) {
3099 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3101 if (super == NULL) {
3102 codegen_addpatchref(cd, PATCHER_checkcast_class,
3103 iptr->sx.s23.s3.c.ref,
3106 if (opt_showdisassemble) {
3107 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3111 M_MOV_IMM(supervftbl, REG_ITMP3);
3112 #if defined(ENABLE_THREADS)
3113 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3115 emit_movl_membase32_reg(cd, REG_ITMP2,
3116 OFFSET(vftbl_t, baseval),
3118 /* if (s1 != REG_ITMP1) { */
3119 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3120 /* OFFSET(vftbl_t, baseval), */
3122 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3123 /* OFFSET(vftbl_t, diffval), */
3125 /* #if defined(ENABLE_THREADS) */
3126 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3128 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3131 emit_movl_membase32_reg(cd, REG_ITMP3,
3132 OFFSET(vftbl_t, baseval),
3134 M_LSUB(REG_ITMP3, REG_ITMP2);
3135 M_MOV_IMM(supervftbl, REG_ITMP3);
3136 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3138 #if defined(ENABLE_THREADS)
3139 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3141 M_LCMP(REG_ITMP3, REG_ITMP2);
3142 M_BA(0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
3143 codegen_add_classcastexception_ref(cd, s1);
3146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3149 /* array type cast-check */
3151 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3152 M_INTMOVE(s1, REG_A0);
3154 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3155 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3156 iptr->sx.s23.s3.c.ref, 0);
3158 if (opt_showdisassemble) {
3159 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3163 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3164 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
3167 /* s1 may have been destroyed over the function call */
3168 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3171 codegen_add_classcastexception_ref(cd, s1);
3173 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3177 emit_store_dst(jd, iptr, d);
3180 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3182 /* val.a: (classinfo *) superclass */
3184 /* superclass is an interface:
3186 * return (sub != NULL) &&
3187 * (sub->vftbl->interfacetablelength > super->index) &&
3188 * (sub->vftbl->interfacetable[-super->index] != NULL);
3190 * superclass is a class:
3192 * return ((sub != NULL) && (0
3193 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3194 * super->vftbl->diffvall));
3199 vftbl_t *supervftbl;
3202 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3208 super = iptr->sx.s23.s3.c.cls;
3209 superindex = super->index;
3210 supervftbl = super->vftbl;
3213 #if defined(ENABLE_THREADS)
3214 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3217 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3218 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3220 M_INTMOVE(s1, REG_ITMP1);
3224 /* calculate interface instanceof code size */
3226 s2 = 3; /* mov_membase_reg */
3227 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3228 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub_imm32 */ +
3229 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3230 3 /* test */ + 4 /* setcc */;
3233 s2 += (opt_showdisassemble ? 5 : 0);
3235 /* calculate class instanceof code size */
3237 s3 = 3; /* mov_membase_reg */
3238 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3239 s3 += 10; /* mov_imm_reg */
3240 s3 += 2; /* movl_membase_reg - only if REG_ITMP1 == RAX */
3241 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3242 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
3243 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3244 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
3245 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3246 s3 += 3 /* sub */ + 3 /* xor */ + 3 /* cmp */ + 4 /* setcc */;
3249 s3 += (opt_showdisassemble ? 5 : 0);
3251 emit_alu_reg_reg(cd, ALU_XOR, d, d);
3253 /* if class is not resolved, check which code to call */
3256 emit_test_reg_reg(cd, s1, s1);
3257 emit_jcc(cd, CC_Z, (6 + (opt_showdisassemble ? 5 : 0) +
3258 7 + 6 + s2 + 5 + s3));
3260 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3261 iptr->sx.s23.s3.c.ref, 0);
3263 if (opt_showdisassemble) {
3264 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3267 emit_movl_imm_reg(cd, 0, REG_ITMP3); /* super->flags */
3268 emit_alul_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP3);
3269 emit_jcc(cd, CC_Z, s2 + 5);
3272 /* interface instanceof code */
3274 if (!super || (super->flags & ACC_INTERFACE)) {
3276 emit_test_reg_reg(cd, s1, s1);
3277 emit_jcc(cd, CC_Z, s2);
3280 emit_mov_membase_reg(cd, s1,
3281 OFFSET(java_objectheader, vftbl),
3284 codegen_addpatchref(cd,
3285 PATCHER_checkcast_instanceof_interface,
3286 iptr->sx.s23.s3.c.ref, 0);
3288 if (opt_showdisassemble) {
3289 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3293 emit_movl_membase32_reg(cd, REG_ITMP1,
3294 OFFSET(vftbl_t, interfacetablelength),
3296 emit_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
3297 emit_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
3299 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
3301 emit_jcc(cd, CC_LE, a);
3302 emit_mov_membase32_reg(cd, REG_ITMP1,
3303 OFFSET(vftbl_t, interfacetable[0]) -
3304 superindex * sizeof(methodptr*),
3306 emit_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3307 emit_setcc_reg(cd, CC_NE, d);
3310 emit_jmp_imm(cd, s3);
3313 /* class instanceof code */
3315 if (!super || !(super->flags & ACC_INTERFACE)) {
3317 emit_test_reg_reg(cd, s1, s1);
3318 emit_jcc(cd, CC_E, s3);
3321 emit_mov_membase_reg(cd, s1,
3322 OFFSET(java_objectheader, vftbl),
3326 codegen_addpatchref(cd, PATCHER_instanceof_class,
3327 iptr->sx.s23.s3.c.ref, 0);
3329 if (opt_showdisassemble) {
3330 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3334 emit_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP2);
3335 #if defined(ENABLE_THREADS)
3336 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3338 emit_movl_membase_reg(cd, REG_ITMP1,
3339 OFFSET(vftbl_t, baseval),
3341 emit_movl_membase_reg(cd, REG_ITMP2,
3342 OFFSET(vftbl_t, diffval),
3344 emit_movl_membase_reg(cd, REG_ITMP2,
3345 OFFSET(vftbl_t, baseval),
3347 #if defined(ENABLE_THREADS)
3348 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3350 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
3351 emit_alu_reg_reg(cd, ALU_XOR, d, d); /* may be REG_ITMP2 */
3352 emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP1);
3353 emit_setcc_reg(cd, CC_BE, d);
3355 emit_store_dst(jd, iptr, d);
3359 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3361 /* check for negative sizes and copy sizes to stack if necessary */
3363 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3365 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3367 /* copy SAVEDVAR sizes to stack */
3368 s3 = iptr->sx.s23.s2.args[s1];
3369 var1 = jd->var + s3;
3371 /* Already Preallocated (ARGVAR) ? */
3372 if (!(var1->flags & PREALLOC)) {
3373 s2 = emit_load(jd, iptr, var1, REG_ITMP1);
3374 M_LST(s2, REG_SP, s1 * 8);
3378 /* is a patcher function set? */
3380 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3381 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3382 iptr->sx.s23.s3.c.ref, 0);
3384 if (opt_showdisassemble) {
3385 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3389 /* a0 = dimension count */
3391 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3393 /* a1 = classinfo */
3395 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3397 /* a2 = pointer to dimensions = stack pointer */
3399 M_MOV(REG_SP, REG_A2);
3401 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3404 /* check for exception before result assignment */
3408 codegen_add_fillinstacktrace_ref(cd);
3410 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3411 M_INTMOVE(REG_RESULT, s1);
3412 emit_store_dst(jd, iptr, s1);
3416 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3420 } /* for instruction */
3422 /* copy values to interface registers */
3424 len = bptr->outdepth;
3427 /* At the end of a basic block we may have to append some nops,
3428 because the patcher stub calling code might be longer than the
3429 actual instruction. So codepatching does not change the
3430 following block unintentionally. */
3432 if (cd->mcodeptr < cd->lastmcodeptr) {
3433 while (cd->mcodeptr < cd->lastmcodeptr) {
3438 } /* if (bptr -> flags >= BBREACHED) */
3439 } /* for basic block */
3441 dseg_createlinenumbertable(cd);
3443 /* generate stubs */
3445 emit_exception_stubs(jd);
3446 emit_patcher_stubs(jd);
3448 emit_replacement_stubs(jd);
3453 /* everything's ok */
3459 /* createcompilerstub **********************************************************
3461 Creates a stub routine which calls the compiler.
3463 *******************************************************************************/
3465 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3466 #define COMPILERSTUB_CODESIZE 7 + 7 + 3
3468 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3471 u1 *createcompilerstub(methodinfo *m)
3473 u1 *s; /* memory to hold the stub */
3479 s = CNEW(u1, COMPILERSTUB_SIZE);
3481 /* set data pointer and code pointer */
3484 s = s + COMPILERSTUB_DATASIZE;
3486 /* mark start of dump memory area */
3488 dumpsize = dump_size();
3490 cd = DNEW(codegendata);
3493 /* Store the codeinfo pointer in the same place as in the
3494 methodheader for compiled methods. */
3496 code = code_codeinfo_new(m);
3498 d[0] = (ptrint) asm_call_jit_compiler;
3500 d[2] = (ptrint) code;
3502 /* code for the stub */
3504 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
3505 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
3508 #if defined(ENABLE_STATISTICS)
3510 count_cstub_len += COMPILERSTUB_SIZE;
3513 /* release dump area */
3515 dump_release(dumpsize);
3521 /* createnativestub ************************************************************
3523 Creates a stub routine which calls a native method.
3525 *******************************************************************************/
3527 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3535 s4 i, j; /* count variables */
3539 /* get required compiler data */
3546 /* initialize variables */
3549 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3551 /* calculate stack frame size */
3553 cd->stackframesize =
3554 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3555 sizeof(localref_table) / SIZEOF_VOID_P +
3556 INT_ARG_CNT + FLT_ARG_CNT +
3557 1 + /* functionptr, TODO: store in data segment */
3560 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3562 /* create method header */
3564 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3565 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3566 (void) dseg_adds4(cd, 0); /* IsSync */
3567 (void) dseg_adds4(cd, 0); /* IsLeaf */
3568 (void) dseg_adds4(cd, 0); /* IntSave */
3569 (void) dseg_adds4(cd, 0); /* FltSave */
3570 (void) dseg_addlinenumbertablesize(cd);
3571 (void) dseg_adds4(cd, 0); /* ExTableSize */
3573 /* generate native method profiling code */
3575 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3576 /* count frequency */
3578 M_MOV_IMM(code, REG_ITMP3);
3579 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3582 /* generate stub code */
3584 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3586 #if !defined(NDEBUG)
3587 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3588 emit_verbosecall_enter(jd);
3591 /* get function address (this must happen before the stackframeinfo) */
3593 #if !defined(WITH_STATIC_CLASSPATH)
3595 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
3597 if (opt_showdisassemble) {
3598 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3603 M_MOV_IMM(f, REG_ITMP3);
3606 /* save integer and float argument registers */
3608 for (i = 0, j = 0; i < md->paramcount; i++) {
3609 if (!md->params[i].inmemory) {
3610 s1 = md->params[i].regoff;
3612 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3613 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3615 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3621 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3623 /* create dynamic stack info */
3625 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3626 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3627 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3628 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3629 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3632 /* restore integer and float argument registers */
3634 for (i = 0, j = 0; i < md->paramcount; i++) {
3635 if (!md->params[i].inmemory) {
3636 s1 = md->params[i].regoff;
3638 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3639 M_LLD(rd->argintregs[s1], REG_SP, j * 8);
3641 M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
3647 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3650 /* copy or spill arguments to new locations */
3652 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3653 t = md->paramtypes[i].type;
3655 if (IS_INT_LNG_TYPE(t)) {
3656 if (!md->params[i].inmemory) {
3657 s1 = rd->argintregs[md->params[i].regoff];
3659 if (!nmd->params[j].inmemory) {
3660 s2 = rd->argintregs[nmd->params[j].regoff];
3664 s2 = nmd->params[j].regoff;
3665 M_LST(s1, REG_SP, s2 * 8);
3669 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3670 s2 = nmd->params[j].regoff;
3671 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3672 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3676 /* We only copy spilled float arguments, as the float argument */
3677 /* registers keep unchanged. */
3679 if (md->params[i].inmemory) {
3680 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3681 s2 = nmd->params[j].regoff;
3683 if (IS_2_WORD_TYPE(t)) {
3684 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3685 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3687 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3688 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3694 /* put class into second argument register */
3696 if (m->flags & ACC_STATIC)
3697 M_MOV_IMM(m->class, REG_A1);
3699 /* put env into first argument register */
3701 M_MOV_IMM(_Jv_env, REG_A0);
3703 /* do the native function call */
3707 /* save return value */
3709 if (md->returntype.type != TYPE_VOID) {
3710 if (IS_INT_LNG_TYPE(md->returntype.type))
3711 M_LST(REG_RESULT, REG_SP, 0 * 8);
3713 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3716 #if !defined(NDEBUG)
3717 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3718 emit_verbosecall_exit(jd);
3721 /* remove native stackframe info */
3723 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3724 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3726 M_MOV(REG_RESULT, REG_ITMP3);
3728 /* restore return value */
3730 if (md->returntype.type != TYPE_VOID) {
3731 if (IS_INT_LNG_TYPE(md->returntype.type))
3732 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3734 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3737 /* remove stackframe */
3739 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3741 /* test for exception */
3747 /* handle exception */
3749 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3750 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3751 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3753 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3756 /* generate patcher stubs */
3758 emit_patcher_stubs(jd);
3762 return code->entrypoint;
3767 * These are local overrides for various environment variables in Emacs.
3768 * Please do not remove this and leave it at the end of the file, where
3769 * Emacs will automagically detect them.
3770 * ---------------------------------------------------------------------
3773 * indent-tabs-mode: t
3777 * vim:noexpandtab:sw=4:ts=4: