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 5386 2006-09-06 21:56:21Z twisti $
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;
105 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
106 unresolved_method *um;
107 builtintable_entry *bte;
109 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.cls);
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;
218 var = &(rd->locals[l][t]);
220 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
224 s1 = md->params[p].regoff;
225 if (IS_INT_LNG_TYPE(t)) { /* integer args */
226 s2 = rd->argintregs[s1];
227 if (!md->params[p].inmemory) { /* register arguments */
228 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
229 M_INTMOVE(s2, var->regoff);
231 } else { /* reg arg -> spilled */
232 M_LST(s2, REG_SP, var->regoff * 8);
235 } else { /* stack arguments */
236 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
237 /* + 8 for return address */
238 M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
240 } else { /* stack arg -> spilled */
241 var->regoff = cd->stackframesize + s1 + 1;
245 } else { /* floating args */
246 if (!md->params[p].inmemory) { /* register arguments */
247 s2 = rd->argfltregs[s1];
248 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
249 M_FLTMOVE(s2, var->regoff);
251 } else { /* reg arg -> spilled */
252 M_DST(s2, REG_SP, var->regoff * 8);
255 } else { /* stack arguments */
256 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
257 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8 + 8);
260 var->regoff = cd->stackframesize + s1 + 1;
266 /* save monitorenter argument */
268 #if defined(ENABLE_THREADS)
269 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
270 /* stack offset for monitor argument */
274 if (opt_verbosecall) {
275 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
277 for (p = 0; p < INT_ARG_CNT; p++)
278 M_LST(rd->argintregs[p], REG_SP, p * 8);
280 for (p = 0; p < FLT_ARG_CNT; p++)
281 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
283 s1 += INT_ARG_CNT + FLT_ARG_CNT;
286 /* decide which monitor enter function to call */
288 if (m->flags & ACC_STATIC) {
289 M_MOV_IMM(&m->class->object.header, REG_A0);
294 codegen_add_nullpointerexception_ref(cd);
297 M_AST(REG_A0, REG_SP, s1 * 8);
298 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
301 if (opt_verbosecall) {
302 for (p = 0; p < INT_ARG_CNT; p++)
303 M_LLD(rd->argintregs[p], REG_SP, p * 8);
305 for (p = 0; p < FLT_ARG_CNT; p++)
306 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
308 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
314 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
315 emit_verbosecall_enter(jd);
316 #endif /* !defined(NDEBUG) */
320 /* end of header generation */
322 replacementpoint = jd->code->rplpoints;
324 /* walk through all basic blocks */
326 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
328 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
330 if (bptr->flags >= BBREACHED) {
332 /* branch resolving */
335 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
336 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
341 /* handle replacement points */
344 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
345 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
349 assert(cd->lastmcodeptr <= cd->mcodeptr);
350 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
354 /* copy interface registers to their destination */
359 /* generate basicblock profiling code */
361 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
362 /* count frequency */
364 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
365 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
367 /* if this is an exception handler, start profiling again */
369 if (bptr->type == BBTYPE_EXH)
373 #if defined(ENABLE_LSRA)
377 src = bptr->invars[len];
378 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
379 if (bptr->type == BBTYPE_SBR) {
380 /* d = reg_of_var(rd, src, REG_ITMP1); */
381 if (!(src->flags & INMEMORY))
386 emit_store(jd, NULL, src, d);
388 } else if (bptr->type == BBTYPE_EXH) {
389 /* d = reg_of_var(rd, src, REG_ITMP1); */
390 if (!(src->flags & INMEMORY))
394 M_INTMOVE(REG_ITMP1, d);
395 emit_store(jd, NULL, src, d);
405 src = bptr->invars[len];
406 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
407 if (bptr->type == BBTYPE_SBR) {
408 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
410 emit_store(jd, NULL, src, d);
412 } else if (bptr->type == BBTYPE_EXH) {
413 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
414 M_INTMOVE(REG_ITMP1, d);
415 emit_store(jd, NULL, src, d);
419 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
420 if ((src->varkind != STACKVAR)) {
422 if (IS_FLT_DBL_TYPE(s2)) {
423 s1 = rd->interfaces[len][s2].regoff;
425 if (!(rd->interfaces[len][s2].flags & INMEMORY))
428 M_DLD(d, REG_SP, s1 * 8);
430 emit_store(jd, NULL, src, d);
433 s1 = rd->interfaces[len][s2].regoff;
435 if (!(rd->interfaces[len][s2].flags & INMEMORY))
438 M_LLD(d, REG_SP, s1 * 8);
440 emit_store(jd, NULL, src, d);
445 #if defined(ENABLE_LSRA)
448 /* walk through all instructions */
453 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
454 if (iptr->line != currentline) {
455 dseg_addlinenumber(cd, iptr->line);
456 currentline = iptr->line;
459 MCODECHECK(1024); /* 1KB should be enough */
462 case ICMD_INLINE_START: /* internal ICMDs */
463 case ICMD_INLINE_END:
466 case ICMD_NOP: /* ... ==> ... */
469 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
471 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
474 codegen_add_nullpointerexception_ref(cd);
477 /* constant operations ************************************************/
479 case ICMD_ICONST: /* ... ==> ..., constant */
481 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
482 ICONST(d, iptr->sx.val.i);
483 emit_store_dst(jd, iptr, d);
486 case ICMD_LCONST: /* ... ==> ..., constant */
488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
489 LCONST(d, iptr->sx.val.l);
490 emit_store_dst(jd, iptr, d);
493 case ICMD_FCONST: /* ... ==> ..., constant */
495 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
496 disp = dseg_addfloat(cd, iptr->sx.val.f);
497 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
498 emit_store_dst(jd, iptr, d);
501 case ICMD_DCONST: /* ... ==> ..., constant */
503 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
504 disp = dseg_adddouble(cd, iptr->sx.val.d);
505 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
506 emit_store_dst(jd, iptr, d);
509 case ICMD_ACONST: /* ... ==> ..., constant */
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
513 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
514 /* PROFILE_CYCLE_STOP; */
516 codegen_addpatchref(cd, PATCHER_aconst,
517 iptr->sx.val.c.ref, 0);
519 if (opt_showdisassemble) {
520 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
523 /* PROFILE_CYCLE_START; */
528 if (iptr->sx.val.anyptr == 0)
531 M_MOV_IMM(iptr->sx.val.anyptr, d);
533 emit_store_dst(jd, iptr, d);
537 /* load/store operations **********************************************/
539 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
540 /* s1.localindex = local variable */
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
543 if ((iptr->dst.var->varkind == LOCALVAR) &&
544 (iptr->dst.var->varnum == iptr->s1.localindex))
546 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
547 if (var->flags & INMEMORY)
548 M_ILD(d, REG_SP, var->regoff * 8);
550 M_INTMOVE(var->regoff, d);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
555 case ICMD_ALOAD: /* op1 = local variable */
557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
558 if ((iptr->dst.var->varkind == LOCALVAR) &&
559 (iptr->dst.var->varnum == iptr->s1.localindex))
561 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
562 if (var->flags & INMEMORY)
563 M_LLD(d, REG_SP, var->regoff * 8);
565 M_INTMOVE(var->regoff, d);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
570 /* s1.localindex = local variable */
572 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
573 if ((iptr->dst.var->varkind == LOCALVAR) &&
574 (iptr->dst.var->varnum == iptr->s1.localindex))
576 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
577 if (var->flags & INMEMORY)
578 M_FLD(d, REG_SP, var->regoff * 8);
580 M_FLTMOVE(var->regoff, d);
581 emit_store_dst(jd, iptr, d);
584 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
585 /* s1.localindex = local variable */
587 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
588 if ((iptr->dst.var->varkind == LOCALVAR) &&
589 (iptr->dst.var->varnum == iptr->s1.localindex))
591 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
592 if (var->flags & INMEMORY)
593 M_DLD(d, REG_SP, var->regoff * 8);
595 M_FLTMOVE(var->regoff, d);
596 emit_store_dst(jd, iptr, d);
599 case ICMD_ISTORE: /* ..., value ==> ... */
600 /* dst.localindex = local variable */
602 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
604 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
605 if (var->flags & INMEMORY) {
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 M_IST(s1, REG_SP, var->regoff * 8);
609 s1 = emit_load_s1(jd, iptr, var->regoff);
610 M_INTMOVE(s1, var->regoff);
614 case ICMD_LSTORE: /* ..., value ==> ... */
615 case ICMD_ASTORE: /* op1 = local variable */
617 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
619 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
620 if (var->flags & INMEMORY) {
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 M_LST(s1, REG_SP, var->regoff * 8);
624 s1 = emit_load_s1(jd, iptr, var->regoff);
625 M_INTMOVE(s1, var->regoff);
629 case ICMD_FSTORE: /* ..., value ==> ... */
630 /* dst.localindex = local variable */
632 if ((iptr->s1.var->varkind == LOCALVAR) &&
633 (iptr->s1.var->varnum == iptr->dst.localindex)) {
636 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
637 if (var->flags & INMEMORY) {
638 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
639 M_FST(s1, REG_SP, var->regoff * 8);
641 s1 = emit_load_s1(jd, iptr, var->regoff);
642 M_FLTMOVE(s1, var->regoff);
646 case ICMD_DSTORE: /* ..., value ==> ... */
647 /* dst.localindex = local variable */
649 if ((iptr->s1.var->varkind == LOCALVAR) &&
650 (iptr->s1.var->varnum == iptr->dst.localindex)) {
653 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
654 if (var->flags & INMEMORY) {
655 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
656 M_DST(s1, REG_SP, var->regoff * 8);
658 s1 = emit_load_s1(jd, iptr, var->regoff);
659 M_FLTMOVE(s1, var->regoff);
664 /* pop/dup/swap operations ********************************************/
666 /* attention: double and longs are only one entry in CACAO ICMDs */
668 case ICMD_POP: /* ..., value ==> ... */
669 case ICMD_POP2: /* ..., value, value ==> ... */
672 case ICMD_DUP: /* ..., a ==> ..., a, a */
674 M_COPY(iptr->s1.var, iptr->dst.var);
677 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
679 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
680 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
681 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
684 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
686 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
687 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
688 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
689 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
692 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
694 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
695 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
698 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
700 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
701 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
702 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
703 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
704 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
707 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
709 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
710 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
711 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
712 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
713 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
714 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
717 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
719 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
720 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
724 /* integer operations *************************************************/
726 case ICMD_INEG: /* ..., value ==> ..., - value */
728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
729 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
732 emit_store_dst(jd, iptr, d);
735 case ICMD_LNEG: /* ..., value ==> ..., - value */
737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
741 emit_store_dst(jd, iptr, d);
744 case ICMD_I2L: /* ..., value ==> ..., value */
746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
747 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
749 emit_store_dst(jd, iptr, d);
752 case ICMD_L2I: /* ..., value ==> ..., value */
754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
757 emit_store_dst(jd, iptr, d);
760 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
763 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
773 emit_store_dst(jd, iptr, d);
776 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
781 emit_store_dst(jd, iptr, d);
785 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
800 /* sx.val.i = constant */
802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
805 M_IADD_IMM(iptr->sx.val.i, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
820 emit_store_dst(jd, iptr, d);
823 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
824 /* sx.val.l = constant */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
829 if (IS_IMM32(iptr->sx.val.l))
830 M_LADD_IMM(iptr->sx.val.l, d);
832 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
833 M_LADD(REG_ITMP2, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
844 M_INTMOVE(s1, REG_ITMP1);
845 M_ISUB(s2, REG_ITMP1);
846 M_INTMOVE(REG_ITMP1, d);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
860 M_ISUB_IMM(iptr->sx.val.i, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870 M_INTMOVE(s1, REG_ITMP1);
871 M_LSUB(s2, REG_ITMP1);
872 M_INTMOVE(REG_ITMP1, d);
877 emit_store_dst(jd, iptr, d);
880 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
881 /* sx.val.l = constant */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
886 if (IS_IMM32(iptr->sx.val.l))
887 M_LSUB_IMM(iptr->sx.val.l, d);
889 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
890 M_LSUB(REG_ITMP2, d);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
897 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
898 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
910 /* sx.val.i = constant */
912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
914 if (iptr->sx.val.i == 2) {
918 M_IMUL_IMM(s1, iptr->sx.val.i, d);
919 emit_store_dst(jd, iptr, d);
922 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
925 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
933 emit_store_dst(jd, iptr, d);
936 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
937 /* sx.val.l = constant */
939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
940 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
941 if (IS_IMM32(iptr->sx.val.l))
942 M_LMUL_IMM(s1, iptr->sx.val.l, d);
944 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
946 M_LMUL(REG_ITMP2, d);
948 emit_store_dst(jd, iptr, d);
951 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
953 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
954 if (iptr->s1.var->flags & INMEMORY)
955 M_ILD(RAX, REG_SP, iptr->s1.var->regoff * 8);
957 M_INTMOVE(iptr->s1.var->regoff, RAX);
959 if (iptr->sx.s23.s2.var->flags & INMEMORY)
960 M_ILD(REG_ITMP3, REG_SP, iptr->sx.s23.s2.var->regoff * 8);
962 M_INTMOVE(iptr->sx.s23.s2.var->regoff, REG_ITMP3);
967 codegen_add_arithmeticexception_ref(cd);
970 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
971 emit_jcc(cd, CC_NE, 4 + 6);
972 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
973 emit_jcc(cd, CC_E, 3 + 1 + 3); /* 6 bytes */
975 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
977 emit_idivl_reg(cd, REG_ITMP3);
979 if (iptr->dst.var->flags & INMEMORY) {
980 emit_mov_reg_membase(cd, RAX, REG_SP, iptr->dst.var->regoff * 8);
981 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
984 M_INTMOVE(RAX, iptr->dst.var->regoff);
986 if (iptr->dst.var->regoff != RDX) {
987 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
992 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
994 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
995 if (iptr->s1.var->flags & INMEMORY)
996 M_ILD(RAX, REG_SP, iptr->s1.var->regoff * 8);
998 M_INTMOVE(iptr->s1.var->regoff, RAX);
1000 if (iptr->sx.s23.s2.var->flags & INMEMORY)
1001 M_ILD(REG_ITMP3, REG_SP, iptr->sx.s23.s2.var->regoff * 8);
1003 M_INTMOVE(iptr->sx.s23.s2.var->regoff, REG_ITMP3);
1008 codegen_add_arithmeticexception_ref(cd);
1011 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
1013 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
1014 emit_jcc(cd, CC_NE, 2 + 4 + 6);
1017 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
1018 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
1019 emit_jcc(cd, CC_E, 1 + 3); /* 6 bytes */
1022 emit_idivl_reg(cd, REG_ITMP3);
1024 if (iptr->dst.var->flags & INMEMORY) {
1025 emit_mov_reg_membase(cd, RDX, REG_SP, iptr->dst.var->regoff * 8);
1026 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
1029 M_INTMOVE(RDX, iptr->dst.var->regoff);
1031 if (iptr->dst.var->regoff != RDX) {
1032 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
1037 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
1038 /* sx.val.i = constant */
1040 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1041 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1042 M_INTMOVE(s1, REG_ITMP1);
1043 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1044 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
1045 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
1046 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
1047 emit_mov_reg_reg(cd, REG_ITMP1, d);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1052 /* sx.val.i = constant */
1054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1056 M_INTMOVE(s1, REG_ITMP1);
1057 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1058 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
1059 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
1060 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
1061 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
1062 emit_mov_reg_reg(cd, REG_ITMP1, d);
1063 emit_store_dst(jd, iptr, d);
1067 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1069 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1071 if (iptr->s1.var->flags & INMEMORY)
1072 M_LLD(RAX, REG_SP, iptr->s1.var->regoff * 8);
1074 M_INTMOVE(iptr->s1.var->regoff, RAX);
1076 if (iptr->sx.s23.s2.var->flags & INMEMORY)
1077 M_LLD(REG_ITMP3, REG_SP, iptr->sx.s23.s2.var->regoff * 8);
1079 M_INTMOVE(iptr->sx.s23.s2.var->regoff, REG_ITMP3);
1084 codegen_add_arithmeticexception_ref(cd);
1087 /* check as described in jvm spec */
1088 disp = dseg_adds8(cd, 0x8000000000000000LL);
1089 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
1091 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
1092 M_BEQ(3 + 2 + 3); /* 6 bytes */
1094 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
1096 emit_idiv_reg(cd, REG_ITMP3);
1098 if (iptr->dst.var->flags & INMEMORY) {
1099 M_LST(RAX, REG_SP, iptr->dst.var->regoff * 8);
1100 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1103 M_INTMOVE(RAX, iptr->dst.var->regoff);
1105 if (iptr->dst.var->regoff != RDX) {
1106 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1111 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1113 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1114 if (iptr->s1.var->flags & INMEMORY)
1115 M_LLD(REG_ITMP1, REG_SP, iptr->s1.var->regoff * 8);
1117 M_INTMOVE(iptr->s1.var->regoff, REG_ITMP1);
1119 if (iptr->sx.s23.s2.var->flags & INMEMORY)
1120 M_LLD(REG_ITMP3, REG_SP, iptr->sx.s23.s2.var->regoff * 8);
1122 M_INTMOVE(iptr->sx.s23.s2.var->regoff, REG_ITMP3);
1127 codegen_add_arithmeticexception_ref(cd);
1130 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
1132 /* check as described in jvm spec */
1133 disp = dseg_adds8(cd, 0x8000000000000000LL);
1134 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
1138 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
1140 M_LXOR(RDX, RDX); /* 3 bytes */
1141 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
1142 M_BEQ(2 + 3); /* 6 bytes */
1145 emit_idiv_reg(cd, REG_ITMP3);
1147 if (iptr->dst.var->flags & INMEMORY) {
1148 M_LST(RDX, REG_SP, iptr->dst.var->regoff * 8);
1149 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1152 M_INTMOVE(RDX, iptr->dst.var->regoff);
1154 if (iptr->dst.var->regoff != RDX) {
1155 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1160 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1161 /* sx.val.i = constant */
1163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1164 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1165 M_INTMOVE(s1, REG_ITMP1);
1166 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1167 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
1168 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
1169 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
1170 emit_mov_reg_reg(cd, REG_ITMP1, d);
1171 emit_store_dst(jd, iptr, d);
1174 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1175 /* sx.val.l = constant */
1177 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1179 M_INTMOVE(s1, REG_ITMP1);
1180 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1181 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
1182 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
1183 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
1184 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
1185 emit_mov_reg_reg(cd, REG_ITMP1, d);
1186 emit_store_dst(jd, iptr, d);
1189 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1191 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1192 emit_ishift(cd, SHIFT_SHL, iptr->sx.s23.s2.var, iptr);
1195 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1196 /* sx.val.i = constant */
1198 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1199 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1201 M_ISLL_IMM(iptr->sx.val.i, d);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1207 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1208 emit_ishift(cd, SHIFT_SAR, iptr->sx.s23.s2.var, iptr);
1211 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1212 /* sx.val.i = constant */
1214 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1215 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1217 M_ISRA_IMM(iptr->sx.val.i, d);
1218 emit_store_dst(jd, iptr, d);
1221 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1223 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1224 emit_ishift(cd, SHIFT_SHR, iptr->sx.s23.s2.var, iptr);
1227 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1228 /* sx.val.i = constant */
1230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1231 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1233 M_ISRL_IMM(iptr->sx.val.i, d);
1234 emit_store_dst(jd, iptr, d);
1237 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1239 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1240 emit_lshift(cd, SHIFT_SHL, iptr->sx.s23.s2.var, iptr);
1243 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1244 /* sx.val.i = constant */
1246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1249 M_LSLL_IMM(iptr->sx.val.i, d);
1250 emit_store_dst(jd, iptr, d);
1253 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1255 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1256 emit_lshift(cd, SHIFT_SAR, iptr->sx.s23.s2.var, iptr);
1259 case ICMD_LSHRCONST: /* ..., 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_ITMP2);
1265 M_LSRA_IMM(iptr->sx.val.i, d);
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1271 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1272 emit_lshift(cd, SHIFT_SHR, iptr->sx.s23.s2.var, iptr);
1275 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1276 /* sx.val.l = constant */
1278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1279 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1281 M_LSRL_IMM(iptr->sx.val.i, d);
1282 emit_store_dst(jd, iptr, d);
1285 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1288 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1289 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1300 /* sx.val.i = constant */
1302 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1305 M_IAND_IMM(iptr->sx.val.i, d);
1306 emit_store_dst(jd, iptr, d);
1309 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1312 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1313 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1324 /* sx.val.l = constant */
1326 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1329 if (IS_IMM32(iptr->sx.val.l))
1330 M_LAND_IMM(iptr->sx.val.l, d);
1332 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1333 M_LAND(REG_ITMP2, d);
1335 emit_store_dst(jd, iptr, d);
1338 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1342 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1349 emit_store_dst(jd, iptr, d);
1352 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1353 /* sx.val.i = constant */
1355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1356 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1358 M_IOR_IMM(iptr->sx.val.i, d);
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1373 emit_store_dst(jd, iptr, d);
1376 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1377 /* sx.val.l = constant */
1379 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1380 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1382 if (IS_IMM32(iptr->sx.val.l))
1383 M_LOR_IMM(iptr->sx.val.l, d);
1385 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1386 M_LOR(REG_ITMP2, d);
1388 emit_store_dst(jd, iptr, d);
1391 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1394 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1402 emit_store_dst(jd, iptr, d);
1405 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1406 /* sx.val.i = constant */
1408 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1411 M_IXOR_IMM(iptr->sx.val.i, d);
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1417 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1418 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1430 /* sx.val.l = constant */
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1435 if (IS_IMM32(iptr->sx.val.l))
1436 M_LXOR_IMM(iptr->sx.val.l, d);
1438 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1439 M_LXOR(REG_ITMP2, d);
1441 emit_store_dst(jd, iptr, d);
1445 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1446 /* s1.localindex = variable, sx.val.i = constant */
1448 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1449 if (var->flags & INMEMORY) {
1451 M_ILD(s1, REG_SP, var->regoff * 8);
1455 /* Using inc and dec is not faster than add (tested with
1458 M_IADD_IMM(iptr->sx.val.i, s1);
1460 if (var->flags & INMEMORY)
1461 M_IST(s1, REG_SP, var->regoff * 8);
1465 /* floating operations ************************************************/
1467 case ICMD_FNEG: /* ..., value ==> ..., - value */
1469 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1471 disp = dseg_adds4(cd, 0x80000000);
1473 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1474 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1475 emit_store_dst(jd, iptr, d);
1478 case ICMD_DNEG: /* ..., value ==> ..., - value */
1480 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1481 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1482 disp = dseg_adds8(cd, 0x8000000000000000);
1484 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1485 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1486 emit_store_dst(jd, iptr, d);
1489 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1491 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1493 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1505 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1519 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1520 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1521 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1523 M_FLTMOVE(s2, REG_FTMP2);
1528 emit_store_dst(jd, iptr, d);
1531 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1533 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1534 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1535 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1537 M_FLTMOVE(s2, REG_FTMP2);
1542 emit_store_dst(jd, iptr, d);
1545 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1547 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1548 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1549 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1561 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1563 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1570 emit_store_dst(jd, iptr, d);
1573 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1575 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1577 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1579 M_FLTMOVE(s2, REG_FTMP2);
1584 emit_store_dst(jd, iptr, d);
1587 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1589 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1590 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1591 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1593 M_FLTMOVE(s2, REG_FTMP2);
1598 emit_store_dst(jd, iptr, d);
1601 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1606 emit_store_dst(jd, iptr, d);
1609 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1612 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1614 emit_store_dst(jd, iptr, d);
1617 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1622 emit_store_dst(jd, iptr, d);
1625 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1628 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1630 emit_store_dst(jd, iptr, d);
1633 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1635 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1638 M_ICMP_IMM(0x80000000, d); /* corner cases */
1639 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1640 ((REG_RESULT == d) ? 0 : 3);
1642 M_FLTMOVE(s1, REG_FTMP1);
1643 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1645 M_INTMOVE(REG_RESULT, d);
1646 emit_store_dst(jd, iptr, d);
1649 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1651 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1654 M_ICMP_IMM(0x80000000, d); /* corner cases */
1655 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1656 ((REG_RESULT == d) ? 0 : 3);
1658 M_FLTMOVE(s1, REG_FTMP1);
1659 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1661 M_INTMOVE(REG_RESULT, d);
1662 emit_store_dst(jd, iptr, d);
1665 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1667 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1670 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1671 M_LCMP(REG_ITMP2, d); /* corner cases */
1672 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1673 ((REG_RESULT == d) ? 0 : 3);
1675 M_FLTMOVE(s1, REG_FTMP1);
1676 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1678 M_INTMOVE(REG_RESULT, d);
1679 emit_store_dst(jd, iptr, d);
1682 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1684 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1687 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1688 M_LCMP(REG_ITMP2, d); /* corner cases */
1689 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1690 ((REG_RESULT == d) ? 0 : 3);
1692 M_FLTMOVE(s1, REG_FTMP1);
1693 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1695 M_INTMOVE(REG_RESULT, d);
1696 emit_store_dst(jd, iptr, d);
1699 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1701 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1702 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1704 emit_store_dst(jd, iptr, d);
1707 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1709 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1710 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1712 emit_store_dst(jd, iptr, d);
1715 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1716 /* == => 0, < => 1, > => -1 */
1718 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1719 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1722 M_MOV_IMM(1, REG_ITMP1);
1723 M_MOV_IMM(-1, REG_ITMP2);
1724 emit_ucomiss_reg_reg(cd, s1, s2);
1725 M_CMOVB(REG_ITMP1, d);
1726 M_CMOVA(REG_ITMP2, d);
1727 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1728 emit_store_dst(jd, iptr, d);
1731 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1732 /* == => 0, < => 1, > => -1 */
1734 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1735 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1738 M_MOV_IMM(1, REG_ITMP1);
1739 M_MOV_IMM(-1, REG_ITMP2);
1740 emit_ucomiss_reg_reg(cd, s1, s2);
1741 M_CMOVB(REG_ITMP1, d);
1742 M_CMOVA(REG_ITMP2, d);
1743 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1744 emit_store_dst(jd, iptr, d);
1747 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1748 /* == => 0, < => 1, > => -1 */
1750 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1751 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1754 M_MOV_IMM(1, REG_ITMP1);
1755 M_MOV_IMM(-1, REG_ITMP2);
1756 emit_ucomisd_reg_reg(cd, s1, s2);
1757 M_CMOVB(REG_ITMP1, d);
1758 M_CMOVA(REG_ITMP2, d);
1759 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1760 emit_store_dst(jd, iptr, d);
1763 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1764 /* == => 0, < => 1, > => -1 */
1766 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1767 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1770 M_MOV_IMM(1, REG_ITMP1);
1771 M_MOV_IMM(-1, REG_ITMP2);
1772 emit_ucomisd_reg_reg(cd, s1, s2);
1773 M_CMOVB(REG_ITMP1, d);
1774 M_CMOVA(REG_ITMP2, d);
1775 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1776 emit_store_dst(jd, iptr, d);
1780 /* memory operations **************************************************/
1782 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1786 gen_nullptr_check(s1);
1787 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1788 emit_store_dst(jd, iptr, d);
1791 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1796 if (INSTRUCTION_MUST_CHECK(iptr)) {
1797 gen_nullptr_check(s1);
1800 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1801 emit_store_dst(jd, iptr, d);
1804 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1807 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1809 if (INSTRUCTION_MUST_CHECK(iptr)) {
1810 gen_nullptr_check(s1);
1813 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1814 emit_store_dst(jd, iptr, d);
1817 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1820 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1822 if (INSTRUCTION_MUST_CHECK(iptr)) {
1823 gen_nullptr_check(s1);
1826 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1827 emit_store_dst(jd, iptr, d);
1830 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1834 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1835 if (INSTRUCTION_MUST_CHECK(iptr)) {
1836 gen_nullptr_check(s1);
1839 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1840 emit_store_dst(jd, iptr, d);
1843 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1848 if (INSTRUCTION_MUST_CHECK(iptr)) {
1849 gen_nullptr_check(s1);
1852 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1853 emit_store_dst(jd, iptr, d);
1856 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1859 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1860 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1861 if (INSTRUCTION_MUST_CHECK(iptr)) {
1862 gen_nullptr_check(s1);
1865 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1866 emit_store_dst(jd, iptr, d);
1869 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1872 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1873 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1874 if (INSTRUCTION_MUST_CHECK(iptr)) {
1875 gen_nullptr_check(s1);
1878 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1879 emit_store_dst(jd, iptr, d);
1882 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1887 if (INSTRUCTION_MUST_CHECK(iptr)) {
1888 gen_nullptr_check(s1);
1891 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]), s1, s2, 3, d);
1892 emit_store_dst(jd, iptr, d);
1896 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1900 if (INSTRUCTION_MUST_CHECK(iptr)) {
1901 gen_nullptr_check(s1);
1904 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1905 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1908 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1912 if (INSTRUCTION_MUST_CHECK(iptr)) {
1913 gen_nullptr_check(s1);
1916 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1917 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1920 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1923 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1924 if (INSTRUCTION_MUST_CHECK(iptr)) {
1925 gen_nullptr_check(s1);
1928 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1929 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1932 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1935 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1936 if (INSTRUCTION_MUST_CHECK(iptr)) {
1937 gen_nullptr_check(s1);
1940 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1941 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1944 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1947 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1948 if (INSTRUCTION_MUST_CHECK(iptr)) {
1949 gen_nullptr_check(s1);
1952 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1953 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1956 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1960 if (INSTRUCTION_MUST_CHECK(iptr)) {
1961 gen_nullptr_check(s1);
1964 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1965 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1968 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1971 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1972 if (INSTRUCTION_MUST_CHECK(iptr)) {
1973 gen_nullptr_check(s1);
1976 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1977 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1980 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1983 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1984 if (INSTRUCTION_MUST_CHECK(iptr)) {
1985 gen_nullptr_check(s1);
1988 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1992 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
1996 codegen_add_arraystoreexception_ref(cd);
1998 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1999 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2000 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2001 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2005 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2008 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2009 if (INSTRUCTION_MUST_CHECK(iptr)) {
2010 gen_nullptr_check(s1);
2013 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2016 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2020 if (INSTRUCTION_MUST_CHECK(iptr)) {
2021 gen_nullptr_check(s1);
2024 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
2027 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2030 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2031 if (INSTRUCTION_MUST_CHECK(iptr)) {
2032 gen_nullptr_check(s1);
2035 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2038 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2040 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2041 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2042 if (INSTRUCTION_MUST_CHECK(iptr)) {
2043 gen_nullptr_check(s1);
2046 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
2049 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2053 if (INSTRUCTION_MUST_CHECK(iptr)) {
2054 gen_nullptr_check(s1);
2058 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
2059 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2061 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2062 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2066 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2069 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2070 if (INSTRUCTION_MUST_CHECK(iptr)) {
2071 gen_nullptr_check(s1);
2074 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2078 case ICMD_GETSTATIC: /* ... ==> ..., value */
2080 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2081 unresolved_field *uf = iptr->sx.s23.s3.uf;
2083 fieldtype = uf->fieldref->parseddesc.fd->type;
2084 disp = dseg_addaddress(cd, NULL);
2085 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2087 /* must be calculated before codegen_addpatchref */
2089 if (opt_showdisassemble)
2090 disp -= PATCHER_CALL_SIZE;
2092 /* PROFILE_CYCLE_STOP; */
2094 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2096 if (opt_showdisassemble) {
2097 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2100 /* PROFILE_CYCLE_START; */
2103 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2105 fieldtype = fi->type;
2107 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2110 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2112 if (opt_showdisassemble) {
2113 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2116 PROFILE_CYCLE_START;
2119 disp = dseg_addaddress(cd, &(fi->value));
2120 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2123 /* This approach is much faster than moving the field
2124 address inline into a register. */
2126 M_ALD(REG_ITMP1, RIP, disp);
2128 switch (fieldtype) {
2130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2131 M_ILD(d, REG_ITMP1, 0);
2135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2136 M_LLD(d, REG_ITMP1, 0);
2139 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2140 M_FLD(d, REG_ITMP1, 0);
2143 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2144 M_DLD(d, REG_ITMP1, 0);
2147 emit_store_dst(jd, iptr, d);
2150 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2152 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2153 unresolved_field *uf = iptr->sx.s23.s3.uf;
2155 fieldtype = uf->fieldref->parseddesc.fd->type;
2156 disp = dseg_addaddress(cd, NULL);
2157 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2159 /* must be calculated before codegen_addpatchref */
2161 if (opt_showdisassemble)
2162 disp -= PATCHER_CALL_SIZE;
2164 /* PROFILE_CYCLE_STOP; */
2166 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2168 if (opt_showdisassemble) {
2169 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2172 /* PROFILE_CYCLE_START; */
2175 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2177 fieldtype = fi->type;
2179 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2182 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2184 if (opt_showdisassemble) {
2185 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2186 disp -= PATCHER_CALL_SIZE;
2189 PROFILE_CYCLE_START;
2192 disp = dseg_addaddress(cd, &(fi->value));
2193 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2196 /* This approach is much faster than moving the field
2197 address inline into a register. */
2199 M_ALD(REG_ITMP1, RIP, disp);
2201 switch (fieldtype) {
2203 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2204 M_IST(s1, REG_ITMP1, 0);
2208 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2209 M_LST(s1, REG_ITMP1, 0);
2212 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2213 M_FST(s1, REG_ITMP1, 0);
2216 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2217 M_DST(s1, REG_ITMP1, 0);
2222 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2223 /* val = value (in current instruction) */
2224 /* following NOP) */
2226 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2227 unresolved_field *uf = iptr->sx.s23.s3.uf;
2229 fieldtype = uf->fieldref->parseddesc.fd->type;
2230 disp = dseg_addaddress(cd, NULL);
2231 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2233 /* must be calculated before codegen_addpatchref */
2235 if (opt_showdisassemble)
2236 disp -= PATCHER_CALL_SIZE;
2239 /* PROFILE_CYCLE_STOP; */
2241 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2243 if (opt_showdisassemble) {
2244 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2247 /* PROFILE_CYCLE_START; */
2250 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2252 fieldtype = fi->type;
2254 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2257 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2259 if (opt_showdisassemble) {
2260 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2263 PROFILE_CYCLE_START;
2266 disp = dseg_addaddress(cd, &(fi->value));
2267 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2270 /* This approach is much faster than moving the field
2271 address inline into a register. */
2273 M_ALD(REG_ITMP1, RIP, disp);
2275 switch (fieldtype) {
2278 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2283 if (IS_IMM32(iptr->sx.s23.s2.constval))
2284 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2286 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2287 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
2293 case ICMD_GETFIELD: /* ... ==> ..., value */
2295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2296 gen_nullptr_check(s1);
2298 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2299 unresolved_field *uf = iptr->sx.s23.s3.uf;
2301 /* PROFILE_CYCLE_STOP; */
2303 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2305 if (opt_showdisassemble) {
2306 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2309 /* PROFILE_CYCLE_START; */
2311 fieldtype = uf->fieldref->parseddesc.fd->type;
2315 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2317 fieldtype = fi->type;
2321 switch (fieldtype) {
2323 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2324 M_ILD32(d, s1, disp);
2328 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2329 M_LLD32(d, s1, disp);
2332 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2333 M_FLD32(d, s1, disp);
2336 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2337 M_DLD32(d, s1, disp);
2340 emit_store_dst(jd, iptr, d);
2343 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2346 gen_nullptr_check(s1);
2348 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2350 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2351 unresolved_field *uf = iptr->sx.s23.s3.uf;
2353 /* PROFILE_CYCLE_STOP; */
2355 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2357 if (opt_showdisassemble) {
2358 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2361 /* PROFILE_CYCLE_START; */
2363 fieldtype = uf->fieldref->parseddesc.fd->type;
2367 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2369 fieldtype = fi->type;
2373 switch (fieldtype) {
2375 M_IST32(s2, s1, disp);
2379 M_LST32(s2, s1, disp);
2382 M_FST32(s2, s1, disp);
2385 M_DST32(s2, s1, disp);
2390 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2391 /* val = value (in current instruction) */
2392 /* following NOP) */
2394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2395 gen_nullptr_check(s1);
2397 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2398 unresolved_field *uf = iptr->sx.s23.s3.uf;
2400 /* PROFILE_CYCLE_STOP; */
2402 codegen_addpatchref(cd, PATCHER_putfieldconst, uf, 0);
2404 if (opt_showdisassemble) {
2405 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2408 /* PROFILE_CYCLE_START; */
2410 fieldtype = uf->fieldref->parseddesc.fd->type;
2414 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2416 fieldtype = fi->type;
2420 switch (fieldtype) {
2423 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2428 /* XXX why no check for IS_IMM32? */
2429 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2430 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2436 /* branch operations **************************************************/
2438 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2440 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2441 M_INTMOVE(s1, REG_ITMP1_XPTR);
2445 #ifdef ENABLE_VERIFIER
2446 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2447 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2448 iptr->sx.s23.s2.uc, 0);
2450 if (opt_showdisassemble) {
2451 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2454 #endif /* ENABLE_VERIFIER */
2456 M_CALL_IMM(0); /* passing exception pc */
2457 M_POP(REG_ITMP2_XPC);
2459 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2463 case ICMD_GOTO: /* ... ==> ... */
2466 codegen_addreference(cd, iptr->dst.block);
2469 case ICMD_JSR: /* ... ==> ... */
2472 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2475 case ICMD_RET: /* ... ==> ... */
2476 /* s1.localindex = local variable */
2478 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2479 if (var->flags & INMEMORY) {
2480 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2486 case ICMD_IFNULL: /* ..., value ==> ... */
2488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2491 codegen_addreference(cd, iptr->dst.block);
2494 case ICMD_IFNONNULL: /* ..., value ==> ... */
2496 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2499 codegen_addreference(cd, iptr->dst.block);
2502 case ICMD_IFEQ: /* ..., value ==> ... */
2504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2505 M_ICMP_IMM(iptr->sx.val.i, s1);
2507 codegen_addreference(cd, iptr->dst.block);
2510 case ICMD_IFLT: /* ..., value ==> ... */
2512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2513 M_ICMP_IMM(iptr->sx.val.i, s1);
2515 codegen_addreference(cd, iptr->dst.block);
2518 case ICMD_IFLE: /* ..., value ==> ... */
2520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2521 M_ICMP_IMM(iptr->sx.val.i, s1);
2523 codegen_addreference(cd, iptr->dst.block);
2526 case ICMD_IFNE: /* ..., value ==> ... */
2528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2529 M_ICMP_IMM(iptr->sx.val.i, s1);
2531 codegen_addreference(cd, iptr->dst.block);
2534 case ICMD_IFGT: /* ..., value ==> ... */
2536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2537 M_ICMP_IMM(iptr->sx.val.i, s1);
2539 codegen_addreference(cd, iptr->dst.block);
2542 case ICMD_IFGE: /* ..., value ==> ... */
2544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2545 M_ICMP_IMM(iptr->sx.val.i, s1);
2547 codegen_addreference(cd, iptr->dst.block);
2550 case ICMD_IF_LEQ: /* ..., value ==> ... */
2552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2553 if (IS_IMM32(iptr->sx.val.l))
2554 M_LCMP_IMM(iptr->sx.val.l, s1);
2556 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2557 M_LCMP(REG_ITMP2, s1);
2560 codegen_addreference(cd, iptr->dst.block);
2563 case ICMD_IF_LLT: /* ..., value ==> ... */
2565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2566 if (IS_IMM32(iptr->sx.val.l))
2567 M_LCMP_IMM(iptr->sx.val.l, s1);
2569 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2570 M_LCMP(REG_ITMP2, s1);
2573 codegen_addreference(cd, iptr->dst.block);
2576 case ICMD_IF_LLE: /* ..., value ==> ... */
2578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2579 if (IS_IMM32(iptr->sx.val.l))
2580 M_LCMP_IMM(iptr->sx.val.l, s1);
2582 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2583 M_LCMP(REG_ITMP2, s1);
2586 codegen_addreference(cd, iptr->dst.block);
2589 case ICMD_IF_LNE: /* ..., value ==> ... */
2591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2592 if (IS_IMM32(iptr->sx.val.l))
2593 M_LCMP_IMM(iptr->sx.val.l, s1);
2595 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2596 M_LCMP(REG_ITMP2, s1);
2599 codegen_addreference(cd, iptr->dst.block);
2602 case ICMD_IF_LGT: /* ..., value ==> ... */
2604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2605 if (IS_IMM32(iptr->sx.val.l))
2606 M_LCMP_IMM(iptr->sx.val.l, s1);
2608 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2609 M_LCMP(REG_ITMP2, s1);
2612 codegen_addreference(cd, iptr->dst.block);
2615 case ICMD_IF_LGE: /* ..., value ==> ... */
2617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2618 if (IS_IMM32(iptr->sx.val.l))
2619 M_LCMP_IMM(iptr->sx.val.l, s1);
2621 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2622 M_LCMP(REG_ITMP2, s1);
2625 codegen_addreference(cd, iptr->dst.block);
2628 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2630 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2631 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2634 codegen_addreference(cd, iptr->dst.block);
2637 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2638 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2641 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2644 codegen_addreference(cd, iptr->dst.block);
2647 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2653 codegen_addreference(cd, iptr->dst.block);
2656 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2657 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2660 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2663 codegen_addreference(cd, iptr->dst.block);
2666 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2672 codegen_addreference(cd, iptr->dst.block);
2675 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2681 codegen_addreference(cd, iptr->dst.block);
2684 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2690 codegen_addreference(cd, iptr->dst.block);
2693 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2699 codegen_addreference(cd, iptr->dst.block);
2702 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2708 codegen_addreference(cd, iptr->dst.block);
2711 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2713 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2714 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2717 codegen_addreference(cd, iptr->dst.block);
2720 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2726 codegen_addreference(cd, iptr->dst.block);
2729 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2735 codegen_addreference(cd, iptr->dst.block);
2738 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2741 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2742 M_INTMOVE(s1, REG_RESULT);
2743 goto nowperformreturn;
2745 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2747 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2748 M_INTMOVE(s1, REG_RESULT);
2750 #ifdef ENABLE_VERIFIER
2751 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2754 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2755 iptr->sx.s23.s2.uc, 0);
2757 if (opt_showdisassemble) {
2758 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
2761 PROFILE_CYCLE_START;
2763 #endif /* ENABLE_VERIFIER */
2764 goto nowperformreturn;
2766 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2769 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2770 M_FLTMOVE(s1, REG_FRESULT);
2771 goto nowperformreturn;
2773 case ICMD_RETURN: /* ... ==> ... */
2779 p = cd->stackframesize;
2781 #if !defined(NDEBUG)
2782 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2783 emit_verbosecall_exit(jd);
2784 #endif /* !defined(NDEBUG) */
2786 #if defined(ENABLE_THREADS)
2787 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2788 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2790 /* we need to save the proper return value */
2791 switch (iptr->opc) {
2795 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2799 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2803 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP1);
2806 /* and now restore the proper return value */
2807 switch (iptr->opc) {
2811 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2815 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2821 /* restore saved registers */
2823 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2824 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2826 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2827 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2830 /* deallocate stack */
2832 if (cd->stackframesize)
2833 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2835 /* generate method profiling code */
2844 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2847 branch_target_t *table;
2849 table = iptr->dst.table;
2851 l = iptr->sx.s23.s2.tablelow;
2852 i = iptr->sx.s23.s3.tablehigh;
2854 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2855 M_INTMOVE(s1, REG_ITMP1);
2858 M_ISUB_IMM(l, REG_ITMP1);
2860 /* number of targets */
2864 M_ICMP_IMM(i - 1, REG_ITMP1);
2867 codegen_addreference(cd, table[0].block); /* default target */
2869 /* build jump table top down and use address of lowest entry */
2874 dseg_addtarget(cd, table->block);
2878 /* length of dataseg after last dseg_addtarget is used
2881 M_MOV_IMM(0, REG_ITMP2);
2883 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2889 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2892 lookup_target_t *lookup;
2894 lookup = iptr->dst.lookup;
2896 i = iptr->sx.s23.s2.lookupcount;
2898 MCODECHECK(8 + ((7 + 6) * i) + 5);
2899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2902 M_ICMP_IMM(lookup->value, s1);
2904 codegen_addreference(cd, lookup->target.block);
2910 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2915 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2917 bte = iptr->sx.s23.s3.bte;
2921 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2923 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2924 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2925 case ICMD_INVOKEINTERFACE:
2927 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2929 um = iptr->sx.s23.s3.um;
2930 md = um->methodref->parseddesc.md;
2933 lm = iptr->sx.s23.s3.fmiref->p.method;
2935 md = lm->parseddesc;
2939 s3 = md->paramcount;
2941 MCODECHECK((20 * s3) + 128);
2943 /* copy arguments to registers or stack location */
2945 for (s3 = s3 - 1; s3 >= 0; s3--) {
2946 src = iptr->sx.s23.s2.args[s3];
2948 if (src->varkind == ARGVAR)
2951 if (IS_INT_LNG_TYPE(src->type)) {
2952 if (!md->params[s3].inmemory) {
2953 s1 = rd->argintregs[md->params[s3].regoff];
2954 d = emit_load(jd, iptr, src, s1);
2958 d = emit_load(jd, iptr, src, REG_ITMP1);
2959 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2963 if (!md->params[s3].inmemory) {
2964 s1 = rd->argfltregs[md->params[s3].regoff];
2965 d = emit_load(jd, iptr, src, s1);
2969 d = emit_load(jd, iptr, src, REG_FTMP1);
2971 if (IS_2_WORD_TYPE(src->type))
2972 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2974 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2979 /* generate method profiling code */
2983 switch (iptr->opc) {
2985 M_MOV_IMM(bte->fp, REG_ITMP1);
2988 if (INSTRUCTION_MUST_CHECK(iptr)) {
2991 codegen_add_fillinstacktrace_ref(cd);
2995 case ICMD_INVOKESPECIAL:
2998 codegen_add_nullpointerexception_ref(cd);
3002 case ICMD_INVOKESTATIC:
3004 disp = dseg_addaddress(cd, NULL);
3005 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
3007 /* must be calculated before codegen_addpatchref */
3009 if (opt_showdisassemble)
3010 disp -= PATCHER_CALL_SIZE;
3012 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3015 if (opt_showdisassemble) {
3016 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3022 disp = dseg_addaddress(cd, lm->stubroutine);
3023 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
3025 /* a = (ptrint) lm->stubroutine; */
3028 /* M_MOV_IMM(a, REG_ITMP2); */
3029 M_ALD(REG_ITMP2, RIP, disp);
3033 case ICMD_INVOKEVIRTUAL:
3034 gen_nullptr_check(REG_A0);
3037 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3039 if (opt_showdisassemble) {
3040 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3046 s1 = OFFSET(vftbl_t, table[0]) +
3047 sizeof(methodptr) * lm->vftblindex;
3049 M_ALD(REG_METHODPTR, REG_A0,
3050 OFFSET(java_objectheader, vftbl));
3051 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3055 case ICMD_INVOKEINTERFACE:
3056 gen_nullptr_check(REG_A0);
3059 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3061 if (opt_showdisassemble) {
3062 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3069 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3070 sizeof(methodptr) * lm->class->index;
3072 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3075 M_ALD(REG_METHODPTR, REG_A0,
3076 OFFSET(java_objectheader, vftbl));
3077 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3078 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3083 /* generate method profiling code */
3085 PROFILE_CYCLE_START;
3087 /* store return value */
3089 d = md->returntype.type;
3091 if (d != TYPE_VOID) {
3092 if (IS_INT_LNG_TYPE(d)) {
3093 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3094 M_INTMOVE(REG_RESULT, s1);
3097 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3098 M_FLTMOVE(REG_FRESULT, s1);
3100 emit_store_dst(jd, iptr, s1);
3105 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3107 /* val.a: (classinfo *) superclass */
3109 /* superclass is an interface:
3111 * OK if ((sub == NULL) ||
3112 * (sub->vftbl->interfacetablelength > super->index) &&
3113 * (sub->vftbl->interfacetable[-super->index] != NULL));
3115 * superclass is a class:
3117 * OK if ((sub == NULL) || (0
3118 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3119 * super->vftbl->diffval));
3122 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3123 /* object type cast-check */
3126 vftbl_t *supervftbl;
3129 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3135 super = iptr->sx.s23.s3.c.cls;
3136 superindex = super->index;
3137 supervftbl = super->vftbl;
3140 #if defined(ENABLE_THREADS)
3141 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3145 /* calculate interface checkcast code size */
3147 s2 = 3; /* mov_membase_reg */
3148 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3150 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
3151 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3152 3 /* test */ + 6 /* jcc */;
3155 s2 += (opt_showdisassemble ? 5 : 0);
3157 /* calculate class checkcast code size */
3159 s3 = 3; /* mov_membase_reg */
3160 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3161 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
3164 if (s1 != REG_ITMP1) {
3165 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
3166 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3167 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
3168 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3174 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
3175 10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
3176 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3179 s3 += 3 /* cmp */ + 6 /* jcc */;
3182 s3 += (opt_showdisassemble ? 5 : 0);
3184 /* if class is not resolved, check which code to call */
3186 if (super == NULL) {
3188 M_BEQ(6 + (opt_showdisassemble ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
3190 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3191 iptr->sx.s23.s3.c.ref, 0);
3193 if (opt_showdisassemble) {
3194 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3197 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
3198 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
3202 /* interface checkcast code */
3204 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3205 if (super != NULL) {
3210 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3212 if (super == NULL) {
3213 codegen_addpatchref(cd,
3214 PATCHER_checkcast_instanceof_interface,
3215 iptr->sx.s23.s3.c.ref,
3218 if (opt_showdisassemble) {
3219 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3223 emit_movl_membase32_reg(cd, REG_ITMP2,
3224 OFFSET(vftbl_t, interfacetablelength),
3226 /* XXX TWISTI: should this be int arithmetic? */
3227 M_LSUB_IMM32(superindex, REG_ITMP3);
3230 codegen_add_classcastexception_ref(cd, s1);
3231 emit_mov_membase32_reg(cd, REG_ITMP2,
3232 OFFSET(vftbl_t, interfacetable[0]) -
3233 superindex * sizeof(methodptr*),
3237 codegen_add_classcastexception_ref(cd, s1);
3243 /* class checkcast code */
3245 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3246 if (super != NULL) {
3251 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3253 if (super == NULL) {
3254 codegen_addpatchref(cd, PATCHER_checkcast_class,
3255 iptr->sx.s23.s3.c.ref,
3258 if (opt_showdisassemble) {
3259 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3263 M_MOV_IMM(supervftbl, REG_ITMP3);
3264 #if defined(ENABLE_THREADS)
3265 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3267 emit_movl_membase32_reg(cd, REG_ITMP2,
3268 OFFSET(vftbl_t, baseval),
3270 /* if (s1 != REG_ITMP1) { */
3271 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3272 /* OFFSET(vftbl_t, baseval), */
3274 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3275 /* OFFSET(vftbl_t, diffval), */
3277 /* #if defined(ENABLE_THREADS) */
3278 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3280 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3283 emit_movl_membase32_reg(cd, REG_ITMP3,
3284 OFFSET(vftbl_t, baseval),
3286 M_LSUB(REG_ITMP3, REG_ITMP2);
3287 M_MOV_IMM(supervftbl, REG_ITMP3);
3288 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3290 #if defined(ENABLE_THREADS)
3291 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3293 M_LCMP(REG_ITMP3, REG_ITMP2);
3294 M_BA(0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
3295 codegen_add_classcastexception_ref(cd, s1);
3298 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3301 /* array type cast-check */
3303 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3304 M_INTMOVE(s1, REG_A0);
3306 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3307 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3308 iptr->sx.s23.s3.c.ref, 0);
3310 if (opt_showdisassemble) {
3311 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3315 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3316 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
3319 /* s1 may have been destroyed over the function call */
3320 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3323 codegen_add_classcastexception_ref(cd, s1);
3325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3329 emit_store_dst(jd, iptr, d);
3332 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3334 /* val.a: (classinfo *) superclass */
3336 /* superclass is an interface:
3338 * return (sub != NULL) &&
3339 * (sub->vftbl->interfacetablelength > super->index) &&
3340 * (sub->vftbl->interfacetable[-super->index] != NULL);
3342 * superclass is a class:
3344 * return ((sub != NULL) && (0
3345 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3346 * super->vftbl->diffvall));
3351 vftbl_t *supervftbl;
3354 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3360 super = iptr->sx.s23.s3.c.cls;
3361 superindex = super->index;
3362 supervftbl = super->vftbl;
3365 #if defined(ENABLE_THREADS)
3366 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3372 M_INTMOVE(s1, REG_ITMP1);
3376 /* calculate interface instanceof code size */
3378 s2 = 3; /* mov_membase_reg */
3379 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3380 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub_imm32 */ +
3381 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3382 3 /* test */ + 4 /* setcc */;
3385 s2 += (opt_showdisassemble ? 5 : 0);
3387 /* calculate class instanceof code size */
3389 s3 = 3; /* mov_membase_reg */
3390 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3391 s3 += 10; /* mov_imm_reg */
3392 s3 += 2; /* movl_membase_reg - only if REG_ITMP1 == RAX */
3393 CALCOFFSETBYTES(s3, REG_ITMP1, OFFSET(vftbl_t, baseval));
3394 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
3395 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3396 s3 += 3; /* movl_membase_reg - only if REG_ITMP2 == R10 */
3397 CALCOFFSETBYTES(s3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3398 s3 += 3 /* sub */ + 3 /* xor */ + 3 /* cmp */ + 4 /* setcc */;
3401 s3 += (opt_showdisassemble ? 5 : 0);
3403 emit_alu_reg_reg(cd, ALU_XOR, d, d);
3405 /* if class is not resolved, check which code to call */
3408 emit_test_reg_reg(cd, s1, s1);
3409 emit_jcc(cd, CC_Z, (6 + (opt_showdisassemble ? 5 : 0) +
3410 7 + 6 + s2 + 5 + s3));
3412 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3413 iptr->sx.s23.s3.c.ref, 0);
3415 if (opt_showdisassemble) {
3416 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3419 emit_movl_imm_reg(cd, 0, REG_ITMP3); /* super->flags */
3420 emit_alul_imm_reg(cd, ALU_AND, ACC_INTERFACE, REG_ITMP3);
3421 emit_jcc(cd, CC_Z, s2 + 5);
3424 /* interface instanceof code */
3426 if (!super || (super->flags & ACC_INTERFACE)) {
3428 emit_test_reg_reg(cd, s1, s1);
3429 emit_jcc(cd, CC_Z, s2);
3432 emit_mov_membase_reg(cd, s1,
3433 OFFSET(java_objectheader, vftbl),
3436 codegen_addpatchref(cd,
3437 PATCHER_checkcast_instanceof_interface,
3438 iptr->sx.s23.s3.c.ref, 0);
3440 if (opt_showdisassemble) {
3441 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3445 emit_movl_membase32_reg(cd, REG_ITMP1,
3446 OFFSET(vftbl_t, interfacetablelength),
3448 emit_alu_imm32_reg(cd, ALU_SUB, superindex, REG_ITMP3);
3449 emit_test_reg_reg(cd, REG_ITMP3, REG_ITMP3);
3451 a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
3453 emit_jcc(cd, CC_LE, a);
3454 emit_mov_membase32_reg(cd, REG_ITMP1,
3455 OFFSET(vftbl_t, interfacetable[0]) -
3456 superindex * sizeof(methodptr*),
3458 emit_test_reg_reg(cd, REG_ITMP1, REG_ITMP1);
3459 emit_setcc_reg(cd, CC_NE, d);
3462 emit_jmp_imm(cd, s3);
3465 /* class instanceof code */
3467 if (!super || !(super->flags & ACC_INTERFACE)) {
3469 emit_test_reg_reg(cd, s1, s1);
3470 emit_jcc(cd, CC_E, s3);
3473 emit_mov_membase_reg(cd, s1,
3474 OFFSET(java_objectheader, vftbl),
3478 codegen_addpatchref(cd, PATCHER_instanceof_class,
3479 iptr->sx.s23.s3.c.ref, 0);
3481 if (opt_showdisassemble) {
3482 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3486 emit_mov_imm_reg(cd, (ptrint) supervftbl, REG_ITMP2);
3487 #if defined(ENABLE_THREADS)
3488 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3490 emit_movl_membase_reg(cd, REG_ITMP1,
3491 OFFSET(vftbl_t, baseval),
3493 emit_movl_membase_reg(cd, REG_ITMP2,
3494 OFFSET(vftbl_t, diffval),
3496 emit_movl_membase_reg(cd, REG_ITMP2,
3497 OFFSET(vftbl_t, baseval),
3499 #if defined(ENABLE_THREADS)
3500 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3502 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
3503 emit_alu_reg_reg(cd, ALU_XOR, d, d); /* may be REG_ITMP2 */
3504 emit_alu_reg_reg(cd, ALU_CMP, REG_ITMP3, REG_ITMP1);
3505 emit_setcc_reg(cd, CC_BE, d);
3507 emit_store_dst(jd, iptr, d);
3511 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3513 /* check for negative sizes and copy sizes to stack if necessary */
3515 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3517 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3519 src = iptr->sx.s23.s2.args[s1];
3521 /* copy SAVEDVAR sizes to stack */
3523 if (src->varkind != ARGVAR) {
3524 s2 = emit_load(jd, iptr, src, REG_ITMP1);
3525 M_LST(s2, REG_SP, s1 * 8);
3529 /* is a patcher function set? */
3531 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3532 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3533 iptr->sx.s23.s3.c.ref, 0);
3535 if (opt_showdisassemble) {
3536 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3540 /* a0 = dimension count */
3542 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3544 /* a1 = classinfo */
3546 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3548 /* a2 = pointer to dimensions = stack pointer */
3550 M_MOV(REG_SP, REG_A2);
3552 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3555 /* check for exception before result assignment */
3559 codegen_add_fillinstacktrace_ref(cd);
3561 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3562 M_INTMOVE(REG_RESULT, s1);
3563 emit_store_dst(jd, iptr, s1);
3567 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3571 } /* for instruction */
3573 /* copy values to interface registers */
3575 len = bptr->outdepth;
3577 #if defined(ENABLE_LSRA)
3582 src = bptr->outvars[len];
3583 if ((src->varkind != STACKVAR)) {
3585 if (IS_FLT_DBL_TYPE(s2)) {
3586 s1 = emit_load(jd, iptr, src, REG_FTMP1);
3587 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3588 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
3591 emit_movq_reg_membase(cd, s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3595 s1 = emit_load(jd, iptr, src, REG_ITMP1);
3596 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3597 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3600 emit_mov_reg_membase(cd, s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3606 /* At the end of a basic block we may have to append some nops,
3607 because the patcher stub calling code might be longer than the
3608 actual instruction. So codepatching does not change the
3609 following block unintentionally. */
3611 if (cd->mcodeptr < cd->lastmcodeptr) {
3612 while (cd->mcodeptr < cd->lastmcodeptr) {
3617 } /* if (bptr -> flags >= BBREACHED) */
3618 } /* for basic block */
3620 dseg_createlinenumbertable(cd);
3622 /* generate stubs */
3624 emit_exception_stubs(jd);
3625 emit_patcher_stubs(jd);
3627 emit_replacement_stubs(jd);
3632 /* everything's ok */
3638 /* createcompilerstub **********************************************************
3640 Creates a stub routine which calls the compiler.
3642 *******************************************************************************/
3644 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3645 #define COMPILERSTUB_CODESIZE 7 + 7 + 3
3647 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3650 u1 *createcompilerstub(methodinfo *m)
3652 u1 *s; /* memory to hold the stub */
3658 s = CNEW(u1, COMPILERSTUB_SIZE);
3660 /* set data pointer and code pointer */
3663 s = s + COMPILERSTUB_DATASIZE;
3665 /* mark start of dump memory area */
3667 dumpsize = dump_size();
3669 cd = DNEW(codegendata);
3672 /* Store the codeinfo pointer in the same place as in the
3673 methodheader for compiled methods. */
3675 code = code_codeinfo_new(m);
3677 d[0] = (ptrint) asm_call_jit_compiler;
3679 d[2] = (ptrint) code;
3681 /* code for the stub */
3683 M_ALD(REG_ITMP1, RIP, -(7 * 1 + 2 * SIZEOF_VOID_P)); /* methodinfo */
3684 M_ALD(REG_ITMP3, RIP, -(7 * 2 + 3 * SIZEOF_VOID_P)); /* compiler pointer */
3687 #if defined(ENABLE_STATISTICS)
3689 count_cstub_len += COMPILERSTUB_SIZE;
3692 /* release dump area */
3694 dump_release(dumpsize);
3700 /* createnativestub ************************************************************
3702 Creates a stub routine which calls a native method.
3704 *******************************************************************************/
3706 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3714 s4 i, j; /* count variables */
3718 /* get required compiler data */
3725 /* initialize variables */
3728 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3730 /* calculate stack frame size */
3732 cd->stackframesize =
3733 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3734 sizeof(localref_table) / SIZEOF_VOID_P +
3735 INT_ARG_CNT + FLT_ARG_CNT +
3736 1 + /* functionptr, TODO: store in data segment */
3739 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3741 /* create method header */
3743 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3744 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3745 (void) dseg_adds4(cd, 0); /* IsSync */
3746 (void) dseg_adds4(cd, 0); /* IsLeaf */
3747 (void) dseg_adds4(cd, 0); /* IntSave */
3748 (void) dseg_adds4(cd, 0); /* FltSave */
3749 (void) dseg_addlinenumbertablesize(cd);
3750 (void) dseg_adds4(cd, 0); /* ExTableSize */
3752 /* generate native method profiling code */
3754 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3755 /* count frequency */
3757 M_MOV_IMM(code, REG_ITMP3);
3758 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3761 /* generate stub code */
3763 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3765 #if !defined(NDEBUG)
3766 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3767 emit_verbosecall_enter(jd);
3770 /* get function address (this must happen before the stackframeinfo) */
3772 #if !defined(WITH_STATIC_CLASSPATH)
3774 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
3776 if (opt_showdisassemble) {
3777 M_NOP; M_NOP; M_NOP; M_NOP; M_NOP;
3782 M_MOV_IMM(f, REG_ITMP3);
3785 /* save integer and float argument registers */
3787 for (i = 0, j = 0; i < md->paramcount; i++) {
3788 if (!md->params[i].inmemory) {
3789 s1 = md->params[i].regoff;
3791 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3792 M_LST(rd->argintregs[s1], REG_SP, j * 8);
3794 M_DST(rd->argfltregs[s1], REG_SP, j * 8);
3800 M_AST(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3802 /* create dynamic stack info */
3804 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3805 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
3806 M_ALEA(REG_SP, cd->stackframesize * 8 + SIZEOF_VOID_P, REG_A2);
3807 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8);
3808 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3811 /* restore integer and float argument registers */
3813 for (i = 0, j = 0; i < md->paramcount; i++) {
3814 if (!md->params[i].inmemory) {
3815 s1 = md->params[i].regoff;
3817 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3818 M_LLD(rd->argintregs[s1], REG_SP, j * 8);
3820 M_DLD(rd->argfltregs[s1], REG_SP, j * 8);
3826 M_ALD(REG_ITMP3, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
3829 /* copy or spill arguments to new locations */
3831 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3832 t = md->paramtypes[i].type;
3834 if (IS_INT_LNG_TYPE(t)) {
3835 if (!md->params[i].inmemory) {
3836 s1 = rd->argintregs[md->params[i].regoff];
3838 if (!nmd->params[j].inmemory) {
3839 s2 = rd->argintregs[nmd->params[j].regoff];
3843 s2 = nmd->params[j].regoff;
3844 M_LST(s1, REG_SP, s2 * 8);
3848 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3849 s2 = nmd->params[j].regoff;
3850 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3851 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3855 /* We only copy spilled float arguments, as the float argument */
3856 /* registers keep unchanged. */
3858 if (md->params[i].inmemory) {
3859 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3860 s2 = nmd->params[j].regoff;
3862 if (IS_2_WORD_TYPE(t)) {
3863 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3864 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3866 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3867 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3873 /* put class into second argument register */
3875 if (m->flags & ACC_STATIC)
3876 M_MOV_IMM(m->class, REG_A1);
3878 /* put env into first argument register */
3880 M_MOV_IMM(_Jv_env, REG_A0);
3882 /* do the native function call */
3886 /* save return value */
3888 if (md->returntype.type != TYPE_VOID) {
3889 if (IS_INT_LNG_TYPE(md->returntype.type))
3890 M_LST(REG_RESULT, REG_SP, 0 * 8);
3892 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3895 #if !defined(NDEBUG)
3896 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3897 emit_verbosecall_exit(jd);
3900 /* remove native stackframe info */
3902 M_ALEA(REG_SP, cd->stackframesize * 8, REG_A0);
3903 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3905 M_MOV(REG_RESULT, REG_ITMP3);
3907 /* restore return value */
3909 if (md->returntype.type != TYPE_VOID) {
3910 if (IS_INT_LNG_TYPE(md->returntype.type))
3911 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3913 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3916 /* remove stackframe */
3918 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3920 /* test for exception */
3926 /* handle exception */
3928 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3929 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
3930 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3932 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3935 /* generate patcher stubs */
3937 emit_patcher_stubs(jd);
3941 return code->entrypoint;
3946 * These are local overrides for various environment variables in Emacs.
3947 * Please do not remove this and leave it at the end of the file, where
3948 * Emacs will automagically detect them.
3949 * ---------------------------------------------------------------------
3952 * indent-tabs-mode: t
3956 * vim:noexpandtab:sw=4:ts=4: