1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2009, 2010
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; */
1511 fi = NULL; /* Silence compiler warning */
1514 fi = iptr->sx.s23.s3.fmiref->p.field;
1515 fieldtype = fi->type;
1516 disp = dseg_add_address(cd, fi->value);
1518 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1519 //PROFILE_CYCLE_STOP;
1521 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1524 //PROFILE_CYCLE_START;
1527 pr = NULL; /* Silence compiler warning */
1530 /* This approach is much faster than moving the field
1531 address inline into a register. */
1533 M_ALD(REG_ITMP1, RIP, disp);
1535 switch (fieldtype) {
1538 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1543 if (IS_IMM32(iptr->sx.s23.s2.constval))
1544 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1546 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1547 M_LST(REG_ITMP2, REG_ITMP1, 0);
1551 codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1554 case ICMD_GETFIELD: /* ... ==> ..., value */
1556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1558 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1559 uf = iptr->sx.s23.s3.uf;
1560 fieldtype = uf->fieldref->parseddesc.fd->type;
1563 /* PROFILE_CYCLE_STOP; */
1565 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1567 /* PROFILE_CYCLE_START; */
1569 fi = NULL; /* Silence compiler warning */
1572 fi = iptr->sx.s23.s3.fmiref->p.field;
1573 fieldtype = fi->type;
1577 /* implicit null-pointer check */
1578 switch (fieldtype) {
1580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1581 M_ILD32(d, s1, disp);
1585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1586 M_LLD32(d, s1, disp);
1589 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1590 M_FLD32(d, s1, disp);
1593 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1594 M_DLD32(d, s1, disp);
1597 // Silence compiler warning.
1600 emit_store_dst(jd, iptr, d);
1603 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1608 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1609 uf = iptr->sx.s23.s3.uf;
1610 fieldtype = uf->fieldref->parseddesc.fd->type;
1613 /* PROFILE_CYCLE_STOP; */
1615 pr = patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1617 /* PROFILE_CYCLE_START; */
1619 fi = NULL; /* Silence compiler warning */
1622 fi = iptr->sx.s23.s3.fmiref->p.field;
1623 fieldtype = fi->type;
1626 pr = NULL; /* Silence compiler warning */
1629 /* implicit null-pointer check */
1630 switch (fieldtype) {
1632 M_IST32(s2, s1, disp);
1636 M_LST32(s2, s1, disp);
1639 M_FST32(s2, s1, disp);
1642 M_DST32(s2, s1, disp);
1645 codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1648 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1649 /* val = value (in current instruction) */
1650 /* following NOP) */
1652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1654 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1655 uf = iptr->sx.s23.s3.uf;
1656 fieldtype = uf->fieldref->parseddesc.fd->type;
1659 /* PROFILE_CYCLE_STOP; */
1661 pr = patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1663 /* PROFILE_CYCLE_START; */
1665 fi = NULL; /* Silence compiler warning */
1668 fi = iptr->sx.s23.s3.fmiref->p.field;
1669 fieldtype = fi->type;
1672 pr = NULL; /* Silence compiler warning */
1675 /* implicit null-pointer check */
1676 switch (fieldtype) {
1679 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
1684 /* XXX why no check for IS_IMM32? -- probably because of the patcher */
1685 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1686 if (disp) /* resolved, disp can never be 0 */
1687 M_LST(REG_ITMP2, s1, disp);
1688 else /* unresolved */
1689 M_LST32(REG_ITMP2, s1, disp);
1692 codegen_emit_patchable_barrier(iptr, cd, pr, fi);
1696 /* branch operations **************************************************/
1698 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1700 M_CALL_IMM(0); /* passing exception pc */
1701 M_POP(REG_ITMP2_XPC);
1703 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
1707 case ICMD_IF_LEQ: /* ..., value ==> ... */
1714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1715 if (IS_IMM32(iptr->sx.val.l))
1716 M_LCMP_IMM(iptr->sx.val.l, s1);
1718 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1719 M_LCMP(REG_ITMP2, s1);
1721 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
1724 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1725 case ICMD_IF_LCMPNE:
1726 case ICMD_IF_LCMPLT:
1727 case ICMD_IF_LCMPGE:
1728 case ICMD_IF_LCMPGT:
1729 case ICMD_IF_LCMPLE:
1731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1734 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
1737 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1740 branch_target_t *table;
1742 table = iptr->dst.table;
1744 l = iptr->sx.s23.s2.tablelow;
1745 i = iptr->sx.s23.s3.tablehigh;
1747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1748 M_INTMOVE(s1, REG_ITMP1);
1751 M_ISUB_IMM(l, REG_ITMP1);
1753 /* number of targets */
1758 M_ICMP_IMM(i - 1, REG_ITMP1);
1759 emit_bugt(cd, table[0].block);
1761 /* build jump table top down and use address of lowest entry */
1766 dseg_add_target(cd, table->block);
1770 /* length of dataseg after last dseg_add_target is used
1773 M_MOV_IMM(0, REG_ITMP2);
1775 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
1781 bte = iptr->sx.s23.s3.bte;
1782 if (bte->stub == NULL) {
1783 M_MOV_IMM(bte->fp, REG_ITMP1);
1786 M_MOV_IMM(bte->stub, REG_ITMP1);
1791 case ICMD_INVOKESPECIAL:
1792 emit_nullpointer_check(cd, iptr, REG_A0);
1795 case ICMD_INVOKESTATIC:
1796 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1797 um = iptr->sx.s23.s3.um;
1798 disp = dseg_add_unique_address(cd, um);
1800 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
1804 lm = iptr->sx.s23.s3.fmiref->p.method;
1805 disp = dseg_add_functionptr(cd, lm->stubroutine);
1808 M_ALD(REG_ITMP2, RIP, disp);
1812 case ICMD_INVOKEVIRTUAL:
1813 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1814 um = iptr->sx.s23.s3.um;
1815 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1820 lm = iptr->sx.s23.s3.fmiref->p.method;
1821 s1 = OFFSET(vftbl_t, table[0]) +
1822 sizeof(methodptr) * lm->vftblindex;
1825 /* implicit null-pointer check */
1826 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
1827 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
1831 case ICMD_INVOKEINTERFACE:
1832 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1833 um = iptr->sx.s23.s3.um;
1834 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1840 lm = iptr->sx.s23.s3.fmiref->p.method;
1841 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1842 sizeof(methodptr) * lm->clazz->index;
1844 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1847 /* implicit null-pointer check */
1848 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
1849 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
1850 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
1854 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1856 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1857 /* object type cast-check */
1862 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1867 super = iptr->sx.s23.s3.c.cls;
1868 superindex = super->index;
1871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1873 /* if class is not resolved, check which code to call */
1875 if (super == NULL) {
1877 emit_label_beq(cd, BRANCH_LABEL_1);
1879 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
1880 iptr->sx.s23.s3.c.ref, 0);
1882 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
1883 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1884 emit_label_beq(cd, BRANCH_LABEL_2);
1887 /* interface checkcast code */
1889 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1890 if (super != NULL) {
1892 emit_label_beq(cd, BRANCH_LABEL_3);
1895 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1897 if (super == NULL) {
1898 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
1899 iptr->sx.s23.s3.c.ref,
1904 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
1905 M_ICMP_IMM32(superindex, REG_ITMP3);
1906 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1908 M_ALD32(REG_ITMP3, REG_ITMP2,
1909 OFFSET(vftbl_t, interfacetable[0]) -
1910 superindex * sizeof(methodptr*));
1912 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
1915 emit_label_br(cd, BRANCH_LABEL_4);
1917 emit_label(cd, BRANCH_LABEL_3);
1920 /* class checkcast code */
1922 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1923 if (super == NULL) {
1924 emit_label(cd, BRANCH_LABEL_2);
1926 constant_classref *cr = iptr->sx.s23.s3.c.ref;
1927 disp = dseg_add_unique_address(cd, cr);
1929 patcher_add_patch_ref(jd,
1930 PATCHER_resolve_classref_to_vftbl,
1935 emit_label_beq(cd, BRANCH_LABEL_5);
1937 disp = dseg_add_address(cd, super->vftbl);
1940 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1941 M_ALD(REG_ITMP3, RIP, disp);
1943 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1944 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1945 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
1946 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
1948 if (super == NULL) {
1949 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
1950 emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
1953 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1954 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
1955 emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
1957 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1958 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
1959 emit_label_beq(cd, BRANCH_LABEL_7); /* good */
1961 emit_label(cd, BRANCH_LABEL_9);
1963 emit_label(cd, BRANCH_LABEL_10);
1965 /* reload s1, might have been destroyed */
1966 emit_load_s1(jd, iptr, REG_ITMP1);
1967 M_ALD_MEM(s1, TRAP_ClassCastException);
1969 emit_label(cd, BRANCH_LABEL_7);
1970 emit_label(cd, BRANCH_LABEL_6);
1971 /* reload s1, might have been destroyed */
1972 emit_load_s1(jd, iptr, REG_ITMP1);
1975 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
1976 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
1980 emit_label(cd, BRANCH_LABEL_5);
1983 if (super == NULL) {
1984 emit_label(cd, BRANCH_LABEL_1);
1985 emit_label(cd, BRANCH_LABEL_4);
1988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1991 /* array type cast-check */
1993 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1994 M_INTMOVE(s1, REG_A0);
1996 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1997 constant_classref *cr = iptr->sx.s23.s3.c.ref;
1998 disp = dseg_add_unique_address(cd, cr);
2000 patcher_add_patch_ref(jd,
2001 PATCHER_resolve_classref_to_classinfo,
2005 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2008 M_ALD(REG_A1, RIP, disp);
2009 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
2012 /* s1 may have been destroyed over the function call */
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2015 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2017 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2021 emit_store_dst(jd, iptr, d);
2024 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2030 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2035 super = iptr->sx.s23.s3.c.cls;
2036 superindex = super->index;
2039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2043 M_INTMOVE(s1, REG_ITMP1);
2049 /* if class is not resolved, check which code to call */
2051 if (super == NULL) {
2053 emit_label_beq(cd, BRANCH_LABEL_1);
2055 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2056 iptr->sx.s23.s3.c.ref, 0);
2058 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2059 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2060 emit_label_beq(cd, BRANCH_LABEL_2);
2063 /* interface instanceof code */
2065 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2066 if (super != NULL) {
2068 emit_label_beq(cd, BRANCH_LABEL_3);
2071 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2073 if (super == NULL) {
2074 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2075 iptr->sx.s23.s3.c.ref, 0);
2079 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2080 M_ICMP_IMM32(superindex, REG_ITMP3);
2082 int a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2085 M_ALD32(REG_ITMP1, REG_ITMP1,
2086 OFFSET(vftbl_t, interfacetable[0]) -
2087 superindex * sizeof(methodptr*));
2092 emit_label_br(cd, BRANCH_LABEL_4);
2094 emit_label(cd, BRANCH_LABEL_3);
2097 /* class instanceof code */
2099 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2100 if (super == NULL) {
2101 emit_label(cd, BRANCH_LABEL_2);
2103 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2104 disp = dseg_add_unique_address(cd, cr);
2106 patcher_add_patch_ref(jd,
2107 PATCHER_resolve_classref_to_vftbl,
2112 emit_label_beq(cd, BRANCH_LABEL_5);
2114 disp = dseg_add_address(cd, super->vftbl);
2117 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2118 M_ALD(REG_ITMP3, RIP, disp);
2120 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2121 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2122 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2123 emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2124 if (d == REG_ITMP2) {
2129 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2130 emit_label(cd, BRANCH_LABEL_8);
2132 if (super == NULL) {
2133 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2134 emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2137 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2138 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2139 emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2141 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2142 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
2144 if (d == REG_ITMP2) {
2147 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2150 emit_label(cd, BRANCH_LABEL_9);
2152 emit_label(cd, BRANCH_LABEL_10);
2153 if (d == REG_ITMP2) {
2156 emit_label(cd, BRANCH_LABEL_7);
2158 emit_label(cd, BRANCH_LABEL_6);
2161 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2168 emit_label(cd, BRANCH_LABEL_5);
2171 if (super == NULL) {
2172 emit_label(cd, BRANCH_LABEL_1);
2173 emit_label(cd, BRANCH_LABEL_4);
2176 emit_store_dst(jd, iptr, d);
2180 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2182 /* check for negative sizes and copy sizes to stack if necessary */
2184 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2186 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2188 /* copy SAVEDVAR sizes to stack */
2189 var = VAR(iptr->sx.s23.s2.args[s1]);
2191 /* Already Preallocated? */
2192 if (!(var->flags & PREALLOC)) {
2193 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2194 M_LST(s2, REG_SP, s1 * 8);
2198 /* a0 = dimension count */
2200 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2202 /* is a patcher function set? */
2204 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2205 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2206 disp = dseg_add_unique_address(cd, cr);
2208 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2212 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2215 /* a1 = classinfo */
2217 M_ALD(REG_A1, RIP, disp);
2219 /* a2 = pointer to dimensions = stack pointer */
2221 M_MOV(REG_SP, REG_A2);
2223 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2226 /* check for exception before result assignment */
2228 emit_exception_check(cd, iptr);
2230 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2231 M_INTMOVE(REG_RESULT, s1);
2232 emit_store_dst(jd, iptr, s1);
2236 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2241 /* codegen_emit_stub_native ****************************************************
2243 Emits a stub routine which calls a native method.
2245 *******************************************************************************/
2247 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2261 /* Get required compiler data. */
2267 /* initialize variables */
2271 /* calculate stack frame size */
2273 cd->stackframesize =
2274 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2275 sizeof(localref_table) / SIZEOF_VOID_P +
2277 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2280 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2282 /* create method header */
2284 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2285 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2286 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2287 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2288 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2290 #if defined(ENABLE_PROFILING)
2291 /* generate native method profiling code */
2293 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2294 /* count frequency */
2296 M_MOV_IMM(code, REG_ITMP3);
2297 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2301 /* generate stub code */
2303 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2305 #if defined(ENABLE_GC_CACAO)
2306 /* Save callee saved integer registers in stackframeinfo (GC may
2307 need to recover them during a collection). */
2309 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2310 OFFSET(stackframeinfo_t, intregs);
2312 for (i = 0; i < INT_SAV_CNT; i++)
2313 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2316 /* save integer and float argument registers */
2318 for (i = 0; i < md->paramcount; i++) {
2319 if (!md->params[i].inmemory) {
2320 s1 = md->params[i].regoff;
2322 switch (md->paramtypes[i].type) {
2326 M_LST(s1, REG_SP, i * 8);
2330 M_DST(s1, REG_SP, i * 8);
2336 /* create dynamic stack info */
2338 M_MOV(REG_SP, REG_A0);
2339 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2340 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2343 /* remember class argument */
2345 if (m->flags & ACC_STATIC)
2346 M_MOV(REG_RESULT, REG_ITMP2);
2348 /* restore integer and float argument registers */
2350 for (i = 0; i < md->paramcount; i++) {
2351 if (!md->params[i].inmemory) {
2352 s1 = md->params[i].regoff;
2354 switch (md->paramtypes[i].type) {
2358 M_LLD(s1, REG_SP, i * 8);
2362 M_DLD(s1, REG_SP, i * 8);
2368 /* Copy or spill arguments to new locations. */
2370 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2371 s2 = nmd->params[j].regoff;
2373 switch (md->paramtypes[i].type) {
2377 if (!md->params[i].inmemory) {
2378 s1 = md->params[i].regoff;
2380 if (!nmd->params[j].inmemory)
2383 M_LST(s1, REG_SP, s2);
2386 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2387 M_LLD(REG_ITMP1, REG_SP, s1);
2388 M_LST(REG_ITMP1, REG_SP, s2);
2392 /* We only copy spilled float arguments, as the float
2393 argument registers keep unchanged. */
2395 if (md->params[i].inmemory) {
2396 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2398 M_FLD(REG_FTMP1, REG_SP, s1);
2399 M_FST(REG_FTMP1, REG_SP, s2);
2403 if (md->params[i].inmemory) {
2404 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2405 M_DLD(REG_FTMP1, REG_SP, s1);
2406 M_DST(REG_FTMP1, REG_SP, s2);
2412 /* Handle native Java methods. */
2414 if (m->flags & ACC_NATIVE) {
2415 /* put class into second argument register */
2417 if (m->flags & ACC_STATIC)
2418 M_MOV(REG_ITMP2, REG_A1);
2420 /* put env into first argument register */
2422 M_MOV_IMM(VM_get_jnienv(), REG_A0);
2425 /* Call the native function. */
2427 disp = dseg_add_functionptr(cd, f);
2428 M_ALD(REG_ITMP1, RIP, disp);
2431 /* save return value */
2433 switch (md->returntype.type) {
2437 switch (md->returntype.primitivetype) {
2438 case PRIMITIVETYPE_BOOLEAN:
2439 M_BZEXT(REG_RESULT, REG_RESULT);
2441 case PRIMITIVETYPE_BYTE:
2442 M_BSEXT(REG_RESULT, REG_RESULT);
2444 case PRIMITIVETYPE_CHAR:
2445 M_CZEXT(REG_RESULT, REG_RESULT);
2447 case PRIMITIVETYPE_SHORT:
2448 M_SSEXT(REG_RESULT, REG_RESULT);
2451 M_LST(REG_RESULT, REG_SP, 0 * 8);
2455 M_DST(REG_FRESULT, REG_SP, 0 * 8);
2461 /* remove native stackframe info */
2463 M_MOV(REG_SP, REG_A0);
2464 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2465 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
2467 M_MOV(REG_RESULT, REG_ITMP3);
2469 /* restore return value */
2471 switch (md->returntype.type) {
2475 M_LLD(REG_RESULT, REG_SP, 0 * 8);
2479 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
2485 #if defined(ENABLE_GC_CACAO)
2486 /* Restore callee saved integer registers from stackframeinfo (GC
2487 might have modified them during a collection). */
2489 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2490 OFFSET(stackframeinfo_t, intregs);
2492 for (i = 0; i < INT_SAV_CNT; i++)
2493 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2496 /* remove stackframe */
2498 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2500 /* test for exception */
2506 /* handle exception */
2508 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
2509 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
2510 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
2512 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
2518 * These are local overrides for various environment variables in Emacs.
2519 * Please do not remove this and leave it at the end of the file, where
2520 * Emacs will automagically detect them.
2521 * ---------------------------------------------------------------------
2524 * indent-tabs-mode: t
2528 * vim:noexpandtab:sw=4:ts=4: