1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "vm/jit/x86_64/arch.h"
38 #include "vm/jit/x86_64/codegen.h"
39 #include "vm/jit/x86_64/emit.h"
41 #include "mm/memory.hpp"
43 #include "native/localref.hpp"
44 #include "native/native.hpp"
46 #include "threads/lock.hpp"
48 #include "vm/jit/builtin.hpp"
49 #include "vm/exceptions.hpp"
50 #include "vm/global.h"
51 #include "vm/loader.hpp"
52 #include "vm/options.h"
53 #include "vm/primitive.hpp"
54 #include "vm/statistics.h"
55 #include "vm/string.hpp"
58 #include "vm/jit/abi.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/code.hpp"
61 #include "vm/jit/codegen-common.hpp"
62 #include "vm/jit/dseg.h"
63 #include "vm/jit/emit-common.hpp"
64 #include "vm/jit/jit.hpp"
65 #include "vm/jit/linenumbertable.hpp"
66 #include "vm/jit/methodheader.h"
67 #include "vm/jit/parse.hpp"
68 #include "vm/jit/patcher-common.hpp"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/stacktrace.hpp"
71 #include "vm/jit/trap.hpp"
75 * Generates machine code for the method prolog.
77 void codegen_emit_prolog(jitdata* jd)
86 // Get required compiler data.
87 methodinfo* m = jd->m;
88 codegendata* cd = jd->cd;
89 registerdata* rd = jd->rd;
91 /* create stack frame (if necessary) */
93 if (cd->stackframesize)
94 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
96 /* save used callee saved registers */
98 p = cd->stackframesize;
99 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
100 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
102 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
103 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
106 /* take arguments out of register or stack frame */
110 for (p = 0, l = 0; p < md->paramcount; p++) {
111 t = md->paramtypes[p].type;
113 varindex = jd->local_map[l * 5 + t];
116 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
119 if (varindex == UNUSED)
124 s1 = md->params[p].regoff;
126 if (IS_INT_LNG_TYPE(t)) { /* integer args */
127 if (!md->params[p].inmemory) { /* register arguments */
128 if (!IS_INMEMORY(var->flags))
129 M_INTMOVE(s1, var->vv.regoff);
131 M_LST(s1, REG_SP, var->vv.regoff);
133 else { /* stack arguments */
134 if (!IS_INMEMORY(var->flags))
135 /* + 8 for return address */
136 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
138 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
141 else { /* floating args */
142 if (!md->params[p].inmemory) { /* register arguments */
143 if (!IS_INMEMORY(var->flags))
144 emit_fmove(cd, s1, var->vv.regoff);
146 M_DST(s1, REG_SP, var->vv.regoff);
148 else { /* stack arguments */
149 if (!IS_INMEMORY(var->flags))
150 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1 + 8);
152 var->vv.regoff = cd->stackframesize * 8 + s1 + 8;
160 * Generates machine code for the method epilog.
162 void codegen_emit_epilog(jitdata* jd)
167 // Get required compiler data.
168 codegendata* cd = jd->cd;
169 registerdata* rd = jd->rd;
171 p = cd->stackframesize;
173 /* restore saved registers */
175 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
176 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
178 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
179 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
182 /* deallocate stack */
184 if (cd->stackframesize)
185 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
191 * Generates a memory barrier to be used after volatile writes. It can be
192 * patched out later if the field turns out not to be volatile.
194 void codegen_emit_patchable_barrier(instruction *iptr, codegendata *cd, patchref_t *pr, fieldinfo *fi)
196 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
197 /* Align on word boundary */
198 if ((((intptr_t) cd->mcodeptr) & 3) >= 2)
199 emit_nop(cd, 4 - (((intptr_t) cd->mcodeptr) & 3));
200 /* Displacement for patching out MFENCE */
201 pr->disp_mb = (cd->mcodeptr - cd->mcodebase - pr->mpc);
203 if (INSTRUCTION_IS_UNRESOLVED(iptr) || fi->flags & ACC_VOLATILE)
208 * Generates machine code for one ICMD.
210 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
214 builtintable_entry* bte;
215 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
216 unresolved_method* um;
218 unresolved_field* uf;
221 int32_t s1, s2, s3, d;
224 // Get required compiler data.
225 codegendata* cd = jd->cd;
229 /* constant operations ************************************************/
231 case ICMD_FCONST: /* ... ==> ..., constant */
233 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
234 disp = dseg_add_float(cd, iptr->sx.val.f);
235 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
236 emit_store_dst(jd, iptr, d);
239 case ICMD_DCONST: /* ... ==> ..., constant */
241 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
242 disp = dseg_add_double(cd, iptr->sx.val.d);
243 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
244 emit_store_dst(jd, iptr, d);
247 case ICMD_ACONST: /* ... ==> ..., constant */
249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
251 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
252 constant_classref *cr = iptr->sx.val.c.ref;
253 disp = dseg_add_unique_address(cd, cr);
255 /* PROFILE_CYCLE_STOP; */
257 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
260 /* PROFILE_CYCLE_START; */
265 if (iptr->sx.val.anyptr == 0) {
269 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
273 emit_store_dst(jd, iptr, d);
277 /* integer operations *************************************************/
279 case ICMD_INEG: /* ..., value ==> ..., - value */
281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
282 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
285 emit_store_dst(jd, iptr, d);
288 case ICMD_LNEG: /* ..., value ==> ..., - value */
290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
291 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
294 emit_store_dst(jd, iptr, d);
297 case ICMD_I2L: /* ..., value ==> ..., value */
299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
302 emit_store_dst(jd, iptr, d);
305 case ICMD_L2I: /* ..., value ==> ..., value */
307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
308 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
310 emit_store_dst(jd, iptr, d);
313 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
318 emit_store_dst(jd, iptr, d);
321 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
324 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
326 emit_store_dst(jd, iptr, d);
329 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
331 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
332 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
334 emit_store_dst(jd, iptr, d);
338 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
342 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
349 emit_store_dst(jd, iptr, d);
353 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
354 /* sx.val.i = constant */
356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
357 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
359 /* Using inc and dec is not faster than add (tested with
363 M_IADD_IMM(iptr->sx.val.i, d);
364 emit_store_dst(jd, iptr, d);
367 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
370 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
371 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
378 emit_store_dst(jd, iptr, d);
381 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
382 /* sx.val.l = constant */
384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
387 if (IS_IMM32(iptr->sx.val.l))
388 M_LADD_IMM(iptr->sx.val.l, d);
390 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
391 M_LADD(REG_ITMP2, d);
393 emit_store_dst(jd, iptr, d);
396 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
399 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
402 M_INTMOVE(s1, REG_ITMP1);
403 M_ISUB(s2, REG_ITMP1);
404 M_INTMOVE(REG_ITMP1, d);
409 emit_store_dst(jd, iptr, d);
412 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
413 /* sx.val.i = constant */
415 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
416 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
418 M_ISUB_IMM(iptr->sx.val.i, d);
419 emit_store_dst(jd, iptr, d);
422 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
425 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
428 M_INTMOVE(s1, REG_ITMP1);
429 M_LSUB(s2, REG_ITMP1);
430 M_INTMOVE(REG_ITMP1, d);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
439 /* sx.val.l = constant */
441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
444 if (IS_IMM32(iptr->sx.val.l))
445 M_LSUB_IMM(iptr->sx.val.l, d);
447 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
448 M_LSUB(REG_ITMP2, d);
450 emit_store_dst(jd, iptr, d);
453 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
464 emit_store_dst(jd, iptr, d);
467 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
468 /* sx.val.i = constant */
470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
472 if (iptr->sx.val.i == 2) {
476 M_IMUL_IMM(s1, iptr->sx.val.i, d);
477 emit_store_dst(jd, iptr, d);
480 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
484 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
491 emit_store_dst(jd, iptr, d);
494 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
495 /* sx.val.l = constant */
497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
499 if (IS_IMM32(iptr->sx.val.l))
500 M_LMUL_IMM(s1, iptr->sx.val.l, d);
502 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
504 M_LMUL(REG_ITMP2, d);
506 emit_store_dst(jd, iptr, d);
509 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
511 s1 = emit_load_s1(jd, iptr, RAX);
512 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
513 d = codegen_reg_of_dst(jd, iptr, RAX);
516 M_INTMOVE(s2, REG_ITMP3);
517 emit_arithmetic_check(cd, iptr, REG_ITMP3);
519 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
521 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
523 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
524 M_BEQ(1 + 3); /* 6 bytes */
526 emit_cltd(cd); /* 1 byte */
527 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
530 emit_store_dst(jd, iptr, d);
531 dst = VAROP(iptr->dst);
532 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
533 M_MOV(REG_ITMP2, RDX); /* restore RDX */
536 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
538 s1 = emit_load_s1(jd, iptr, RAX);
539 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
540 d = codegen_reg_of_dst(jd, iptr, RDX);
543 M_INTMOVE(s2, REG_ITMP3);
544 emit_arithmetic_check(cd, iptr, REG_ITMP3);
546 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
548 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
550 M_CLR(RDX); /* 3 bytes */
551 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
552 M_BEQ(1 + 3); /* 6 bytes */
554 emit_cltd(cd); /* 1 byte */
555 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
558 emit_store_dst(jd, iptr, d);
559 dst = VAROP(iptr->dst);
560 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
561 M_MOV(REG_ITMP2, RDX); /* restore RDX */
564 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
565 /* sx.val.i = constant */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
569 M_INTMOVE(s1, REG_ITMP1);
570 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
571 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
572 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
573 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
574 emit_mov_reg_reg(cd, REG_ITMP1, d);
575 emit_store_dst(jd, iptr, d);
578 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
579 /* sx.val.i = constant */
581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
583 M_INTMOVE(s1, REG_ITMP1);
584 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
585 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
586 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
587 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
588 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
589 emit_mov_reg_reg(cd, REG_ITMP1, d);
590 emit_store_dst(jd, iptr, d);
594 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
596 s1 = emit_load_s1(jd, iptr, RAX);
597 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
598 d = codegen_reg_of_dst(jd, iptr, RAX);
601 M_INTMOVE(s2, REG_ITMP3);
602 emit_arithmetic_check(cd, iptr, REG_ITMP3);
604 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
606 /* check as described in jvm spec */
607 disp = dseg_add_s8(cd, 0x8000000000000000LL);
608 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
610 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
611 M_BEQ(2 + 3); /* 6 bytes */
613 emit_cqto(cd); /* 2 bytes */
614 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
617 emit_store_dst(jd, iptr, d);
618 dst = VAROP(iptr->dst);
619 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
620 M_MOV(REG_ITMP2, RDX); /* restore RDX */
623 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
625 s1 = emit_load_s1(jd, iptr, RAX);
626 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
627 d = codegen_reg_of_dst(jd, iptr, RDX);
630 M_INTMOVE(s2, REG_ITMP3);
631 emit_arithmetic_check(cd, iptr, REG_ITMP3);
633 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
635 /* check as described in jvm spec */
636 disp = dseg_add_s8(cd, 0x8000000000000000LL);
637 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
639 M_LXOR(RDX, RDX); /* 3 bytes */
640 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
641 M_BEQ(2 + 3); /* 6 bytes */
643 emit_cqto(cd); /* 2 bytes */
644 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
647 emit_store_dst(jd, iptr, d);
648 dst = VAROP(iptr->dst);
649 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
650 M_MOV(REG_ITMP2, RDX); /* restore RDX */
653 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
654 /* sx.val.i = constant */
656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
658 M_INTMOVE(s1, REG_ITMP1);
659 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
660 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
661 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
662 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
663 emit_mov_reg_reg(cd, REG_ITMP1, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
668 /* sx.val.l = constant */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
672 M_INTMOVE(s1, REG_ITMP1);
673 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
674 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
675 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
676 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
677 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
678 emit_mov_reg_reg(cd, REG_ITMP1, d);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
684 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
685 emit_ishift(jd, SHIFT_SHL, iptr);
688 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
689 /* sx.val.i = constant */
691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
694 M_ISLL_IMM(iptr->sx.val.i, d);
695 emit_store_dst(jd, iptr, d);
698 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
700 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
701 emit_ishift(jd, SHIFT_SAR, iptr);
704 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
705 /* sx.val.i = constant */
707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710 M_ISRA_IMM(iptr->sx.val.i, d);
711 emit_store_dst(jd, iptr, d);
714 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
716 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
717 emit_ishift(jd, SHIFT_SHR, iptr);
720 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
721 /* sx.val.i = constant */
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
726 M_ISRL_IMM(iptr->sx.val.i, d);
727 emit_store_dst(jd, iptr, d);
730 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
732 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
733 emit_lshift(jd, SHIFT_SHL, iptr);
736 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
737 /* sx.val.i = constant */
739 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
742 M_LSLL_IMM(iptr->sx.val.i, d);
743 emit_store_dst(jd, iptr, d);
746 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
748 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
749 emit_lshift(jd, SHIFT_SAR, iptr);
752 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
753 /* sx.val.i = constant */
755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
758 M_LSRA_IMM(iptr->sx.val.i, d);
759 emit_store_dst(jd, iptr, d);
762 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
764 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
765 emit_lshift(jd, SHIFT_SHR, iptr);
768 case ICMD_LUSHRCONST: /* ..., 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_ITMP2);
774 M_LSRL_IMM(iptr->sx.val.i, d);
775 emit_store_dst(jd, iptr, d);
778 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
789 emit_store_dst(jd, iptr, d);
792 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
793 /* sx.val.i = constant */
795 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
798 M_IAND_IMM(iptr->sx.val.i, d);
799 emit_store_dst(jd, iptr, d);
802 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
817 /* sx.val.l = constant */
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
822 if (IS_IMM32(iptr->sx.val.l))
823 M_LAND_IMM(iptr->sx.val.l, d);
825 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
826 M_LAND(REG_ITMP2, d);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
834 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
846 /* sx.val.i = constant */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
851 M_IOR_IMM(iptr->sx.val.i, d);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 emit_store_dst(jd, iptr, d);
869 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
870 /* sx.val.l = constant */
872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
875 if (IS_IMM32(iptr->sx.val.l))
876 M_LOR_IMM(iptr->sx.val.l, d);
878 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
881 emit_store_dst(jd, iptr, d);
884 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895 emit_store_dst(jd, iptr, d);
898 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
899 /* sx.val.i = constant */
901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
902 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
904 M_IXOR_IMM(iptr->sx.val.i, d);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
919 emit_store_dst(jd, iptr, d);
922 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
923 /* sx.val.l = constant */
925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
928 if (IS_IMM32(iptr->sx.val.l))
929 M_LXOR_IMM(iptr->sx.val.l, d);
931 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
932 M_LXOR(REG_ITMP2, d);
934 emit_store_dst(jd, iptr, d);
938 /* floating operations ************************************************/
940 case ICMD_FNEG: /* ..., value ==> ..., - value */
942 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
943 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
944 disp = dseg_add_s4(cd, 0x80000000);
945 emit_fmove(cd, s1, d);
946 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
947 emit_xorps_reg_reg(cd, REG_FTMP2, d);
948 emit_store_dst(jd, iptr, d);
951 case ICMD_DNEG: /* ..., value ==> ..., - value */
953 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
954 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
955 disp = dseg_add_s8(cd, 0x8000000000000000);
956 emit_fmove(cd, s1, d);
957 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
958 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
959 emit_store_dst(jd, iptr, d);
962 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
964 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
965 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
966 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
970 emit_fmove(cd, s1, d);
973 emit_store_dst(jd, iptr, d);
976 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
978 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
979 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
980 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
984 emit_fmove(cd, s1, d);
987 emit_store_dst(jd, iptr, d);
990 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
992 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
993 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
994 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
996 emit_fmove(cd, s2, REG_FTMP2);
999 emit_fmove(cd, s1, d);
1001 emit_store_dst(jd, iptr, d);
1004 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1006 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1007 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1008 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1010 emit_fmove(cd, s2, REG_FTMP2);
1013 emit_fmove(cd, s1, d);
1015 emit_store_dst(jd, iptr, d);
1018 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1020 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1021 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1022 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1026 emit_fmove(cd, s1, d);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1034 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1035 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1036 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1040 emit_fmove(cd, s1, d);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1048 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1049 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1050 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1052 emit_fmove(cd, s2, REG_FTMP2);
1055 emit_fmove(cd, s1, d);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1062 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1063 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1064 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1066 emit_fmove(cd, s2, REG_FTMP2);
1069 emit_fmove(cd, s1, d);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1077 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1085 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1093 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1103 emit_store_dst(jd, iptr, d);
1106 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1108 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1109 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1111 M_ICMP_IMM(0x80000000, d); /* corner cases */
1112 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1113 ((REG_RESULT == d) ? 0 : 3);
1115 emit_fmove(cd, s1, REG_FTMP1);
1116 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1118 M_INTMOVE(REG_RESULT, d);
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1124 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1125 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1127 M_ICMP_IMM(0x80000000, d); /* corner cases */
1128 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1129 ((REG_RESULT == d) ? 0 : 3);
1131 emit_fmove(cd, s1, REG_FTMP1);
1132 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1134 M_INTMOVE(REG_RESULT, d);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1140 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1143 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1144 M_LCMP(REG_ITMP2, d); /* corner cases */
1145 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1146 ((REG_RESULT == d) ? 0 : 3);
1148 emit_fmove(cd, s1, REG_FTMP1);
1149 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1151 M_INTMOVE(REG_RESULT, d);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1160 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1161 M_LCMP(REG_ITMP2, d); /* corner cases */
1162 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1163 ((REG_RESULT == d) ? 0 : 3);
1165 emit_fmove(cd, s1, REG_FTMP1);
1166 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1168 M_INTMOVE(REG_RESULT, d);
1169 emit_store_dst(jd, iptr, d);
1172 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1174 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1175 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1177 emit_store_dst(jd, iptr, d);
1180 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1182 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1183 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1185 emit_store_dst(jd, iptr, d);
1188 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1189 /* == => 0, < => 1, > => -1 */
1191 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1192 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1193 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1195 M_MOV_IMM(1, REG_ITMP1);
1196 M_MOV_IMM(-1, REG_ITMP2);
1197 emit_ucomiss_reg_reg(cd, s1, s2);
1198 M_CMOVULT(REG_ITMP1, d);
1199 M_CMOVUGT(REG_ITMP2, d);
1200 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1201 emit_store_dst(jd, iptr, d);
1204 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1205 /* == => 0, < => 1, > => -1 */
1207 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1208 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1209 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1211 M_MOV_IMM(1, REG_ITMP1);
1212 M_MOV_IMM(-1, REG_ITMP2);
1213 emit_ucomiss_reg_reg(cd, s1, s2);
1214 M_CMOVULT(REG_ITMP1, d);
1215 M_CMOVUGT(REG_ITMP2, d);
1216 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1221 /* == => 0, < => 1, > => -1 */
1223 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1224 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1225 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1227 M_MOV_IMM(1, REG_ITMP1);
1228 M_MOV_IMM(-1, REG_ITMP2);
1229 emit_ucomisd_reg_reg(cd, s1, s2);
1230 M_CMOVULT(REG_ITMP1, d);
1231 M_CMOVUGT(REG_ITMP2, d);
1232 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1233 emit_store_dst(jd, iptr, d);
1236 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1237 /* == => 0, < => 1, > => -1 */
1239 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1240 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1241 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1243 M_MOV_IMM(1, REG_ITMP1);
1244 M_MOV_IMM(-1, REG_ITMP2);
1245 emit_ucomisd_reg_reg(cd, s1, s2);
1246 M_CMOVULT(REG_ITMP1, d);
1247 M_CMOVUGT(REG_ITMP2, d);
1248 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1249 emit_store_dst(jd, iptr, d);
1253 /* memory operations **************************************************/
1255 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1257 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1258 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1259 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1260 /* implicit null-pointer check */
1261 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1262 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1269 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1270 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1271 /* implicit null-pointer check */
1272 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1273 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1274 emit_store_dst(jd, iptr, d);
1277 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1279 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1280 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1281 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1282 /* implicit null-pointer check */
1283 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1284 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1285 emit_store_dst(jd, iptr, d);
1288 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1291 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1293 /* implicit null-pointer check */
1294 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1295 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1301 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1302 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1304 /* implicit null-pointer check */
1305 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1306 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1313 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1314 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1315 /* implicit null-pointer check */
1316 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1317 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1326 /* implicit null-pointer check */
1327 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1328 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1329 emit_store_dst(jd, iptr, d);
1332 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1337 /* implicit null-pointer check */
1338 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1339 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1340 emit_store_dst(jd, iptr, d);
1344 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1347 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1348 /* implicit null-pointer check */
1349 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1350 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1351 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1354 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1357 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1358 /* implicit null-pointer check */
1359 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1360 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1361 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1364 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1368 /* implicit null-pointer check */
1369 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1370 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1371 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1374 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1377 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1378 /* implicit null-pointer check */
1379 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1380 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1381 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1384 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1387 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1388 /* implicit null-pointer check */
1389 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1390 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1391 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1394 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1396 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398 /* implicit null-pointer check */
1399 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1400 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1401 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1404 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1407 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1408 /* implicit null-pointer check */
1409 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1410 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1411 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1414 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1417 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1418 /* implicit null-pointer check */
1419 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1420 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1424 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1426 emit_arraystore_check(cd, iptr);
1428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1431 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1435 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1438 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1439 /* implicit null-pointer check */
1440 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1441 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1444 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1447 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1448 /* implicit null-pointer check */
1449 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1450 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1453 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1457 /* implicit null-pointer check */
1458 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1459 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1462 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1464 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1465 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1466 /* implicit null-pointer check */
1467 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1468 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1471 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1473 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1475 /* implicit null-pointer check */
1476 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1478 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1479 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1482 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1483 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1487 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1491 /* implicit null-pointer check */
1492 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1493 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1496 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1497 /* val = value (in current instruction) */
1498 /* following NOP) */
1500 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1501 uf = iptr->sx.s23.s3.uf;
1502 fieldtype = uf->fieldref->parseddesc.fd->type;
1503 disp = dseg_add_unique_address(cd, uf);
1505 /* PROFILE_CYCLE_STOP; */
1507 pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1509 /* PROFILE_CYCLE_START; */
1512 fi = iptr->sx.s23.s3.fmiref->p.field;
1513 fieldtype = fi->type;
1514 disp = dseg_add_address(cd, fi->value);
1516 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1517 //PROFILE_CYCLE_STOP;
1519 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1522 //PROFILE_CYCLE_START;
1526 /* This approach is much faster than moving the field
1527 address inline into a register. */
1529 M_ALD(REG_ITMP1, RIP, disp);
1531 switch (fieldtype) {
1534 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1539 if (IS_IMM32(iptr->sx.s23.s2.constval))
1540 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1542 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1543 M_LST(REG_ITMP2, REG_ITMP1, 0);
1547 codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1550 case ICMD_GETFIELD: /* ... ==> ..., value */
1552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1554 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1555 uf = iptr->sx.s23.s3.uf;
1556 fieldtype = uf->fieldref->parseddesc.fd->type;
1559 /* PROFILE_CYCLE_STOP; */
1561 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1563 /* PROFILE_CYCLE_START; */
1566 fi = iptr->sx.s23.s3.fmiref->p.field;
1567 fieldtype = fi->type;
1571 /* implicit null-pointer check */
1572 switch (fieldtype) {
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1575 M_ILD32(d, s1, disp);
1579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1580 M_LLD32(d, s1, disp);
1583 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1584 M_FLD32(d, s1, disp);
1587 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1588 M_DLD32(d, s1, disp);
1591 emit_store_dst(jd, iptr, d);
1594 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1597 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1599 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1600 uf = iptr->sx.s23.s3.uf;
1601 fieldtype = uf->fieldref->parseddesc.fd->type;
1604 /* PROFILE_CYCLE_STOP; */
1606 pr = patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1608 /* PROFILE_CYCLE_START; */
1611 fi = iptr->sx.s23.s3.fmiref->p.field;
1612 fieldtype = fi->type;
1616 /* implicit null-pointer check */
1617 switch (fieldtype) {
1619 M_IST32(s2, s1, disp);
1623 M_LST32(s2, s1, disp);
1626 M_FST32(s2, s1, disp);
1629 M_DST32(s2, s1, disp);
1632 codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1635 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1636 /* val = value (in current instruction) */
1637 /* following NOP) */
1639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1641 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1642 uf = iptr->sx.s23.s3.uf;
1643 fieldtype = uf->fieldref->parseddesc.fd->type;
1646 /* PROFILE_CYCLE_STOP; */
1648 pr = patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1650 /* PROFILE_CYCLE_START; */
1653 fi = iptr->sx.s23.s3.fmiref->p.field;
1654 fieldtype = fi->type;
1658 /* implicit null-pointer check */
1659 switch (fieldtype) {
1662 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
1667 /* XXX why no check for IS_IMM32? -- probably because of the patcher */
1668 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1669 if (disp) /* resolved, disp can never be 0 */
1670 M_LST(REG_ITMP2, s1, disp);
1671 else /* unresolved */
1672 M_LST32(REG_ITMP2, s1, disp);
1675 codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1679 /* branch operations **************************************************/
1681 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1683 M_CALL_IMM(0); /* passing exception pc */
1684 M_POP(REG_ITMP2_XPC);
1686 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
1690 case ICMD_IF_LEQ: /* ..., value ==> ... */
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 if (IS_IMM32(iptr->sx.val.l))
1699 M_LCMP_IMM(iptr->sx.val.l, s1);
1701 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1702 M_LCMP(REG_ITMP2, s1);
1704 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
1707 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1708 case ICMD_IF_LCMPNE:
1709 case ICMD_IF_LCMPLT:
1710 case ICMD_IF_LCMPGE:
1711 case ICMD_IF_LCMPGT:
1712 case ICMD_IF_LCMPLE:
1714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1715 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1717 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
1720 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1723 branch_target_t *table;
1725 table = iptr->dst.table;
1727 l = iptr->sx.s23.s2.tablelow;
1728 i = iptr->sx.s23.s3.tablehigh;
1730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1731 M_INTMOVE(s1, REG_ITMP1);
1734 M_ISUB_IMM(l, REG_ITMP1);
1736 /* number of targets */
1741 M_ICMP_IMM(i - 1, REG_ITMP1);
1742 emit_bugt(cd, table[0].block);
1744 /* build jump table top down and use address of lowest entry */
1749 dseg_add_target(cd, table->block);
1753 /* length of dataseg after last dseg_add_target is used
1756 M_MOV_IMM(0, REG_ITMP2);
1758 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
1764 bte = iptr->sx.s23.s3.bte;
1765 if (bte->stub == NULL) {
1766 M_MOV_IMM(bte->fp, REG_ITMP1);
1769 M_MOV_IMM(bte->stub, REG_ITMP1);
1774 case ICMD_INVOKESPECIAL:
1775 emit_nullpointer_check(cd, iptr, REG_A0);
1778 case ICMD_INVOKESTATIC:
1779 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1780 um = iptr->sx.s23.s3.um;
1781 disp = dseg_add_unique_address(cd, um);
1783 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
1787 lm = iptr->sx.s23.s3.fmiref->p.method;
1788 disp = dseg_add_functionptr(cd, lm->stubroutine);
1791 M_ALD(REG_ITMP2, RIP, disp);
1795 case ICMD_INVOKEVIRTUAL:
1796 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1797 um = iptr->sx.s23.s3.um;
1798 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1803 lm = iptr->sx.s23.s3.fmiref->p.method;
1804 s1 = OFFSET(vftbl_t, table[0]) +
1805 sizeof(methodptr) * lm->vftblindex;
1808 /* implicit null-pointer check */
1809 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
1810 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
1814 case ICMD_INVOKEINTERFACE:
1815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816 um = iptr->sx.s23.s3.um;
1817 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1823 lm = iptr->sx.s23.s3.fmiref->p.method;
1824 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1825 sizeof(methodptr) * lm->clazz->index;
1827 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1830 /* implicit null-pointer check */
1831 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
1832 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
1833 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
1837 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1839 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1840 /* object type cast-check */
1845 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1850 super = iptr->sx.s23.s3.c.cls;
1851 superindex = super->index;
1854 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1856 /* if class is not resolved, check which code to call */
1858 if (super == NULL) {
1860 emit_label_beq(cd, BRANCH_LABEL_1);
1862 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
1863 iptr->sx.s23.s3.c.ref, 0);
1865 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
1866 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1867 emit_label_beq(cd, BRANCH_LABEL_2);
1870 /* interface checkcast code */
1872 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1873 if (super != NULL) {
1875 emit_label_beq(cd, BRANCH_LABEL_3);
1878 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1880 if (super == NULL) {
1881 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
1882 iptr->sx.s23.s3.c.ref,
1887 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
1888 M_ICMP_IMM32(superindex, REG_ITMP3);
1889 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1891 M_ALD32(REG_ITMP3, REG_ITMP2,
1892 OFFSET(vftbl_t, interfacetable[0]) -
1893 superindex * sizeof(methodptr*));
1895 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
1898 emit_label_br(cd, BRANCH_LABEL_4);
1900 emit_label(cd, BRANCH_LABEL_3);
1903 /* class checkcast code */
1905 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1906 if (super == NULL) {
1907 emit_label(cd, BRANCH_LABEL_2);
1909 constant_classref *cr = iptr->sx.s23.s3.c.ref;
1910 disp = dseg_add_unique_address(cd, cr);
1912 patcher_add_patch_ref(jd,
1913 PATCHER_resolve_classref_to_vftbl,
1918 emit_label_beq(cd, BRANCH_LABEL_5);
1920 disp = dseg_add_address(cd, super->vftbl);
1923 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1924 M_ALD(REG_ITMP3, RIP, disp);
1926 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1927 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1928 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
1929 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
1931 if (super == NULL) {
1932 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
1933 emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
1936 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1937 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
1938 emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
1940 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1941 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
1942 emit_label_beq(cd, BRANCH_LABEL_7); /* good */
1944 emit_label(cd, BRANCH_LABEL_9);
1946 emit_label(cd, BRANCH_LABEL_10);
1948 /* reload s1, might have been destroyed */
1949 emit_load_s1(jd, iptr, REG_ITMP1);
1950 M_ALD_MEM(s1, TRAP_ClassCastException);
1952 emit_label(cd, BRANCH_LABEL_7);
1953 emit_label(cd, BRANCH_LABEL_6);
1954 /* reload s1, might have been destroyed */
1955 emit_load_s1(jd, iptr, REG_ITMP1);
1958 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
1959 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
1963 emit_label(cd, BRANCH_LABEL_5);
1966 if (super == NULL) {
1967 emit_label(cd, BRANCH_LABEL_1);
1968 emit_label(cd, BRANCH_LABEL_4);
1971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1974 /* array type cast-check */
1976 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1977 M_INTMOVE(s1, REG_A0);
1979 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1980 constant_classref *cr = iptr->sx.s23.s3.c.ref;
1981 disp = dseg_add_unique_address(cd, cr);
1983 patcher_add_patch_ref(jd,
1984 PATCHER_resolve_classref_to_classinfo,
1988 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
1991 M_ALD(REG_A1, RIP, disp);
1992 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
1995 /* s1 may have been destroyed over the function call */
1996 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1998 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2000 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2004 emit_store_dst(jd, iptr, d);
2007 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2013 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2018 super = iptr->sx.s23.s3.c.cls;
2019 superindex = super->index;
2022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2026 M_INTMOVE(s1, REG_ITMP1);
2032 /* if class is not resolved, check which code to call */
2034 if (super == NULL) {
2036 emit_label_beq(cd, BRANCH_LABEL_1);
2038 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2039 iptr->sx.s23.s3.c.ref, 0);
2041 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2042 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2043 emit_label_beq(cd, BRANCH_LABEL_2);
2046 /* interface instanceof code */
2048 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2049 if (super != NULL) {
2051 emit_label_beq(cd, BRANCH_LABEL_3);
2054 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2056 if (super == NULL) {
2057 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2058 iptr->sx.s23.s3.c.ref, 0);
2062 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2063 M_ICMP_IMM32(superindex, REG_ITMP3);
2065 int a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2068 M_ALD32(REG_ITMP1, REG_ITMP1,
2069 OFFSET(vftbl_t, interfacetable[0]) -
2070 superindex * sizeof(methodptr*));
2075 emit_label_br(cd, BRANCH_LABEL_4);
2077 emit_label(cd, BRANCH_LABEL_3);
2080 /* class instanceof code */
2082 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2083 if (super == NULL) {
2084 emit_label(cd, BRANCH_LABEL_2);
2086 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2087 disp = dseg_add_unique_address(cd, cr);
2089 patcher_add_patch_ref(jd,
2090 PATCHER_resolve_classref_to_vftbl,
2095 emit_label_beq(cd, BRANCH_LABEL_5);
2097 disp = dseg_add_address(cd, super->vftbl);
2100 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2101 M_ALD(REG_ITMP3, RIP, disp);
2103 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2104 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2105 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2106 emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2107 if (d == REG_ITMP2) {
2112 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2113 emit_label(cd, BRANCH_LABEL_8);
2115 if (super == NULL) {
2116 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2117 emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2120 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2121 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2122 emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2124 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2125 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
2127 if (d == REG_ITMP2) {
2130 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2133 emit_label(cd, BRANCH_LABEL_9);
2135 emit_label(cd, BRANCH_LABEL_10);
2136 if (d == REG_ITMP2) {
2139 emit_label(cd, BRANCH_LABEL_7);
2141 emit_label(cd, BRANCH_LABEL_6);
2144 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2151 emit_label(cd, BRANCH_LABEL_5);
2154 if (super == NULL) {
2155 emit_label(cd, BRANCH_LABEL_1);
2156 emit_label(cd, BRANCH_LABEL_4);
2159 emit_store_dst(jd, iptr, d);
2163 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2165 /* check for negative sizes and copy sizes to stack if necessary */
2167 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2169 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2171 /* copy SAVEDVAR sizes to stack */
2172 var = VAR(iptr->sx.s23.s2.args[s1]);
2174 /* Already Preallocated? */
2175 if (!(var->flags & PREALLOC)) {
2176 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2177 M_LST(s2, REG_SP, s1 * 8);
2181 /* a0 = dimension count */
2183 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2185 /* is a patcher function set? */
2187 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2188 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2189 disp = dseg_add_unique_address(cd, cr);
2191 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2195 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2198 /* a1 = classinfo */
2200 M_ALD(REG_A1, RIP, disp);
2202 /* a2 = pointer to dimensions = stack pointer */
2204 M_MOV(REG_SP, REG_A2);
2206 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2209 /* check for exception before result assignment */
2211 emit_exception_check(cd, iptr);
2213 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2214 M_INTMOVE(REG_RESULT, s1);
2215 emit_store_dst(jd, iptr, s1);
2219 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2224 /* codegen_emit_stub_native ****************************************************
2226 Emits a stub routine which calls a native method.
2228 *******************************************************************************/
2230 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2244 /* Get required compiler data. */
2250 /* initialize variables */
2254 /* calculate stack frame size */
2256 cd->stackframesize =
2257 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2258 sizeof(localref_table) / SIZEOF_VOID_P +
2260 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2263 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2265 /* create method header */
2267 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2268 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2269 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2270 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2271 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2273 #if defined(ENABLE_PROFILING)
2274 /* generate native method profiling code */
2276 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2277 /* count frequency */
2279 M_MOV_IMM(code, REG_ITMP3);
2280 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2284 /* generate stub code */
2286 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2288 #if defined(ENABLE_GC_CACAO)
2289 /* Save callee saved integer registers in stackframeinfo (GC may
2290 need to recover them during a collection). */
2292 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2293 OFFSET(stackframeinfo_t, intregs);
2295 for (i = 0; i < INT_SAV_CNT; i++)
2296 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2299 /* save integer and float argument registers */
2301 for (i = 0; i < md->paramcount; i++) {
2302 if (!md->params[i].inmemory) {
2303 s1 = md->params[i].regoff;
2305 switch (md->paramtypes[i].type) {
2309 M_LST(s1, REG_SP, i * 8);
2313 M_DST(s1, REG_SP, i * 8);
2319 /* create dynamic stack info */
2321 M_MOV(REG_SP, REG_A0);
2322 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2323 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2326 /* remember class argument */
2328 if (m->flags & ACC_STATIC)
2329 M_MOV(REG_RESULT, REG_ITMP2);
2331 /* restore integer and float argument registers */
2333 for (i = 0; i < md->paramcount; i++) {
2334 if (!md->params[i].inmemory) {
2335 s1 = md->params[i].regoff;
2337 switch (md->paramtypes[i].type) {
2341 M_LLD(s1, REG_SP, i * 8);
2345 M_DLD(s1, REG_SP, i * 8);
2351 /* Copy or spill arguments to new locations. */
2353 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2354 s2 = nmd->params[j].regoff;
2356 switch (md->paramtypes[i].type) {
2360 if (!md->params[i].inmemory) {
2361 s1 = md->params[i].regoff;
2363 if (!nmd->params[j].inmemory)
2366 M_LST(s1, REG_SP, s2);
2369 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2370 M_LLD(REG_ITMP1, REG_SP, s1);
2371 M_LST(REG_ITMP1, REG_SP, s2);
2375 /* We only copy spilled float arguments, as the float
2376 argument registers keep unchanged. */
2378 if (md->params[i].inmemory) {
2379 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2381 M_FLD(REG_FTMP1, REG_SP, s1);
2382 M_FST(REG_FTMP1, REG_SP, s2);
2386 if (md->params[i].inmemory) {
2387 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2388 M_DLD(REG_FTMP1, REG_SP, s1);
2389 M_DST(REG_FTMP1, REG_SP, s2);
2395 /* Handle native Java methods. */
2397 if (m->flags & ACC_NATIVE) {
2398 /* put class into second argument register */
2400 if (m->flags & ACC_STATIC)
2401 M_MOV(REG_ITMP2, REG_A1);
2403 /* put env into first argument register */
2405 M_MOV_IMM(VM_get_jnienv(), REG_A0);
2408 /* Call the native function. */
2410 disp = dseg_add_functionptr(cd, f);
2411 M_ALD(REG_ITMP1, RIP, disp);
2414 /* save return value */
2416 switch (md->returntype.type) {
2420 switch (md->returntype.primitivetype) {
2421 case PRIMITIVETYPE_BOOLEAN:
2422 M_BZEXT(REG_RESULT, REG_RESULT);
2424 case PRIMITIVETYPE_BYTE:
2425 M_BSEXT(REG_RESULT, REG_RESULT);
2427 case PRIMITIVETYPE_CHAR:
2428 M_CZEXT(REG_RESULT, REG_RESULT);
2430 case PRIMITIVETYPE_SHORT:
2431 M_SSEXT(REG_RESULT, REG_RESULT);
2434 M_LST(REG_RESULT, REG_SP, 0 * 8);
2438 M_DST(REG_FRESULT, REG_SP, 0 * 8);
2444 /* remove native stackframe info */
2446 M_MOV(REG_SP, REG_A0);
2447 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2448 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
2450 M_MOV(REG_RESULT, REG_ITMP3);
2452 /* restore return value */
2454 switch (md->returntype.type) {
2458 M_LLD(REG_RESULT, REG_SP, 0 * 8);
2462 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
2468 #if defined(ENABLE_GC_CACAO)
2469 /* Restore callee saved integer registers from stackframeinfo (GC
2470 might have modified them during a collection). */
2472 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2473 OFFSET(stackframeinfo_t, intregs);
2475 for (i = 0; i < INT_SAV_CNT; i++)
2476 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2479 /* remove stackframe */
2481 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2483 /* test for exception */
2489 /* handle exception */
2491 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
2492 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
2493 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
2495 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
2501 * These are local overrides for various environment variables in Emacs.
2502 * Please do not remove this and leave it at the end of the file, where
2503 * Emacs will automagically detect them.
2504 * ---------------------------------------------------------------------
2507 * indent-tabs-mode: t
2511 * vim:noexpandtab:sw=4:ts=4: