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);
192 * Generates machine code for one ICMD.
194 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
198 builtintable_entry* bte;
199 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
200 unresolved_method* um;
202 unresolved_field* uf;
204 int32_t s1, s2, s3, d;
207 // Get required compiler data.
208 codegendata* cd = jd->cd;
212 /* constant operations ************************************************/
214 case ICMD_FCONST: /* ... ==> ..., constant */
216 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
217 disp = dseg_add_float(cd, iptr->sx.val.f);
218 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
219 emit_store_dst(jd, iptr, d);
222 case ICMD_DCONST: /* ... ==> ..., constant */
224 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
225 disp = dseg_add_double(cd, iptr->sx.val.d);
226 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
227 emit_store_dst(jd, iptr, d);
230 case ICMD_ACONST: /* ... ==> ..., constant */
232 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
234 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
235 constant_classref *cr = iptr->sx.val.c.ref;
236 disp = dseg_add_unique_address(cd, cr);
238 /* PROFILE_CYCLE_STOP; */
240 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
243 /* PROFILE_CYCLE_START; */
248 if (iptr->sx.val.anyptr == 0) {
252 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
256 emit_store_dst(jd, iptr, d);
260 /* integer operations *************************************************/
262 case ICMD_INEG: /* ..., value ==> ..., - value */
264 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
265 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
268 emit_store_dst(jd, iptr, d);
271 case ICMD_LNEG: /* ..., value ==> ..., - value */
273 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
274 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
277 emit_store_dst(jd, iptr, d);
280 case ICMD_I2L: /* ..., value ==> ..., value */
282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
283 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
285 emit_store_dst(jd, iptr, d);
288 case ICMD_L2I: /* ..., value ==> ..., value */
290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
291 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
293 emit_store_dst(jd, iptr, d);
296 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
298 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
299 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
301 emit_store_dst(jd, iptr, d);
304 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
307 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
309 emit_store_dst(jd, iptr, d);
312 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
314 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
315 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
317 emit_store_dst(jd, iptr, d);
321 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
332 emit_store_dst(jd, iptr, d);
336 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
337 /* sx.val.i = constant */
339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
342 /* Using inc and dec is not faster than add (tested with
346 M_IADD_IMM(iptr->sx.val.i, d);
347 emit_store_dst(jd, iptr, d);
350 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
353 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
361 emit_store_dst(jd, iptr, d);
364 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
365 /* sx.val.l = constant */
367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
368 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
370 if (IS_IMM32(iptr->sx.val.l))
371 M_LADD_IMM(iptr->sx.val.l, d);
373 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
374 M_LADD(REG_ITMP2, d);
376 emit_store_dst(jd, iptr, d);
379 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
381 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
382 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
383 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
385 M_INTMOVE(s1, REG_ITMP1);
386 M_ISUB(s2, REG_ITMP1);
387 M_INTMOVE(REG_ITMP1, d);
392 emit_store_dst(jd, iptr, d);
395 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
396 /* sx.val.i = constant */
398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
401 M_ISUB_IMM(iptr->sx.val.i, d);
402 emit_store_dst(jd, iptr, d);
405 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
407 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
408 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
411 M_INTMOVE(s1, REG_ITMP1);
412 M_LSUB(s2, REG_ITMP1);
413 M_INTMOVE(REG_ITMP1, d);
418 emit_store_dst(jd, iptr, d);
421 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
422 /* sx.val.l = constant */
424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
427 if (IS_IMM32(iptr->sx.val.l))
428 M_LSUB_IMM(iptr->sx.val.l, d);
430 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
431 M_LSUB(REG_ITMP2, d);
433 emit_store_dst(jd, iptr, d);
436 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
439 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
440 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
447 emit_store_dst(jd, iptr, d);
450 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
451 /* sx.val.i = constant */
453 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
455 if (iptr->sx.val.i == 2) {
459 M_IMUL_IMM(s1, iptr->sx.val.i, d);
460 emit_store_dst(jd, iptr, d);
463 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
478 /* sx.val.l = constant */
480 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
481 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
482 if (IS_IMM32(iptr->sx.val.l))
483 M_LMUL_IMM(s1, iptr->sx.val.l, d);
485 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
487 M_LMUL(REG_ITMP2, d);
489 emit_store_dst(jd, iptr, d);
492 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
494 s1 = emit_load_s1(jd, iptr, RAX);
495 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
496 d = codegen_reg_of_dst(jd, iptr, RAX);
499 M_INTMOVE(s2, REG_ITMP3);
500 emit_arithmetic_check(cd, iptr, REG_ITMP3);
502 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
504 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
506 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
507 M_BEQ(1 + 3); /* 6 bytes */
509 emit_cltd(cd); /* 1 byte */
510 emit_idivl_reg(cd, REG_ITMP3); /* 3 bytes */
513 emit_store_dst(jd, iptr, d);
514 dst = VAROP(iptr->dst);
515 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
516 M_MOV(REG_ITMP2, RDX); /* restore RDX */
519 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
521 s1 = emit_load_s1(jd, iptr, RAX);
522 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
523 d = codegen_reg_of_dst(jd, iptr, RDX);
526 M_INTMOVE(s2, REG_ITMP3);
527 emit_arithmetic_check(cd, iptr, REG_ITMP3);
529 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
531 M_ICMP_IMM(0x80000000, RAX); /* check as described in jvm spec */
533 M_CLR(RDX); /* 3 bytes */
534 M_ICMP_IMM(-1, REG_ITMP3); /* 4 bytes */
535 M_BEQ(1 + 3); /* 6 bytes */
537 emit_cltd(cd); /* 1 byte */
538 emit_idivl_reg(cd, REG_ITMP3); /* 3 byte */
541 emit_store_dst(jd, iptr, d);
542 dst = VAROP(iptr->dst);
543 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
544 M_MOV(REG_ITMP2, RDX); /* restore RDX */
547 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
548 /* sx.val.i = constant */
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
552 M_INTMOVE(s1, REG_ITMP1);
553 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
554 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
555 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
556 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
557 emit_mov_reg_reg(cd, REG_ITMP1, d);
558 emit_store_dst(jd, iptr, d);
561 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
562 /* sx.val.i = constant */
564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
566 M_INTMOVE(s1, REG_ITMP1);
567 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
568 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
569 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
570 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
571 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
572 emit_mov_reg_reg(cd, REG_ITMP1, d);
573 emit_store_dst(jd, iptr, d);
577 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
579 s1 = emit_load_s1(jd, iptr, RAX);
580 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
581 d = codegen_reg_of_dst(jd, iptr, RAX);
584 M_INTMOVE(s2, REG_ITMP3);
585 emit_arithmetic_check(cd, iptr, REG_ITMP3);
587 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
589 /* check as described in jvm spec */
590 disp = dseg_add_s8(cd, 0x8000000000000000LL);
591 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
593 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
594 M_BEQ(2 + 3); /* 6 bytes */
596 emit_cqto(cd); /* 2 bytes */
597 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
600 emit_store_dst(jd, iptr, d);
601 dst = VAROP(iptr->dst);
602 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
603 M_MOV(REG_ITMP2, RDX); /* restore RDX */
606 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
608 s1 = emit_load_s1(jd, iptr, RAX);
609 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
610 d = codegen_reg_of_dst(jd, iptr, RDX);
613 M_INTMOVE(s2, REG_ITMP3);
614 emit_arithmetic_check(cd, iptr, REG_ITMP3);
616 M_MOV(RDX, REG_ITMP2); /* save RDX (it's an argument register) */
618 /* check as described in jvm spec */
619 disp = dseg_add_s8(cd, 0x8000000000000000LL);
620 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
622 M_LXOR(RDX, RDX); /* 3 bytes */
623 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
624 M_BEQ(2 + 3); /* 6 bytes */
626 emit_cqto(cd); /* 2 bytes */
627 emit_idiv_reg(cd, REG_ITMP3); /* 3 bytes */
630 emit_store_dst(jd, iptr, d);
631 dst = VAROP(iptr->dst);
632 if (IS_INMEMORY(dst->flags) || (dst->vv.regoff != RDX))
633 M_MOV(REG_ITMP2, RDX); /* restore RDX */
636 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
637 /* sx.val.i = constant */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
641 M_INTMOVE(s1, REG_ITMP1);
642 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
643 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
644 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
645 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
646 emit_mov_reg_reg(cd, REG_ITMP1, d);
647 emit_store_dst(jd, iptr, d);
650 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
651 /* sx.val.l = constant */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
655 M_INTMOVE(s1, REG_ITMP1);
656 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
657 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
658 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
659 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
660 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
661 emit_mov_reg_reg(cd, REG_ITMP1, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
667 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
668 emit_ishift(jd, SHIFT_SHL, iptr);
671 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
672 /* sx.val.i = constant */
674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
677 M_ISLL_IMM(iptr->sx.val.i, d);
678 emit_store_dst(jd, iptr, d);
681 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
683 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
684 emit_ishift(jd, SHIFT_SAR, iptr);
687 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
688 /* sx.val.i = constant */
690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
693 M_ISRA_IMM(iptr->sx.val.i, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
699 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
700 emit_ishift(jd, SHIFT_SHR, iptr);
703 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
704 /* sx.val.i = constant */
706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709 M_ISRL_IMM(iptr->sx.val.i, d);
710 emit_store_dst(jd, iptr, d);
713 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
715 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
716 emit_lshift(jd, SHIFT_SHL, iptr);
719 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
720 /* sx.val.i = constant */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
725 M_LSLL_IMM(iptr->sx.val.i, d);
726 emit_store_dst(jd, iptr, d);
729 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
731 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
732 emit_lshift(jd, SHIFT_SAR, iptr);
735 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
736 /* sx.val.i = constant */
738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
739 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
741 M_LSRA_IMM(iptr->sx.val.i, d);
742 emit_store_dst(jd, iptr, d);
745 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
747 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
748 emit_lshift(jd, SHIFT_SHR, iptr);
751 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
752 /* sx.val.l = constant */
754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
757 M_LSRL_IMM(iptr->sx.val.i, d);
758 emit_store_dst(jd, iptr, d);
761 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
764 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 emit_store_dst(jd, iptr, d);
775 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
776 /* sx.val.i = constant */
778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
781 M_IAND_IMM(iptr->sx.val.i, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
800 /* sx.val.l = constant */
802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
805 if (IS_IMM32(iptr->sx.val.l))
806 M_LAND_IMM(iptr->sx.val.l, d);
808 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
809 M_LAND(REG_ITMP2, d);
811 emit_store_dst(jd, iptr, d);
814 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
829 /* sx.val.i = constant */
831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
834 M_IOR_IMM(iptr->sx.val.i, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
849 emit_store_dst(jd, iptr, d);
852 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
853 /* sx.val.l = constant */
855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
856 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
858 if (IS_IMM32(iptr->sx.val.l))
859 M_LOR_IMM(iptr->sx.val.l, d);
861 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
864 emit_store_dst(jd, iptr, d);
867 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
870 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
882 /* sx.val.i = constant */
884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
887 M_IXOR_IMM(iptr->sx.val.i, d);
888 emit_store_dst(jd, iptr, d);
891 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
902 emit_store_dst(jd, iptr, d);
905 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
906 /* sx.val.l = constant */
908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
911 if (IS_IMM32(iptr->sx.val.l))
912 M_LXOR_IMM(iptr->sx.val.l, d);
914 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
915 M_LXOR(REG_ITMP2, d);
917 emit_store_dst(jd, iptr, d);
921 /* floating operations ************************************************/
923 case ICMD_FNEG: /* ..., value ==> ..., - value */
925 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
926 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
927 disp = dseg_add_s4(cd, 0x80000000);
928 emit_fmove(cd, s1, d);
929 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
930 emit_xorps_reg_reg(cd, REG_FTMP2, d);
931 emit_store_dst(jd, iptr, d);
934 case ICMD_DNEG: /* ..., value ==> ..., - value */
936 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
937 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
938 disp = dseg_add_s8(cd, 0x8000000000000000);
939 emit_fmove(cd, s1, d);
940 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
941 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
942 emit_store_dst(jd, iptr, d);
945 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
947 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
948 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
949 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
953 emit_fmove(cd, s1, d);
956 emit_store_dst(jd, iptr, d);
959 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
961 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
962 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
963 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
967 emit_fmove(cd, s1, d);
970 emit_store_dst(jd, iptr, d);
973 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
975 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
976 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
977 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
979 emit_fmove(cd, s2, REG_FTMP2);
982 emit_fmove(cd, s1, d);
984 emit_store_dst(jd, iptr, d);
987 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
989 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
990 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
991 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
993 emit_fmove(cd, s2, REG_FTMP2);
996 emit_fmove(cd, s1, d);
998 emit_store_dst(jd, iptr, d);
1001 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1003 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1004 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1005 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1009 emit_fmove(cd, s1, d);
1012 emit_store_dst(jd, iptr, d);
1015 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1017 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1018 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1019 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1023 emit_fmove(cd, s1, d);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1031 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1032 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1033 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1035 emit_fmove(cd, s2, REG_FTMP2);
1038 emit_fmove(cd, s1, d);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1045 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1046 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1047 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1049 emit_fmove(cd, s2, REG_FTMP2);
1052 emit_fmove(cd, s1, d);
1054 emit_store_dst(jd, iptr, d);
1057 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1060 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1062 emit_store_dst(jd, iptr, d);
1065 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1068 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1084 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1091 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1094 M_ICMP_IMM(0x80000000, d); /* corner cases */
1095 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1096 ((REG_RESULT == d) ? 0 : 3);
1098 emit_fmove(cd, s1, REG_FTMP1);
1099 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1101 M_INTMOVE(REG_RESULT, d);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1107 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1108 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1110 M_ICMP_IMM(0x80000000, d); /* corner cases */
1111 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1112 ((REG_RESULT == d) ? 0 : 3);
1114 emit_fmove(cd, s1, REG_FTMP1);
1115 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1117 M_INTMOVE(REG_RESULT, d);
1118 emit_store_dst(jd, iptr, d);
1121 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1123 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1126 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1127 M_LCMP(REG_ITMP2, 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_f2l, REG_ITMP2);
1134 M_INTMOVE(REG_RESULT, d);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_D2L: /* ..., 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_d2l, REG_ITMP2);
1151 M_INTMOVE(REG_RESULT, d);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1165 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1166 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1172 /* == => 0, < => 1, > => -1 */
1174 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1175 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1176 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1178 M_MOV_IMM(1, REG_ITMP1);
1179 M_MOV_IMM(-1, REG_ITMP2);
1180 emit_ucomiss_reg_reg(cd, s1, s2);
1181 M_CMOVULT(REG_ITMP1, d);
1182 M_CMOVUGT(REG_ITMP2, d);
1183 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1184 emit_store_dst(jd, iptr, d);
1187 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1188 /* == => 0, < => 1, > => -1 */
1190 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1191 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1192 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1194 M_MOV_IMM(1, REG_ITMP1);
1195 M_MOV_IMM(-1, REG_ITMP2);
1196 emit_ucomiss_reg_reg(cd, s1, s2);
1197 M_CMOVULT(REG_ITMP1, d);
1198 M_CMOVUGT(REG_ITMP2, d);
1199 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1204 /* == => 0, < => 1, > => -1 */
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1207 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1208 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1210 M_MOV_IMM(1, REG_ITMP1);
1211 M_MOV_IMM(-1, REG_ITMP2);
1212 emit_ucomisd_reg_reg(cd, s1, s2);
1213 M_CMOVULT(REG_ITMP1, d);
1214 M_CMOVUGT(REG_ITMP2, d);
1215 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1220 /* == => 0, < => 1, > => -1 */
1222 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1224 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1226 M_MOV_IMM(1, REG_ITMP1);
1227 M_MOV_IMM(-1, REG_ITMP2);
1228 emit_ucomisd_reg_reg(cd, s1, s2);
1229 M_CMOVULT(REG_ITMP1, d);
1230 M_CMOVUGT(REG_ITMP2, d);
1231 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1232 emit_store_dst(jd, iptr, d);
1236 /* memory operations **************************************************/
1238 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1240 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1241 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1243 /* implicit null-pointer check */
1244 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1245 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]), s1, s2, 0, d);
1246 emit_store_dst(jd, iptr, d);
1249 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1251 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1252 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1253 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1254 /* implicit null-pointer check */
1255 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1256 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray_t, data[0]), s1, s2, 1, d);
1257 emit_store_dst(jd, iptr, d);
1260 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1265 /* implicit null-pointer check */
1266 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1267 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]), s1, s2, 1, d);
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1273 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1274 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1275 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1276 /* implicit null-pointer check */
1277 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1278 emit_movl_memindex_reg(cd, OFFSET(java_intarray_t, data[0]), s1, s2, 2, d);
1279 emit_store_dst(jd, iptr, d);
1282 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1284 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1285 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1287 /* implicit null-pointer check */
1288 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1289 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]), s1, s2, 3, d);
1290 emit_store_dst(jd, iptr, d);
1293 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1296 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1297 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1298 /* implicit null-pointer check */
1299 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1300 emit_movss_memindex_reg(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2, d);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1308 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1309 /* implicit null-pointer check */
1310 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1311 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray_t, data[0]), s1, s2, 3, d);
1312 emit_store_dst(jd, iptr, d);
1315 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1318 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1319 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1320 /* implicit null-pointer check */
1321 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1322 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]), s1, s2, 3, d);
1323 emit_store_dst(jd, iptr, d);
1327 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1331 /* implicit null-pointer check */
1332 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1333 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1334 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1337 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1340 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1341 /* implicit null-pointer check */
1342 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1343 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1344 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1347 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1351 /* implicit null-pointer check */
1352 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1353 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1354 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1357 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1360 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1361 /* implicit null-pointer check */
1362 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1363 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1364 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1367 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1370 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1371 /* implicit null-pointer check */
1372 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1373 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1374 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1377 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1379 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1380 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1381 /* implicit null-pointer check */
1382 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1383 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1384 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1387 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1389 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1390 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1391 /* implicit null-pointer check */
1392 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1393 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1394 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray_t, data[0]), s1, s2, 3);
1397 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1399 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1400 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1401 /* implicit null-pointer check */
1402 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1403 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1407 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1409 emit_arraystore_check(cd, iptr);
1411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1413 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1414 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1418 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1421 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1422 /* implicit null-pointer check */
1423 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1424 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1427 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1430 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1431 /* implicit null-pointer check */
1432 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1433 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1436 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1440 /* implicit null-pointer check */
1441 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1442 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1445 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1447 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1448 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1449 /* implicit null-pointer check */
1450 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1451 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1454 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1456 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1458 /* implicit null-pointer check */
1459 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1461 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
1462 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1465 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1466 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1470 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1473 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1474 /* implicit null-pointer check */
1475 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1476 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray_t, data[0]), s1, s2, 3);
1479 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1480 /* val = value (in current instruction) */
1481 /* following NOP) */
1483 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1484 uf = iptr->sx.s23.s3.uf;
1485 fieldtype = uf->fieldref->parseddesc.fd->type;
1486 disp = dseg_add_unique_address(cd, uf);
1488 /* PROFILE_CYCLE_STOP; */
1490 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1492 /* PROFILE_CYCLE_START; */
1495 fi = iptr->sx.s23.s3.fmiref->p.field;
1496 fieldtype = fi->type;
1497 disp = dseg_add_address(cd, fi->value);
1499 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1500 //PROFILE_CYCLE_STOP;
1502 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1505 //PROFILE_CYCLE_START;
1509 /* This approach is much faster than moving the field
1510 address inline into a register. */
1512 M_ALD(REG_ITMP1, RIP, disp);
1514 switch (fieldtype) {
1517 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1522 if (IS_IMM32(iptr->sx.s23.s2.constval))
1523 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
1525 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1526 M_LST(REG_ITMP2, REG_ITMP1, 0);
1532 case ICMD_GETFIELD: /* ... ==> ..., value */
1534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1536 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1537 uf = iptr->sx.s23.s3.uf;
1538 fieldtype = uf->fieldref->parseddesc.fd->type;
1541 /* PROFILE_CYCLE_STOP; */
1543 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1545 /* PROFILE_CYCLE_START; */
1548 fi = iptr->sx.s23.s3.fmiref->p.field;
1549 fieldtype = fi->type;
1553 /* implicit null-pointer check */
1554 switch (fieldtype) {
1556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1557 M_ILD32(d, s1, disp);
1561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1562 M_LLD32(d, s1, disp);
1565 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1566 M_FLD32(d, s1, disp);
1569 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1570 M_DLD32(d, s1, disp);
1573 emit_store_dst(jd, iptr, d);
1576 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579 s2 = emit_load_s2(jd, iptr, REG_IFTMP); /* REG_IFTMP == REG_ITMP2 */
1581 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1582 uf = iptr->sx.s23.s3.uf;
1583 fieldtype = uf->fieldref->parseddesc.fd->type;
1586 /* PROFILE_CYCLE_STOP; */
1588 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1590 /* PROFILE_CYCLE_START; */
1593 fi = iptr->sx.s23.s3.fmiref->p.field;
1594 fieldtype = fi->type;
1598 /* implicit null-pointer check */
1599 switch (fieldtype) {
1601 M_IST32(s2, s1, disp);
1605 M_LST32(s2, s1, disp);
1608 M_FST32(s2, s1, disp);
1611 M_DST32(s2, s1, disp);
1616 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
1617 /* val = value (in current instruction) */
1618 /* following NOP) */
1620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1622 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1623 uf = iptr->sx.s23.s3.uf;
1624 fieldtype = uf->fieldref->parseddesc.fd->type;
1627 /* PROFILE_CYCLE_STOP; */
1629 patcher_add_patch_ref(jd, PATCHER_putfieldconst, uf, 0);
1631 /* PROFILE_CYCLE_START; */
1634 fi = iptr->sx.s23.s3.fmiref->p.field;
1635 fieldtype = fi->type;
1639 /* implicit null-pointer check */
1640 switch (fieldtype) {
1643 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
1648 /* XXX why no check for IS_IMM32? -- probably because of the patcher */
1649 M_MOV_IMM(iptr->sx.s23.s2.constval, REG_ITMP2);
1650 if (disp) /* resolved, disp can never be 0 */
1651 M_LST(REG_ITMP2, s1, disp);
1652 else /* unresolved */
1653 M_LST32(REG_ITMP2, s1, disp);
1659 /* branch operations **************************************************/
1661 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1663 M_CALL_IMM(0); /* passing exception pc */
1664 M_POP(REG_ITMP2_XPC);
1666 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
1670 case ICMD_IF_LEQ: /* ..., value ==> ... */
1677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1678 if (IS_IMM32(iptr->sx.val.l))
1679 M_LCMP_IMM(iptr->sx.val.l, s1);
1681 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1682 M_LCMP(REG_ITMP2, s1);
1684 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LEQ, BRANCH_OPT_NONE);
1687 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1688 case ICMD_IF_LCMPNE:
1689 case ICMD_IF_LCMPLT:
1690 case ICMD_IF_LCMPGE:
1691 case ICMD_IF_LCMPGT:
1692 case ICMD_IF_LCMPLE:
1694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1695 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_LCMPEQ, BRANCH_OPT_NONE);
1700 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1703 branch_target_t *table;
1705 table = iptr->dst.table;
1707 l = iptr->sx.s23.s2.tablelow;
1708 i = iptr->sx.s23.s3.tablehigh;
1710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1711 M_INTMOVE(s1, REG_ITMP1);
1714 M_ISUB_IMM(l, REG_ITMP1);
1716 /* number of targets */
1721 M_ICMP_IMM(i - 1, REG_ITMP1);
1722 emit_bugt(cd, table[0].block);
1724 /* build jump table top down and use address of lowest entry */
1729 dseg_add_target(cd, table->block);
1733 /* length of dataseg after last dseg_add_target is used
1736 M_MOV_IMM(0, REG_ITMP2);
1738 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
1744 bte = iptr->sx.s23.s3.bte;
1745 if (bte->stub == NULL) {
1746 M_MOV_IMM(bte->fp, REG_ITMP1);
1749 M_MOV_IMM(bte->stub, REG_ITMP1);
1754 case ICMD_INVOKESPECIAL:
1755 emit_nullpointer_check(cd, iptr, REG_A0);
1758 case ICMD_INVOKESTATIC:
1759 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1760 um = iptr->sx.s23.s3.um;
1761 disp = dseg_add_unique_address(cd, um);
1763 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
1767 lm = iptr->sx.s23.s3.fmiref->p.method;
1768 disp = dseg_add_functionptr(cd, lm->stubroutine);
1771 M_ALD(REG_ITMP2, RIP, disp);
1775 case ICMD_INVOKEVIRTUAL:
1776 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1777 um = iptr->sx.s23.s3.um;
1778 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1783 lm = iptr->sx.s23.s3.fmiref->p.method;
1784 s1 = OFFSET(vftbl_t, table[0]) +
1785 sizeof(methodptr) * lm->vftblindex;
1788 /* implicit null-pointer check */
1789 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
1790 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
1794 case ICMD_INVOKEINTERFACE:
1795 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1796 um = iptr->sx.s23.s3.um;
1797 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1803 lm = iptr->sx.s23.s3.fmiref->p.method;
1804 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1805 sizeof(methodptr) * lm->clazz->index;
1807 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1810 /* implicit null-pointer check */
1811 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
1812 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
1813 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
1817 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1819 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1820 /* object type cast-check */
1825 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1830 super = iptr->sx.s23.s3.c.cls;
1831 superindex = super->index;
1834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1836 /* if class is not resolved, check which code to call */
1838 if (super == NULL) {
1840 emit_label_beq(cd, BRANCH_LABEL_1);
1842 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
1843 iptr->sx.s23.s3.c.ref, 0);
1845 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
1846 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1847 emit_label_beq(cd, BRANCH_LABEL_2);
1850 /* interface checkcast code */
1852 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1853 if (super != NULL) {
1855 emit_label_beq(cd, BRANCH_LABEL_3);
1858 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1860 if (super == NULL) {
1861 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
1862 iptr->sx.s23.s3.c.ref,
1867 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
1868 M_ICMP_IMM32(superindex, REG_ITMP3);
1869 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1871 M_ALD32(REG_ITMP3, REG_ITMP2,
1872 OFFSET(vftbl_t, interfacetable[0]) -
1873 superindex * sizeof(methodptr*));
1875 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
1878 emit_label_br(cd, BRANCH_LABEL_4);
1880 emit_label(cd, BRANCH_LABEL_3);
1883 /* class checkcast code */
1885 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1886 if (super == NULL) {
1887 emit_label(cd, BRANCH_LABEL_2);
1889 constant_classref *cr = iptr->sx.s23.s3.c.ref;
1890 disp = dseg_add_unique_address(cd, cr);
1892 patcher_add_patch_ref(jd,
1893 PATCHER_resolve_classref_to_vftbl,
1898 emit_label_beq(cd, BRANCH_LABEL_5);
1900 disp = dseg_add_address(cd, super->vftbl);
1903 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
1904 M_ALD(REG_ITMP3, RIP, disp);
1906 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
1907 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
1908 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
1909 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
1911 if (super == NULL) {
1912 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
1913 emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
1916 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
1917 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
1918 emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
1920 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
1921 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
1922 emit_label_beq(cd, BRANCH_LABEL_7); /* good */
1924 emit_label(cd, BRANCH_LABEL_9);
1926 emit_label(cd, BRANCH_LABEL_10);
1928 /* reload s1, might have been destroyed */
1929 emit_load_s1(jd, iptr, REG_ITMP1);
1930 M_ALD_MEM(s1, TRAP_ClassCastException);
1932 emit_label(cd, BRANCH_LABEL_7);
1933 emit_label(cd, BRANCH_LABEL_6);
1934 /* reload s1, might have been destroyed */
1935 emit_load_s1(jd, iptr, REG_ITMP1);
1938 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
1939 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
1943 emit_label(cd, BRANCH_LABEL_5);
1946 if (super == NULL) {
1947 emit_label(cd, BRANCH_LABEL_1);
1948 emit_label(cd, BRANCH_LABEL_4);
1951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1954 /* array type cast-check */
1956 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1957 M_INTMOVE(s1, REG_A0);
1959 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1960 constant_classref *cr = iptr->sx.s23.s3.c.ref;
1961 disp = dseg_add_unique_address(cd, cr);
1963 patcher_add_patch_ref(jd,
1964 PATCHER_resolve_classref_to_classinfo,
1968 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
1971 M_ALD(REG_A1, RIP, disp);
1972 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
1975 /* s1 may have been destroyed over the function call */
1976 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1978 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1980 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1984 emit_store_dst(jd, iptr, d);
1987 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1993 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1998 super = iptr->sx.s23.s3.c.cls;
1999 superindex = super->index;
2002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2006 M_INTMOVE(s1, REG_ITMP1);
2012 /* if class is not resolved, check which code to call */
2014 if (super == NULL) {
2016 emit_label_beq(cd, BRANCH_LABEL_1);
2018 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2019 iptr->sx.s23.s3.c.ref, 0);
2021 M_IMOV_IMM(0, REG_ITMP3); /* super->flags */
2022 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2023 emit_label_beq(cd, BRANCH_LABEL_2);
2026 /* interface instanceof code */
2028 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2029 if (super != NULL) {
2031 emit_label_beq(cd, BRANCH_LABEL_3);
2034 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2036 if (super == NULL) {
2037 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2038 iptr->sx.s23.s3.c.ref, 0);
2042 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2043 M_ICMP_IMM32(superindex, REG_ITMP3);
2045 int a = 3 + 4 /* mov_membase32_reg */ + 3 /* test */ + 4 /* setcc */;
2048 M_ALD32(REG_ITMP1, REG_ITMP1,
2049 OFFSET(vftbl_t, interfacetable[0]) -
2050 superindex * sizeof(methodptr*));
2055 emit_label_br(cd, BRANCH_LABEL_4);
2057 emit_label(cd, BRANCH_LABEL_3);
2060 /* class instanceof code */
2062 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2063 if (super == NULL) {
2064 emit_label(cd, BRANCH_LABEL_2);
2066 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2067 disp = dseg_add_unique_address(cd, cr);
2069 patcher_add_patch_ref(jd,
2070 PATCHER_resolve_classref_to_vftbl,
2075 emit_label_beq(cd, BRANCH_LABEL_5);
2077 disp = dseg_add_address(cd, super->vftbl);
2080 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2081 M_ALD(REG_ITMP3, RIP, disp);
2083 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2084 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2085 M_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2086 emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2087 if (d == REG_ITMP2) {
2092 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2093 emit_label(cd, BRANCH_LABEL_8);
2095 if (super == NULL) {
2096 M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2097 emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2100 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2101 M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2102 emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2104 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2105 M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, REG_ITMP3);
2107 if (d == REG_ITMP2) {
2110 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2113 emit_label(cd, BRANCH_LABEL_9);
2115 emit_label(cd, BRANCH_LABEL_10);
2116 if (d == REG_ITMP2) {
2119 emit_label(cd, BRANCH_LABEL_7);
2121 emit_label(cd, BRANCH_LABEL_6);
2124 M_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2131 emit_label(cd, BRANCH_LABEL_5);
2134 if (super == NULL) {
2135 emit_label(cd, BRANCH_LABEL_1);
2136 emit_label(cd, BRANCH_LABEL_4);
2139 emit_store_dst(jd, iptr, d);
2143 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2145 /* check for negative sizes and copy sizes to stack if necessary */
2147 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
2149 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2151 /* copy SAVEDVAR sizes to stack */
2152 var = VAR(iptr->sx.s23.s2.args[s1]);
2154 /* Already Preallocated? */
2155 if (!(var->flags & PREALLOC)) {
2156 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2157 M_LST(s2, REG_SP, s1 * 8);
2161 /* a0 = dimension count */
2163 M_MOV_IMM(iptr->s1.argcount, REG_A0);
2165 /* is a patcher function set? */
2167 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2168 constant_classref *cr = iptr->sx.s23.s3.c.ref;
2169 disp = dseg_add_unique_address(cd, cr);
2171 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2175 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2178 /* a1 = classinfo */
2180 M_ALD(REG_A1, RIP, disp);
2182 /* a2 = pointer to dimensions = stack pointer */
2184 M_MOV(REG_SP, REG_A2);
2186 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2189 /* check for exception before result assignment */
2191 emit_exception_check(cd, iptr);
2193 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2194 M_INTMOVE(REG_RESULT, s1);
2195 emit_store_dst(jd, iptr, s1);
2199 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2204 /* codegen_emit_stub_native ****************************************************
2206 Emits a stub routine which calls a native method.
2208 *******************************************************************************/
2210 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2224 /* Get required compiler data. */
2230 /* initialize variables */
2234 /* calculate stack frame size */
2236 cd->stackframesize =
2237 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2238 sizeof(localref_table) / SIZEOF_VOID_P +
2240 (md->returntype.type == TYPE_VOID ? 0 : 1) +
2243 ALIGN_ODD(cd->stackframesize); /* keep stack 16-byte aligned */
2245 /* create method header */
2247 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2248 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2249 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2250 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2251 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2253 #if defined(ENABLE_PROFILING)
2254 /* generate native method profiling code */
2256 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2257 /* count frequency */
2259 M_MOV_IMM(code, REG_ITMP3);
2260 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
2264 /* generate stub code */
2266 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
2268 #if defined(ENABLE_GC_CACAO)
2269 /* Save callee saved integer registers in stackframeinfo (GC may
2270 need to recover them during a collection). */
2272 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2273 OFFSET(stackframeinfo_t, intregs);
2275 for (i = 0; i < INT_SAV_CNT; i++)
2276 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2279 /* save integer and float argument registers */
2281 for (i = 0; i < md->paramcount; i++) {
2282 if (!md->params[i].inmemory) {
2283 s1 = md->params[i].regoff;
2285 switch (md->paramtypes[i].type) {
2289 M_LST(s1, REG_SP, i * 8);
2293 M_DST(s1, REG_SP, i * 8);
2299 /* create dynamic stack info */
2301 M_MOV(REG_SP, REG_A0);
2302 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2303 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2306 /* remember class argument */
2308 if (m->flags & ACC_STATIC)
2309 M_MOV(REG_RESULT, REG_ITMP2);
2311 /* restore integer and float argument registers */
2313 for (i = 0; i < md->paramcount; i++) {
2314 if (!md->params[i].inmemory) {
2315 s1 = md->params[i].regoff;
2317 switch (md->paramtypes[i].type) {
2321 M_LLD(s1, REG_SP, i * 8);
2325 M_DLD(s1, REG_SP, i * 8);
2331 /* Copy or spill arguments to new locations. */
2333 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2334 s2 = nmd->params[j].regoff;
2336 switch (md->paramtypes[i].type) {
2340 if (!md->params[i].inmemory) {
2341 s1 = md->params[i].regoff;
2343 if (!nmd->params[j].inmemory)
2346 M_LST(s1, REG_SP, s2);
2349 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2350 M_LLD(REG_ITMP1, REG_SP, s1);
2351 M_LST(REG_ITMP1, REG_SP, s2);
2355 /* We only copy spilled float arguments, as the float
2356 argument registers keep unchanged. */
2358 if (md->params[i].inmemory) {
2359 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2361 M_FLD(REG_FTMP1, REG_SP, s1);
2362 M_FST(REG_FTMP1, REG_SP, s2);
2366 if (md->params[i].inmemory) {
2367 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;/* +1 (RA) */
2368 M_DLD(REG_FTMP1, REG_SP, s1);
2369 M_DST(REG_FTMP1, REG_SP, s2);
2375 /* Handle native Java methods. */
2377 if (m->flags & ACC_NATIVE) {
2378 /* put class into second argument register */
2380 if (m->flags & ACC_STATIC)
2381 M_MOV(REG_ITMP2, REG_A1);
2383 /* put env into first argument register */
2385 M_MOV_IMM(VM_get_jnienv(), REG_A0);
2388 /* Call the native function. */
2390 disp = dseg_add_functionptr(cd, f);
2391 M_ALD(REG_ITMP1, RIP, disp);
2394 /* save return value */
2396 switch (md->returntype.type) {
2400 switch (md->returntype.primitivetype) {
2401 case PRIMITIVETYPE_BOOLEAN:
2402 M_BZEXT(REG_RESULT, REG_RESULT);
2404 case PRIMITIVETYPE_BYTE:
2405 M_BSEXT(REG_RESULT, REG_RESULT);
2407 case PRIMITIVETYPE_CHAR:
2408 M_CZEXT(REG_RESULT, REG_RESULT);
2410 case PRIMITIVETYPE_SHORT:
2411 M_SSEXT(REG_RESULT, REG_RESULT);
2414 M_LST(REG_RESULT, REG_SP, 0 * 8);
2418 M_DST(REG_FRESULT, REG_SP, 0 * 8);
2424 /* remove native stackframe info */
2426 M_MOV(REG_SP, REG_A0);
2427 emit_lea_membase_reg(cd, RIP, -((cd->mcodeptr + 7) - cd->mcodebase), REG_A1);
2428 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
2430 M_MOV(REG_RESULT, REG_ITMP3);
2432 /* restore return value */
2434 switch (md->returntype.type) {
2438 M_LLD(REG_RESULT, REG_SP, 0 * 8);
2442 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
2448 #if defined(ENABLE_GC_CACAO)
2449 /* Restore callee saved integer registers from stackframeinfo (GC
2450 might have modified them during a collection). */
2452 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2453 OFFSET(stackframeinfo_t, intregs);
2455 for (i = 0; i < INT_SAV_CNT; i++)
2456 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
2459 /* remove stackframe */
2461 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2463 /* test for exception */
2469 /* handle exception */
2471 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
2472 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
2473 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
2475 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
2481 * These are local overrides for various environment variables in Emacs.
2482 * Please do not remove this and leave it at the end of the file, where
2483 * Emacs will automagically detect them.
2484 * ---------------------------------------------------------------------
2487 * indent-tabs-mode: t
2491 * vim:noexpandtab:sw=4:ts=4: