1 /* src/vm/jit/i386/codegen.c - machine code generator for i386
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
35 #include "vm/jit/i386/md-abi.h"
37 #include "vm/jit/i386/codegen.h"
38 #include "vm/jit/i386/emit.h"
40 #include "mm/memory.hpp"
42 #include "native/localref.hpp"
43 #include "native/native.hpp"
45 #include "threads/lock.hpp"
47 #include "vm/jit/builtin.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/global.h"
50 #include "vm/loader.hpp"
51 #include "vm/options.h"
52 #include "vm/primitive.hpp"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.hpp"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.hpp"
61 #include "vm/jit/jit.hpp"
62 #include "vm/jit/linenumbertable.hpp"
63 #include "vm/jit/parse.hpp"
64 #include "vm/jit/patcher-common.hpp"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/stacktrace.hpp"
67 #include "vm/jit/trap.hpp"
71 * Generates machine code for the method prolog.
73 void codegen_emit_prolog(jitdata* jd)
83 // Get required compiler data.
84 methodinfo* m = jd->m;
85 codegendata* cd = jd->cd;
86 registerdata* rd = jd->rd;
88 /* create stack frame (if necessary) */
90 align_off = cd->stackframesize ? 4 : 0;
92 if (cd->stackframesize) {
93 assert(align_off == 4);
94 M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
97 /* save return address and used callee saved registers */
99 p = cd->stackframesize;
100 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
101 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
103 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
104 p--; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 8);
107 /* take arguments out of register or stack frame */
111 for (p = 0, l = 0; p < md->paramcount; p++) {
112 t = md->paramtypes[p].type;
114 varindex = jd->local_map[l * 5 + t];
115 #if defined(ENABLE_SSA)
117 if (varindex != UNUSED)
118 varindex = ls->var_0[varindex];
119 if ((varindex != UNUSED) && (ls->lifetime[varindex].type == UNUSED))
124 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
127 if (varindex == UNUSED)
131 s1 = md->params[p].regoff;
134 if (IS_INT_LNG_TYPE(t)) { /* integer args */
135 if (!md->params[p].inmemory) { /* register arguments */
136 log_text("integer register argument");
138 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
139 /* rd->argintregs[md->params[p].regoff -> var->vv.regoff */
141 else { /* reg arg -> spilled */
142 /* rd->argintregs[md->params[p].regoff -> var->vv.regoff * 4 */
146 if (!(var->flags & INMEMORY)) {
148 cd->stackframesize * 8 + 4 + align_off + s1);
151 if (!IS_2_WORD_TYPE(t)) {
152 #if defined(ENABLE_SSA)
153 /* no copy avoiding by now possible with SSA */
155 emit_mov_membase_reg( /* + 4 for return address */
157 cd->stackframesize * 8 + s1 + 4 + align_off,
159 emit_mov_reg_membase(
160 cd, REG_ITMP1, REG_SP, var->vv.regoff);
163 #endif /*defined(ENABLE_SSA)*/
164 /* reuse stackslot */
165 var->vv.regoff = cd->stackframesize * 8 + 4 +
170 #if defined(ENABLE_SSA)
171 /* no copy avoiding by now possible with SSA */
173 emit_mov_membase_reg( /* + 4 for return address */
175 cd->stackframesize * 8 + s1 + 4 + align_off,
177 emit_mov_reg_membase(
178 cd, REG_ITMP1, REG_SP, var->vv.regoff);
179 emit_mov_membase_reg( /* + 4 for return address */
181 cd->stackframesize * 8 + s1 + 4 + 4 + align_off,
183 emit_mov_reg_membase(
184 cd, REG_ITMP1, REG_SP, var->vv.regoff + 4);
187 #endif /*defined(ENABLE_SSA)*/
188 /* reuse stackslot */
189 var->vv.regoff = cd->stackframesize * 8 + 8 + s1;
194 else { /* floating args */
195 if (!md->params[p].inmemory) { /* register arguments */
196 log_text("There are no float argument registers!");
198 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
199 /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff */
200 } else { /* reg arg -> spilled */
201 /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff * 8 */
205 else { /* stack arguments */
206 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
210 cd->stackframesize * 8 + s1 + 4 + align_off);
212 /* emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
218 cd->stackframesize * 8 + s1 + 4 + align_off);
220 /* emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
223 } else { /* stack-arg -> spilled */
224 #if defined(ENABLE_SSA)
225 /* no copy avoiding by now possible with SSA */
227 emit_mov_membase_reg(
229 cd->stackframesize * 8 + s1 + 4 + align_off,
231 emit_mov_reg_membase(
232 cd, REG_ITMP1, REG_SP, var->vv.regoff);
236 cd->stackframesize * 8 + s1 + 4 + align_off);
237 emit_fstps_membase(cd, REG_SP, var->vv.regoff);
242 cd->stackframesize * 8 + s1 + 4 + align_off);
243 emit_fstpl_membase(cd, REG_SP, var->vv.regoff);
247 #endif /*defined(ENABLE_SSA)*/
248 /* reuse stackslot */
249 var->vv.regoff = cd->stackframesize * 8 + 4 +
259 * Generates machine code for the method epilog.
261 void codegen_emit_epilog(jitdata* jd)
267 // Get required compiler data.
268 methodinfo* m = jd->m;
269 codegendata* cd = jd->cd;
270 registerdata* rd = jd->rd;
272 p = cd->stackframesize;
275 /* restore saved registers */
277 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
278 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
281 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
283 emit_fldl_membase(cd, REG_SP, p * 8);
284 if (md->returntype.type == TYPE_FLT || md->returntype.type == TYPE_DBL) {
286 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
289 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
293 /* deallocate stack */
295 if (cd->stackframesize)
296 M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
303 * Generates machine code for one ICMD.
305 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
309 builtintable_entry* bte;
310 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
311 unresolved_method* um;
313 unresolved_field* uf;
315 int32_t s1, s2, s3, d;
318 // Get required compiler data.
319 codegendata* cd = jd->cd;
323 /* constant operations ************************************************/
325 case ICMD_FCONST: /* ... ==> ..., constant */
327 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
328 if (iptr->sx.val.f == 0.0) {
332 if (iptr->sx.val.i == 0x80000000) {
336 } else if (iptr->sx.val.f == 1.0) {
339 } else if (iptr->sx.val.f == 2.0) {
345 disp = dseg_add_float(cd, iptr->sx.val.f);
346 emit_mov_imm_reg(cd, 0, REG_ITMP1);
348 emit_flds_membase(cd, REG_ITMP1, disp);
350 emit_store_dst(jd, iptr, d);
353 case ICMD_DCONST: /* ... ==> ..., constant */
355 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
356 if (iptr->sx.val.d == 0.0) {
360 if (iptr->sx.val.l == 0x8000000000000000LL) {
364 } else if (iptr->sx.val.d == 1.0) {
367 } else if (iptr->sx.val.d == 2.0) {
373 disp = dseg_add_double(cd, iptr->sx.val.d);
374 emit_mov_imm_reg(cd, 0, REG_ITMP1);
376 emit_fldl_membase(cd, REG_ITMP1, disp);
378 emit_store_dst(jd, iptr, d);
381 case ICMD_ACONST: /* ... ==> ..., constant */
383 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
385 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
386 patcher_add_patch_ref(jd, PATCHER_aconst,
387 iptr->sx.val.c.ref, 0);
392 if (iptr->sx.val.anyptr == NULL)
395 M_MOV_IMM(iptr->sx.val.anyptr, d);
397 emit_store_dst(jd, iptr, d);
401 /* integer operations *************************************************/
403 case ICMD_INEG: /* ..., value ==> ..., - value */
405 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
406 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
409 emit_store_dst(jd, iptr, d);
412 case ICMD_LNEG: /* ..., value ==> ..., - value */
414 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
417 M_NEG(GET_LOW_REG(d));
418 M_IADDC_IMM(0, GET_HIGH_REG(d));
419 M_NEG(GET_HIGH_REG(d));
420 emit_store_dst(jd, iptr, d);
423 case ICMD_I2L: /* ..., value ==> ..., value */
425 s1 = emit_load_s1(jd, iptr, EAX);
426 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
429 M_LNGMOVE(EAX_EDX_PACKED, d);
430 emit_store_dst(jd, iptr, d);
433 case ICMD_L2I: /* ..., value ==> ..., value */
435 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
436 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
438 emit_store_dst(jd, iptr, d);
441 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
448 emit_store_dst(jd, iptr, d);
451 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
453 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
456 emit_store_dst(jd, iptr, d);
459 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
464 emit_store_dst(jd, iptr, d);
468 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
471 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
472 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
479 emit_store_dst(jd, iptr, d);
483 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
484 /* sx.val.i = constant */
486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
489 /* `inc reg' is slower on p4's (regarding to ia32
490 optimization reference manual and benchmarks) and as
494 M_IADD_IMM(iptr->sx.val.i, d);
495 emit_store_dst(jd, iptr, d);
498 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
500 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
501 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
502 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
503 M_INTMOVE(s1, GET_LOW_REG(d));
504 M_IADD(s2, GET_LOW_REG(d));
505 /* don't use REG_ITMP1 */
506 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
507 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
508 M_INTMOVE(s1, GET_HIGH_REG(d));
509 M_IADDC(s2, GET_HIGH_REG(d));
510 emit_store_dst(jd, iptr, d);
513 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
514 /* sx.val.l = constant */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
519 M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
520 M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
521 emit_store_dst(jd, iptr, d);
524 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
528 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
530 M_INTMOVE(s1, REG_ITMP1);
531 M_ISUB(s2, REG_ITMP1);
532 M_INTMOVE(REG_ITMP1, d);
538 emit_store_dst(jd, iptr, d);
541 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
542 /* sx.val.i = constant */
544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
547 M_ISUB_IMM(iptr->sx.val.i, d);
548 emit_store_dst(jd, iptr, d);
551 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
553 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
554 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
556 if (s2 == GET_LOW_REG(d)) {
557 M_INTMOVE(s1, REG_ITMP1);
558 M_ISUB(s2, REG_ITMP1);
559 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
562 M_INTMOVE(s1, GET_LOW_REG(d));
563 M_ISUB(s2, GET_LOW_REG(d));
565 /* don't use REG_ITMP1 */
566 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
567 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
568 if (s2 == GET_HIGH_REG(d)) {
569 M_INTMOVE(s1, REG_ITMP2);
570 M_ISUBB(s2, REG_ITMP2);
571 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
574 M_INTMOVE(s1, GET_HIGH_REG(d));
575 M_ISUBB(s2, GET_HIGH_REG(d));
577 emit_store_dst(jd, iptr, d);
580 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
581 /* sx.val.l = constant */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
586 M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
587 M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
588 emit_store_dst(jd, iptr, d);
591 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602 emit_store_dst(jd, iptr, d);
605 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
606 /* sx.val.i = constant */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610 M_IMUL_IMM(s1, iptr->sx.val.i, d);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
616 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
617 s2 = emit_load_s2_low(jd, iptr, EDX);
618 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
620 M_INTMOVE(s1, REG_ITMP2);
621 M_IMUL(s2, REG_ITMP2);
623 s1 = emit_load_s1_low(jd, iptr, EAX);
624 s2 = emit_load_s2_high(jd, iptr, EDX);
627 M_IADD(EDX, REG_ITMP2);
629 s1 = emit_load_s1_low(jd, iptr, EAX);
630 s2 = emit_load_s2_low(jd, iptr, EDX);
633 M_INTMOVE(EAX, GET_LOW_REG(d));
634 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
636 emit_store_dst(jd, iptr, d);
639 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
640 /* sx.val.l = constant */
642 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
643 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
644 ICONST(EAX, iptr->sx.val.l);
646 M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
647 M_IADD(REG_ITMP2, EDX);
648 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
649 M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
650 M_IADD(REG_ITMP2, EDX);
651 M_LNGMOVE(EAX_EDX_PACKED, d);
652 emit_store_dst(jd, iptr, d);
655 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
657 s1 = emit_load_s1(jd, iptr, EAX);
658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
659 d = codegen_reg_of_dst(jd, iptr, EAX);
660 emit_arithmetic_check(cd, iptr, s2);
662 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
664 /* check as described in jvm spec */
666 M_CMP_IMM(0x80000000, EAX);
673 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
674 emit_store_dst(jd, iptr, d);
677 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
679 s1 = emit_load_s1(jd, iptr, EAX);
680 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
681 d = codegen_reg_of_dst(jd, iptr, EDX);
682 emit_arithmetic_check(cd, iptr, s2);
684 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
686 /* check as described in jvm spec */
688 M_CMP_IMM(0x80000000, EAX);
696 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
697 emit_store_dst(jd, iptr, d);
700 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
701 /* sx.val.i = constant */
703 /* TODO: optimize for `/ 2' */
704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
705 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
709 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
710 M_SRA_IMM(iptr->sx.val.i, d);
711 emit_store_dst(jd, iptr, d);
714 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
715 /* sx.val.i = constant */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
720 M_MOV(s1, REG_ITMP1);
724 M_AND_IMM(iptr->sx.val.i, d);
726 M_BGE(2 + 2 + 6 + 2);
727 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
729 M_AND_IMM32(iptr->sx.val.i, d); /* use 32-bit for jump offset */
731 emit_store_dst(jd, iptr, d);
734 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
735 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
737 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
738 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
740 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
741 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
742 /* XXX could be optimized */
743 emit_arithmetic_check(cd, iptr, REG_ITMP3);
745 bte = iptr->sx.s23.s3.bte;
747 M_LST(s2, REG_SP, 2 * 4);
749 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
750 M_LST(s1, REG_SP, 0 * 4);
752 M_MOV_IMM(bte->fp, REG_ITMP3);
754 emit_store_dst(jd, iptr, d);
757 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
758 /* sx.val.i = constant */
760 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
761 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
763 M_TEST(GET_HIGH_REG(d));
765 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
766 M_IADDC_IMM(0, GET_HIGH_REG(d));
767 M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
768 M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
769 emit_store_dst(jd, iptr, d);
773 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
774 /* sx.val.l = constant */
776 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
777 if (iptr->dst.var->flags & INMEMORY) {
778 if (iptr->s1.var->flags & INMEMORY) {
779 /* Alpha algorithm */
781 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8);
783 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
789 /* TODO: hmm, don't know if this is always correct */
791 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
793 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
799 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
800 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
802 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
803 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
804 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
805 emit_jcc(cd, CC_GE, disp);
807 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
808 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
810 emit_neg_reg(cd, REG_ITMP1);
811 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
812 emit_neg_reg(cd, REG_ITMP2);
814 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
815 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
817 emit_neg_reg(cd, REG_ITMP1);
818 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
819 emit_neg_reg(cd, REG_ITMP2);
821 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->vv.regoff * 8);
822 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->vv.regoff * 8 + 4);
826 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
827 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
829 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
830 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
831 M_TEST(GET_LOW_REG(s1));
837 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
842 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
845 emit_store_dst(jd, iptr, d);
848 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
849 /* sx.val.i = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
854 M_SLL_IMM(iptr->sx.val.i, d);
855 emit_store_dst(jd, iptr, d);
858 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
861 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
862 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
863 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
866 emit_store_dst(jd, iptr, d);
869 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
870 /* sx.val.i = constant */
872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
875 M_SRA_IMM(iptr->sx.val.i, d);
876 emit_store_dst(jd, iptr, d);
879 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
883 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
884 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
887 emit_store_dst(jd, iptr, d);
890 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
891 /* sx.val.i = constant */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
896 M_SRL_IMM(iptr->sx.val.i, d);
897 emit_store_dst(jd, iptr, d);
900 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
902 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
903 s2 = emit_load_s2(jd, iptr, ECX);
904 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
909 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
910 M_CLR(GET_LOW_REG(d));
911 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
912 M_SLL(GET_LOW_REG(d));
913 emit_store_dst(jd, iptr, d);
916 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
917 /* sx.val.i = constant */
919 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
920 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
922 if (iptr->sx.val.i & 0x20) {
923 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
924 M_CLR(GET_LOW_REG(d));
925 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
929 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
931 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
933 emit_store_dst(jd, iptr, d);
936 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
938 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
939 s2 = emit_load_s2(jd, iptr, ECX);
940 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
945 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
946 M_SRA_IMM(31, GET_HIGH_REG(d));
947 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
948 M_SRA(GET_HIGH_REG(d));
949 emit_store_dst(jd, iptr, d);
952 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
953 /* sx.val.i = constant */
955 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
956 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
958 if (iptr->sx.val.i & 0x20) {
959 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
960 M_SRA_IMM(31, GET_HIGH_REG(d));
961 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
965 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
967 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
969 emit_store_dst(jd, iptr, d);
972 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
974 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
975 s2 = emit_load_s2(jd, iptr, ECX);
976 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
981 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
982 M_CLR(GET_HIGH_REG(d));
983 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
984 M_SRL(GET_HIGH_REG(d));
985 emit_store_dst(jd, iptr, d);
988 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
989 /* sx.val.l = constant */
991 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
994 if (iptr->sx.val.i & 0x20) {
995 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
996 M_CLR(GET_HIGH_REG(d));
997 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1001 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1003 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1005 emit_store_dst(jd, iptr, d);
1008 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1019 emit_store_dst(jd, iptr, d);
1022 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1023 /* sx.val.i = constant */
1025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1028 M_AND_IMM(iptr->sx.val.i, d);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1034 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1035 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1036 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1037 if (s2 == GET_LOW_REG(d))
1038 M_AND(s1, GET_LOW_REG(d));
1040 M_INTMOVE(s1, GET_LOW_REG(d));
1041 M_AND(s2, GET_LOW_REG(d));
1043 /* REG_ITMP1 probably contains low 32-bit of destination */
1044 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1045 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1046 if (s2 == GET_HIGH_REG(d))
1047 M_AND(s1, GET_HIGH_REG(d));
1049 M_INTMOVE(s1, GET_HIGH_REG(d));
1050 M_AND(s2, GET_HIGH_REG(d));
1052 emit_store_dst(jd, iptr, d);
1055 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1056 /* sx.val.l = constant */
1058 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1059 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1061 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1062 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1063 emit_store_dst(jd, iptr, d);
1066 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1069 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1070 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1077 emit_store_dst(jd, iptr, d);
1080 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1081 /* sx.val.i = constant */
1083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1084 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1086 M_OR_IMM(iptr->sx.val.i, d);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1092 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1093 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1094 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1095 if (s2 == GET_LOW_REG(d))
1096 M_OR(s1, GET_LOW_REG(d));
1098 M_INTMOVE(s1, GET_LOW_REG(d));
1099 M_OR(s2, GET_LOW_REG(d));
1101 /* REG_ITMP1 probably contains low 32-bit of destination */
1102 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1103 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1104 if (s2 == GET_HIGH_REG(d))
1105 M_OR(s1, GET_HIGH_REG(d));
1107 M_INTMOVE(s1, GET_HIGH_REG(d));
1108 M_OR(s2, GET_HIGH_REG(d));
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1114 /* sx.val.l = constant */
1116 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1119 M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1120 M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1121 emit_store_dst(jd, iptr, d);
1124 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1127 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1128 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1139 /* sx.val.i = constant */
1141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1144 M_XOR_IMM(iptr->sx.val.i, d);
1145 emit_store_dst(jd, iptr, d);
1148 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1150 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1151 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1152 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1153 if (s2 == GET_LOW_REG(d))
1154 M_XOR(s1, GET_LOW_REG(d));
1156 M_INTMOVE(s1, GET_LOW_REG(d));
1157 M_XOR(s2, GET_LOW_REG(d));
1159 /* REG_ITMP1 probably contains low 32-bit of destination */
1160 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1161 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1162 if (s2 == GET_HIGH_REG(d))
1163 M_XOR(s1, GET_HIGH_REG(d));
1165 M_INTMOVE(s1, GET_HIGH_REG(d));
1166 M_XOR(s2, GET_HIGH_REG(d));
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1172 /* sx.val.l = constant */
1174 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1175 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1177 M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1178 M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1179 emit_store_dst(jd, iptr, d);
1183 /* floating operations ************************************************/
1185 case ICMD_FNEG: /* ..., value ==> ..., - value */
1187 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1188 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_DNEG: /* ..., value ==> ..., - value */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1198 emit_store_dst(jd, iptr, d);
1201 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1203 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1205 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1207 emit_store_dst(jd, iptr, d);
1210 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1212 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1213 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1214 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1221 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1222 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1225 emit_store_dst(jd, iptr, d);
1228 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1230 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1231 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1232 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1234 emit_store_dst(jd, iptr, d);
1237 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1239 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1240 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1241 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1243 emit_store_dst(jd, iptr, d);
1246 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1248 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252 emit_store_dst(jd, iptr, d);
1255 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1257 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1258 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1261 emit_store_dst(jd, iptr, d);
1264 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1266 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1267 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1268 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1275 /* exchanged to skip fxch */
1276 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1277 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 /* emit_fxch(cd); */
1284 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1285 emit_store_dst(jd, iptr, d);
1286 emit_ffree_reg(cd, 0);
1290 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1292 /* exchanged to skip fxch */
1293 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1295 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 /* emit_fxch(cd); */
1301 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1302 emit_store_dst(jd, iptr, d);
1303 emit_ffree_reg(cd, 0);
1307 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1308 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1310 var = VAROP(iptr->s1);
1311 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1313 if (var->flags & INMEMORY) {
1314 emit_fildl_membase(cd, REG_SP, var->vv.regoff);
1316 /* XXX not thread safe! */
1317 disp = dseg_add_unique_s4(cd, 0);
1318 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1320 emit_mov_reg_membase(cd, var->vv.regoff, REG_ITMP1, disp);
1321 emit_fildl_membase(cd, REG_ITMP1, disp);
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1328 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1330 var = VAROP(iptr->s1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1332 if (var->flags & INMEMORY) {
1333 emit_fildll_membase(cd, REG_SP, var->vv.regoff);
1336 log_text("L2F: longs have to be in memory");
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1344 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1345 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1347 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1350 /* Round to zero, 53-bit mode, exception masked */
1351 disp = dseg_add_s4(cd, 0x0e7f);
1352 emit_fldcw_membase(cd, REG_ITMP1, disp);
1354 var = VAROP(iptr->dst);
1355 var1 = VAROP(iptr->s1);
1357 if (var->flags & INMEMORY) {
1358 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1360 /* Round to nearest, 53-bit mode, exceptions masked */
1361 disp = dseg_add_s4(cd, 0x027f);
1362 emit_fldcw_membase(cd, REG_ITMP1, disp);
1364 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1365 REG_SP, var->vv.regoff);
1368 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1370 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1373 /* XXX not thread safe! */
1374 disp = dseg_add_unique_s4(cd, 0);
1375 emit_fistpl_membase(cd, REG_ITMP1, disp);
1376 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1378 /* Round to nearest, 53-bit mode, exceptions masked */
1379 disp = dseg_add_s4(cd, 0x027f);
1380 emit_fldcw_membase(cd, REG_ITMP1, disp);
1382 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1385 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1386 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1389 emit_jcc(cd, CC_NE, disp);
1391 /* XXX: change this when we use registers */
1392 emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1393 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1394 emit_call_reg(cd, REG_ITMP1);
1396 if (var->flags & INMEMORY) {
1397 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1400 M_INTMOVE(REG_RESULT, var->vv.regoff);
1404 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1406 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1407 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1409 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1412 /* Round to zero, 53-bit mode, exception masked */
1413 disp = dseg_add_s4(cd, 0x0e7f);
1414 emit_fldcw_membase(cd, REG_ITMP1, disp);
1416 var = VAROP(iptr->dst);
1417 var1 = VAROP(iptr->s1);
1419 if (var->flags & INMEMORY) {
1420 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1422 /* Round to nearest, 53-bit mode, exceptions masked */
1423 disp = dseg_add_s4(cd, 0x027f);
1424 emit_fldcw_membase(cd, REG_ITMP1, disp);
1426 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1427 REG_SP, var->vv.regoff);
1430 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1432 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1435 /* XXX not thread safe! */
1436 disp = dseg_add_unique_s4(cd, 0);
1437 emit_fistpl_membase(cd, REG_ITMP1, disp);
1438 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1440 /* Round to nearest, 53-bit mode, exceptions masked */
1441 disp = dseg_add_s4(cd, 0x027f);
1442 emit_fldcw_membase(cd, REG_ITMP1, disp);
1444 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1447 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1448 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1451 emit_jcc(cd, CC_NE, disp);
1453 /* XXX: change this when we use registers */
1454 emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1455 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1456 emit_call_reg(cd, REG_ITMP1);
1458 if (var->flags & INMEMORY) {
1459 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1461 M_INTMOVE(REG_RESULT, var->vv.regoff);
1465 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1467 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1468 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1470 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1473 /* Round to zero, 53-bit mode, exception masked */
1474 disp = dseg_add_s4(cd, 0x0e7f);
1475 emit_fldcw_membase(cd, REG_ITMP1, disp);
1477 var = VAROP(iptr->dst);
1478 var1 = VAROP(iptr->s1);
1480 if (var->flags & INMEMORY) {
1481 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1483 /* Round to nearest, 53-bit mode, exceptions masked */
1484 disp = dseg_add_s4(cd, 0x027f);
1485 emit_fldcw_membase(cd, REG_ITMP1, disp);
1487 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1488 REG_SP, var->vv.regoff + 4);
1491 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1493 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1496 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1498 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1500 emit_jcc(cd, CC_NE, disp);
1502 emit_alu_imm_membase(cd, ALU_CMP, 0,
1503 REG_SP, var->vv.regoff);
1506 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1508 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1510 emit_jcc(cd, CC_NE, disp);
1512 /* XXX: change this when we use registers */
1513 emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1514 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
1515 emit_call_reg(cd, REG_ITMP1);
1516 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1517 emit_mov_reg_membase(cd, REG_RESULT2,
1518 REG_SP, var->vv.regoff + 4);
1521 log_text("F2L: longs have to be in memory");
1526 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1528 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1529 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1531 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1534 /* Round to zero, 53-bit mode, exception masked */
1535 disp = dseg_add_s4(cd, 0x0e7f);
1536 emit_fldcw_membase(cd, REG_ITMP1, disp);
1538 var = VAROP(iptr->dst);
1539 var1 = VAROP(iptr->s1);
1541 if (var->flags & INMEMORY) {
1542 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1544 /* Round to nearest, 53-bit mode, exceptions masked */
1545 disp = dseg_add_s4(cd, 0x027f);
1546 emit_fldcw_membase(cd, REG_ITMP1, disp);
1548 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1549 REG_SP, var->vv.regoff + 4);
1552 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1554 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1557 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1559 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1561 emit_jcc(cd, CC_NE, disp);
1563 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->vv.regoff);
1566 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1568 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1570 emit_jcc(cd, CC_NE, disp);
1572 /* XXX: change this when we use registers */
1573 emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1574 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
1575 emit_call_reg(cd, REG_ITMP1);
1576 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1577 emit_mov_reg_membase(cd, REG_RESULT2,
1578 REG_SP, var->vv.regoff + 4);
1581 log_text("D2L: longs have to be in memory");
1586 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1588 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1589 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1591 emit_store_dst(jd, iptr, d);
1594 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1596 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1597 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1599 emit_store_dst(jd, iptr, d);
1602 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1605 /* exchanged to skip fxch */
1606 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1607 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1608 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1609 /* emit_fxch(cd); */
1612 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
1613 emit_jcc(cd, CC_E, 6);
1614 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
1616 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
1617 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1618 emit_jcc(cd, CC_B, 3 + 5);
1619 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1620 emit_jmp_imm(cd, 3);
1621 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1622 emit_store_dst(jd, iptr, d);
1625 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1628 /* exchanged to skip fxch */
1629 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1630 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1631 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1632 /* emit_fxch(cd); */
1635 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
1636 emit_jcc(cd, CC_E, 3);
1637 emit_movb_imm_reg(cd, 1, REG_AH);
1639 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
1640 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1641 emit_jcc(cd, CC_B, 3 + 5);
1642 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1643 emit_jmp_imm(cd, 3);
1644 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1645 emit_store_dst(jd, iptr, d);
1649 /* memory operations **************************************************/
1651 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1656 /* implicit null-pointer check */
1657 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1658 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]),
1660 emit_store_dst(jd, iptr, d);
1663 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1668 /* implicit null-pointer check */
1669 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1670 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray_t, data[0]),
1672 emit_store_dst(jd, iptr, d);
1675 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1679 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1680 /* implicit null-pointer check */
1681 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1682 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]),
1684 emit_store_dst(jd, iptr, d);
1687 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1692 /* implicit null-pointer check */
1693 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1694 emit_mov_memindex_reg(cd, OFFSET(java_intarray_t, data[0]),
1696 emit_store_dst(jd, iptr, d);
1699 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1703 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1704 /* implicit null-pointer check */
1705 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1707 var = VAROP(iptr->dst);
1709 assert(var->flags & INMEMORY);
1710 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]),
1711 s1, s2, 3, REG_ITMP3);
1712 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff);
1713 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]) + 4,
1714 s1, s2, 3, REG_ITMP3);
1715 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff + 4);
1718 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1722 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1723 /* implicit null-pointer check */
1724 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1725 emit_flds_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1726 emit_store_dst(jd, iptr, d);
1729 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1733 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1734 /* implicit null-pointer check */
1735 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1736 emit_fldl_memindex(cd, OFFSET(java_doublearray_t, data[0]), s1, s2,3);
1737 emit_store_dst(jd, iptr, d);
1740 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1745 /* implicit null-pointer check */
1746 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1747 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]),
1749 emit_store_dst(jd, iptr, d);
1753 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1756 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1757 /* implicit null-pointer check */
1758 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1759 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1761 /* because EBP, ESI, EDI have no xH and xL nibbles */
1762 M_INTMOVE(s3, REG_ITMP3);
1765 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]),
1769 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1772 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773 /* implicit null-pointer check */
1774 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1775 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1776 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]),
1780 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1784 /* implicit null-pointer check */
1785 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1786 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1787 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]),
1791 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795 /* implicit null-pointer check */
1796 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1797 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1798 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]),
1802 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1806 /* implicit null-pointer check */
1807 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1809 var = VAROP(iptr->sx.s23.s3);
1811 assert(var->flags & INMEMORY);
1812 emit_mov_membase_reg(cd, REG_SP, var->vv.regoff, REG_ITMP3);
1813 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray_t, data[0])
1815 emit_mov_membase_reg(cd, REG_SP, var->vv.regoff + 4, REG_ITMP3);
1816 emit_mov_reg_memindex(cd, REG_ITMP3,
1817 OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1820 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1823 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1824 /* implicit null-pointer check */
1825 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1826 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1827 emit_fstps_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2,2);
1830 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1834 /* implicit null-pointer check */
1835 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1836 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1837 emit_fstpl_memindex(cd, OFFSET(java_doublearray_t, data[0]),
1841 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1843 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1844 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1845 /* implicit null-pointer check */
1846 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1847 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1849 M_AST(s1, REG_SP, 0 * 4);
1850 M_AST(s3, REG_SP, 1 * 4);
1851 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
1853 emit_arraystore_check(cd, iptr);
1855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1856 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1857 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1858 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]),
1862 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1866 /* implicit null-pointer check */
1867 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1868 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
1869 OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
1872 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1875 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1876 /* implicit null-pointer check */
1877 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1878 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
1879 OFFSET(java_chararray_t, data[0]), s1, s2, 1);
1882 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1886 /* implicit null-pointer check */
1887 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1888 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
1889 OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
1892 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1896 /* implicit null-pointer check */
1897 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1898 emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
1899 OFFSET(java_intarray_t, data[0]), s1, s2, 2);
1902 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1905 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1906 /* implicit null-pointer check */
1907 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1908 emit_mov_imm_memindex(cd,
1909 (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
1910 OFFSET(java_longarray_t, data[0]), s1, s2, 3);
1911 emit_mov_imm_memindex(cd,
1912 ((s4)iptr->sx.s23.s3.constval) >> 31,
1913 OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
1916 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1920 /* implicit null-pointer check */
1921 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1922 emit_mov_imm_memindex(cd, 0,
1923 OFFSET(java_objectarray_t, data[0]), s1, s2, 2);
1927 case ICMD_GETSTATIC: /* ... ==> ..., value */
1929 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1930 uf = iptr->sx.s23.s3.uf;
1931 fieldtype = uf->fieldref->parseddesc.fd->type;
1934 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1938 fi = iptr->sx.s23.s3.fmiref->p.field;
1939 fieldtype = fi->type;
1940 disp = (intptr_t) fi->value;
1942 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1943 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
1946 M_MOV_IMM2(disp, REG_ITMP1);
1947 switch (fieldtype) {
1950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1951 M_ILD(d, REG_ITMP1, 0);
1954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1955 M_LLD(d, REG_ITMP1, 0);
1958 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1959 M_FLD(d, REG_ITMP1, 0);
1962 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1963 M_DLD(d, REG_ITMP1, 0);
1966 emit_store_dst(jd, iptr, d);
1969 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1971 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1972 uf = iptr->sx.s23.s3.uf;
1973 fieldtype = uf->fieldref->parseddesc.fd->type;
1976 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1979 fi = iptr->sx.s23.s3.fmiref->p.field;
1980 fieldtype = fi->type;
1981 disp = (intptr_t) fi->value;
1983 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1984 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
1987 M_MOV_IMM2(disp, REG_ITMP1);
1988 switch (fieldtype) {
1991 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1992 M_IST(s1, REG_ITMP1, 0);
1995 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1996 M_LST(s1, REG_ITMP1, 0);
1999 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2000 emit_fstps_membase(cd, REG_ITMP1, 0);
2003 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2004 emit_fstpl_membase(cd, REG_ITMP1, 0);
2009 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2010 /* val = value (in current instruction) */
2011 /* following NOP) */
2013 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2014 uf = iptr->sx.s23.s3.uf;
2015 fieldtype = uf->fieldref->parseddesc.fd->type;
2018 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2021 fi = iptr->sx.s23.s3.fmiref->p.field;
2022 fieldtype = fi->type;
2023 disp = (intptr_t) fi->value;
2025 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2026 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
2029 M_MOV_IMM2(disp, REG_ITMP1);
2030 switch (fieldtype) {
2033 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2036 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2037 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2044 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2047 emit_nullpointer_check(cd, iptr, s1);
2049 #if defined(ENABLE_ESCAPE_CHECK)
2050 /*emit_escape_check(cd, s1);*/
2053 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2054 uf = iptr->sx.s23.s3.uf;
2055 fieldtype = uf->fieldref->parseddesc.fd->type;
2058 patcher_add_patch_ref(jd, PATCHER_getfield,
2059 iptr->sx.s23.s3.uf, 0);
2062 fi = iptr->sx.s23.s3.fmiref->p.field;
2063 fieldtype = fi->type;
2067 switch (fieldtype) {
2070 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2071 M_ILD32(d, s1, disp);
2074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2075 M_LLD32(d, s1, disp);
2078 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2079 M_FLD32(d, s1, disp);
2082 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2083 M_DLD32(d, s1, disp);
2086 emit_store_dst(jd, iptr, d);
2089 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2092 emit_nullpointer_check(cd, iptr, s1);
2094 /* must be done here because of code patching */
2096 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2097 uf = iptr->sx.s23.s3.uf;
2098 fieldtype = uf->fieldref->parseddesc.fd->type;
2101 fi = iptr->sx.s23.s3.fmiref->p.field;
2102 fieldtype = fi->type;
2105 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2106 if (IS_2_WORD_TYPE(fieldtype))
2107 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2109 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2112 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2114 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2116 uf = iptr->sx.s23.s3.uf;
2119 patcher_add_patch_ref(jd, PATCHER_putfield, uf, 0);
2123 fi = iptr->sx.s23.s3.fmiref->p.field;
2127 switch (fieldtype) {
2130 M_IST32(s2, s1, disp);
2133 M_LST32(s2, s1, disp);
2136 emit_fstps_membase32(cd, s1, disp);
2139 emit_fstpl_membase32(cd, s1, disp);
2144 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2145 /* val = value (in current instruction) */
2146 /* following NOP) */
2148 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2149 emit_nullpointer_check(cd, iptr, s1);
2151 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2152 uf = iptr->sx.s23.s3.uf;
2153 fieldtype = uf->fieldref->parseddesc.fd->type;
2156 patcher_add_patch_ref(jd, PATCHER_putfieldconst,
2160 fi = iptr->sx.s23.s3.fmiref->p.field;
2161 fieldtype = fi->type;
2165 switch (fieldtype) {
2168 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2171 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2172 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2180 /* branch operations **************************************************/
2182 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2184 M_CALL_IMM(0); /* passing exception pc */
2185 M_POP(REG_ITMP2_XPC);
2187 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2191 case ICMD_IF_LEQ: /* ..., value ==> ... */
2193 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2194 if (iptr->sx.val.l == 0) {
2195 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2196 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2199 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2200 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2201 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2202 M_OR(REG_ITMP2, REG_ITMP1);
2204 emit_beq(cd, iptr->dst.block);
2207 case ICMD_IF_LLT: /* ..., value ==> ... */
2209 if (iptr->sx.val.l == 0) {
2210 /* If high 32-bit are less than zero, then the 64-bits
2212 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2214 emit_blt(cd, iptr->dst.block);
2217 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2218 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2219 emit_blt(cd, iptr->dst.block);
2221 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2222 emit_bult(cd, iptr->dst.block);
2226 case ICMD_IF_LLE: /* ..., value ==> ... */
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2229 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2230 emit_blt(cd, iptr->dst.block);
2232 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2233 emit_bule(cd, iptr->dst.block);
2236 case ICMD_IF_LNE: /* ..., value ==> ... */
2238 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2239 if (iptr->sx.val.l == 0) {
2240 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2241 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2244 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2245 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2246 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2247 M_OR(REG_ITMP2, REG_ITMP1);
2249 emit_bne(cd, iptr->dst.block);
2252 case ICMD_IF_LGT: /* ..., value ==> ... */
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2255 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2256 emit_bgt(cd, iptr->dst.block);
2258 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2259 emit_bugt(cd, iptr->dst.block);
2262 case ICMD_IF_LGE: /* ..., value ==> ... */
2264 if (iptr->sx.val.l == 0) {
2265 /* If high 32-bit are greater equal zero, then the
2267 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2269 emit_bge(cd, iptr->dst.block);
2272 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2273 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2274 emit_bgt(cd, iptr->dst.block);
2276 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2277 emit_buge(cd, iptr->dst.block);
2281 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2283 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2284 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2285 M_INTMOVE(s1, REG_ITMP1);
2286 M_XOR(s2, REG_ITMP1);
2287 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2288 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2289 M_INTMOVE(s1, REG_ITMP2);
2290 M_XOR(s2, REG_ITMP2);
2291 M_OR(REG_ITMP1, REG_ITMP2);
2292 emit_beq(cd, iptr->dst.block);
2295 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2297 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2298 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2299 M_INTMOVE(s1, REG_ITMP1);
2300 M_XOR(s2, REG_ITMP1);
2301 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2302 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2303 M_INTMOVE(s1, REG_ITMP2);
2304 M_XOR(s2, REG_ITMP2);
2305 M_OR(REG_ITMP1, REG_ITMP2);
2306 emit_bne(cd, iptr->dst.block);
2309 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2311 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2312 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2314 emit_blt(cd, iptr->dst.block);
2315 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2316 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2319 emit_bult(cd, iptr->dst.block);
2322 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2324 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2325 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2327 emit_bgt(cd, iptr->dst.block);
2328 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2329 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2332 emit_bugt(cd, iptr->dst.block);
2335 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2337 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2338 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2340 emit_blt(cd, iptr->dst.block);
2341 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2342 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2345 emit_bule(cd, iptr->dst.block);
2348 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2350 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2351 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2353 emit_bgt(cd, iptr->dst.block);
2354 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2355 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2358 emit_buge(cd, iptr->dst.block);
2361 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2364 branch_target_t *table;
2366 table = iptr->dst.table;
2368 l = iptr->sx.s23.s2.tablelow;
2369 i = iptr->sx.s23.s3.tablehigh;
2371 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2372 M_INTMOVE(s1, REG_ITMP1);
2375 M_ISUB_IMM(l, REG_ITMP1);
2381 M_CMP_IMM(i - 1, REG_ITMP1);
2382 emit_bugt(cd, table[0].block);
2384 /* build jump table top down and use address of lowest entry */
2389 dseg_add_target(cd, table->block);
2393 /* length of dataseg after last dseg_addtarget is used
2396 M_MOV_IMM(0, REG_ITMP2);
2398 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2404 bte = iptr->sx.s23.s3.bte;
2405 if (bte->stub == NULL) {
2406 M_MOV_IMM(bte->fp, REG_ITMP1);
2409 M_MOV_IMM(bte->stub, REG_ITMP1);
2413 #if defined(ENABLE_ESCAPE_CHECK)
2414 if (bte->opcode == ICMD_NEW || bte->opcode == ICMD_NEWARRAY) {
2415 /*emit_escape_annotate_object(cd, m);*/
2420 case ICMD_INVOKESPECIAL:
2421 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2422 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2425 case ICMD_INVOKESTATIC:
2426 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2427 um = iptr->sx.s23.s3.um;
2429 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2435 lm = iptr->sx.s23.s3.fmiref->p.method;
2436 disp = (ptrint) lm->stubroutine;
2439 M_MOV_IMM2(disp, REG_ITMP2);
2443 case ICMD_INVOKEVIRTUAL:
2444 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2445 emit_nullpointer_check(cd, iptr, s1);
2447 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2448 um = iptr->sx.s23.s3.um;
2450 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2455 lm = iptr->sx.s23.s3.fmiref->p.method;
2456 s1 = OFFSET(vftbl_t, table[0]) +
2457 sizeof(methodptr) * lm->vftblindex;
2460 M_ALD(REG_METHODPTR, REG_ITMP1,
2461 OFFSET(java_object_t, vftbl));
2462 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
2466 case ICMD_INVOKEINTERFACE:
2467 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2468 emit_nullpointer_check(cd, iptr, s1);
2470 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2471 um = iptr->sx.s23.s3.um;
2473 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2479 lm = iptr->sx.s23.s3.fmiref->p.method;
2480 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2481 sizeof(methodptr) * lm->clazz->index;
2483 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2486 M_ALD(REG_METHODPTR, REG_ITMP1,
2487 OFFSET(java_object_t, vftbl));
2488 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
2489 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
2493 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2495 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2496 /* object type cast-check */
2499 vftbl_t *supervftbl;
2502 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2508 super = iptr->sx.s23.s3.c.cls;
2509 superindex = super->index;
2510 supervftbl = super->vftbl;
2513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2515 /* if class is not resolved, check which code to call */
2517 if (super == NULL) {
2519 emit_label_beq(cd, BRANCH_LABEL_1);
2521 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
2522 iptr->sx.s23.s3.c.ref, 0);
2524 M_MOV_IMM2(0, REG_ITMP2); /* super->flags */
2525 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
2526 emit_label_beq(cd, BRANCH_LABEL_2);
2529 /* interface checkcast code */
2531 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2532 if (super != NULL) {
2534 emit_label_beq(cd, BRANCH_LABEL_3);
2537 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2539 if (super == NULL) {
2540 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
2541 iptr->sx.s23.s3.c.ref,
2546 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2547 M_ISUB_IMM32(superindex, REG_ITMP3);
2548 /* XXX do we need this one? */
2550 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2552 M_ALD32(REG_ITMP3, REG_ITMP2,
2553 OFFSET(vftbl_t, interfacetable[0]) -
2554 superindex * sizeof(methodptr*));
2556 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2559 emit_label_br(cd, BRANCH_LABEL_4);
2561 emit_label(cd, BRANCH_LABEL_3);
2564 /* class checkcast code */
2566 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2567 if (super == NULL) {
2568 emit_label(cd, BRANCH_LABEL_2);
2572 emit_label_beq(cd, BRANCH_LABEL_5);
2575 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2576 if (super == NULL) {
2577 patcher_add_patch_ref(jd, PATCHER_checkcast_class,
2578 iptr->sx.s23.s3.c.ref,
2581 M_MOV_IMM2(supervftbl, REG_ITMP3);
2583 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2584 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2585 M_CMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2586 emit_label_beq(cd, BRANCH_LABEL_6); /* good */
2588 if (super == NULL) {
2589 M_ICMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2590 emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
2593 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2594 M_CMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2595 emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
2597 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2598 M_CMP_MEMINDEX(REG_ITMP2, -4*DISPLAY_SIZE, REG_ITMP1, 2, REG_ITMP3);
2599 emit_label_beq(cd, BRANCH_LABEL_7); /* good */
2601 emit_label(cd, BRANCH_LABEL_9);
2603 emit_label(cd, BRANCH_LABEL_10);
2605 /* reload s1, might have been destroyed */
2606 emit_load_s1(jd, iptr, REG_ITMP1);
2607 M_ALD_MEM(s1, TRAP_ClassCastException);
2609 emit_label(cd, BRANCH_LABEL_7);
2610 emit_label(cd, BRANCH_LABEL_6);
2611 /* reload s1, might have been destroyed */
2612 emit_load_s1(jd, iptr, REG_ITMP1);
2615 M_CMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2617 emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
2621 emit_label(cd, BRANCH_LABEL_5);
2624 if (super == NULL) {
2625 emit_label(cd, BRANCH_LABEL_1);
2626 emit_label(cd, BRANCH_LABEL_4);
2629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
2632 /* array type cast-check */
2634 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2635 M_AST(s1, REG_SP, 0 * 4);
2637 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2638 patcher_add_patch_ref(jd, PATCHER_builtin_arraycheckcast,
2639 iptr->sx.s23.s3.c.ref, 0);
2642 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
2643 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
2646 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2648 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2650 d = codegen_reg_of_dst(jd, iptr, s1);
2654 emit_store_dst(jd, iptr, d);
2657 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2661 vftbl_t *supervftbl;
2664 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2670 super = iptr->sx.s23.s3.c.cls;
2671 superindex = super->index;
2672 supervftbl = super->vftbl;
2675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2679 M_INTMOVE(s1, REG_ITMP1);
2685 /* if class is not resolved, check which code to call */
2687 if (super == NULL) {
2689 emit_label_beq(cd, BRANCH_LABEL_1);
2691 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
2692 iptr->sx.s23.s3.c.ref, 0);
2694 M_MOV_IMM2(0, REG_ITMP3); /* super->flags */
2695 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
2696 emit_label_beq(cd, BRANCH_LABEL_2);
2699 /* interface instanceof code */
2701 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2702 if (super != NULL) {
2704 emit_label_beq(cd, BRANCH_LABEL_3);
2707 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2709 if (super == NULL) {
2710 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
2711 iptr->sx.s23.s3.c.ref, 0);
2715 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2716 M_ISUB_IMM32(superindex, REG_ITMP3);
2719 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
2720 6 /* jcc */ + 5 /* mov_imm_reg */);
2723 M_ALD32(REG_ITMP1, REG_ITMP1,
2724 OFFSET(vftbl_t, interfacetable[0]) -
2725 superindex * sizeof(methodptr*));
2727 /* emit_setcc_reg(cd, CC_A, d); */
2728 /* emit_jcc(cd, CC_BE, 5); */
2733 emit_label_br(cd, BRANCH_LABEL_4);
2735 emit_label(cd, BRANCH_LABEL_3);
2738 /* class instanceof code */
2740 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2741 if (super == NULL) {
2742 emit_label(cd, BRANCH_LABEL_2);
2746 emit_label_beq(cd, BRANCH_LABEL_5);
2749 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2750 if (super == NULL) {
2751 patcher_add_patch_ref(jd, PATCHER_instanceof_class,
2752 iptr->sx.s23.s3.c.ref, 0);
2754 M_MOV_IMM2(supervftbl, REG_ITMP3);
2756 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2757 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2758 M_CMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
2759 emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */
2760 if (d == REG_ITMP2) {
2765 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2766 emit_label(cd, BRANCH_LABEL_8);
2768 if (super == NULL) {
2769 M_ICMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2770 emit_label_bne(cd, BRANCH_LABEL_10); /* false */
2773 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2774 M_CMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
2775 emit_label_bgt(cd, BRANCH_LABEL_9); /* false */
2777 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2778 M_CMP_MEMINDEX(REG_ITMP2, -4*DISPLAY_SIZE, REG_ITMP1, 2, REG_ITMP3);
2781 M_BSEXT(REG_ITMP1, d);
2785 if (d == REG_ITMP2) {
2788 emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */
2792 emit_label(cd, BRANCH_LABEL_9);
2794 emit_label(cd, BRANCH_LABEL_10);
2795 if (d == REG_ITMP2) {
2798 emit_label(cd, BRANCH_LABEL_7);
2800 emit_label(cd, BRANCH_LABEL_6);
2803 M_CMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
2807 M_BSEXT(REG_ITMP1, d);
2817 emit_label(cd, BRANCH_LABEL_5);
2820 if (super == NULL) {
2821 emit_label(cd, BRANCH_LABEL_1);
2822 emit_label(cd, BRANCH_LABEL_4);
2825 emit_store_dst(jd, iptr, d);
2829 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2831 /* check for negative sizes and copy sizes to stack if necessary */
2833 MCODECHECK((iptr->s1.argcount << 1) + 64);
2835 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2836 /* copy SAVEDVAR sizes to stack */
2837 var = VAR(iptr->sx.s23.s2.args[s1]);
2839 /* Already Preallocated? */
2840 if (!(var->flags & PREALLOC)) {
2841 if (var->flags & INMEMORY) {
2842 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff);
2843 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
2846 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
2850 /* is a patcher function set? */
2852 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2853 patcher_add_patch_ref(jd, PATCHER_builtin_multianewarray,
2854 iptr->sx.s23.s3.c.ref, 0);
2860 disp = (ptrint) iptr->sx.s23.s3.c.cls;
2862 /* a0 = dimension count */
2864 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
2866 /* a1 = arraydescriptor */
2868 M_IST_IMM(disp, REG_SP, 1 * 4);
2870 /* a2 = pointer to dimensions = stack pointer */
2872 M_MOV(REG_SP, REG_ITMP1);
2873 M_AADD_IMM(3 * 4, REG_ITMP1);
2874 M_AST(REG_ITMP1, REG_SP, 2 * 4);
2876 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
2879 /* check for exception before result assignment */
2881 emit_exception_check(cd, iptr);
2883 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2884 M_INTMOVE(REG_RESULT, s1);
2885 emit_store_dst(jd, iptr, s1);
2889 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
2894 /* codegen_emit_stub_native ****************************************************
2896 Emits a stub routine which calls a native method.
2898 *******************************************************************************/
2900 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2906 int i, j; /* count variables */
2910 /* get required compiler data */
2916 /* set some variables */
2920 /* calculate stackframe size */
2922 cd->stackframesize =
2923 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2924 sizeof(localref_table) / SIZEOF_VOID_P +
2925 4 + /* 4 arguments (start_native_call) */
2928 /* keep stack 16-byte aligned */
2930 ALIGN_ODD(cd->stackframesize);
2932 /* create method header */
2934 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2935 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2936 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2937 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2938 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2940 #if defined(ENABLE_PROFILING)
2941 /* generate native method profiling code */
2943 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
2944 /* count frequency */
2946 M_MOV_IMM(code, REG_ITMP1);
2947 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
2951 /* calculate stackframe size for native function */
2953 M_ASUB_IMM(cd->stackframesize * 8 + 4, REG_SP);
2955 /* Mark the whole fpu stack as free for native functions (only for saved */
2956 /* register count == 0). */
2958 emit_ffree_reg(cd, 0);
2959 emit_ffree_reg(cd, 1);
2960 emit_ffree_reg(cd, 2);
2961 emit_ffree_reg(cd, 3);
2962 emit_ffree_reg(cd, 4);
2963 emit_ffree_reg(cd, 5);
2964 emit_ffree_reg(cd, 6);
2965 emit_ffree_reg(cd, 7);
2967 #if defined(ENABLE_GC_CACAO)
2968 /* remember callee saved int registers in stackframeinfo (GC may need to */
2969 /* recover them during a collection). */
2971 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2972 OFFSET(stackframeinfo_t, intregs);
2974 for (i = 0; i < INT_SAV_CNT; i++)
2975 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
2978 /* prepare data structures for native function call */
2980 M_MOV(REG_SP, REG_ITMP1);
2981 M_AST(REG_ITMP1, REG_SP, 0 * 4);
2982 M_IST_IMM(0, REG_SP, 1 * 4);
2985 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
2988 /* remember class argument */
2990 if (m->flags & ACC_STATIC)
2991 M_MOV(REG_RESULT, REG_ITMP3);
2993 /* Copy or spill arguments to new locations. */
2995 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2996 if (!md->params[i].inmemory)
2999 s1 = md->params[i].regoff + cd->stackframesize * 8 + 8;
3000 s2 = nmd->params[j].regoff;
3002 /* float/double in memory can be copied like int/longs */
3004 switch (md->paramtypes[i].type) {
3008 M_ILD(REG_ITMP1, REG_SP, s1);
3009 M_IST(REG_ITMP1, REG_SP, s2);
3013 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3014 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3019 /* Handle native Java methods. */
3021 if (m->flags & ACC_NATIVE) {
3022 /* if function is static, put class into second argument */
3024 if (m->flags & ACC_STATIC)
3025 M_AST(REG_ITMP3, REG_SP, 1 * 4);
3027 /* put env into first argument */
3029 M_AST_IMM(VM_get_jnienv(), REG_SP, 0 * 4);
3032 /* Call the native function. */
3034 disp = dseg_add_functionptr(cd, f);
3035 emit_mov_imm_reg(cd, 0, REG_ITMP3);
3037 M_ALD(REG_ITMP1, REG_ITMP3, disp);
3040 /* save return value */
3042 switch (md->returntype.type) {
3045 switch (md->returntype.primitivetype) {
3046 case PRIMITIVETYPE_BOOLEAN:
3047 M_BZEXT(REG_RESULT, REG_RESULT);
3049 case PRIMITIVETYPE_BYTE:
3050 M_BSEXT(REG_RESULT, REG_RESULT);
3052 case PRIMITIVETYPE_CHAR:
3053 M_CZEXT(REG_RESULT, REG_RESULT);
3055 case PRIMITIVETYPE_SHORT:
3056 M_SSEXT(REG_RESULT, REG_RESULT);
3059 M_IST(REG_RESULT, REG_SP, 1 * 8);
3062 M_LST(REG_RESULT_PACKED, REG_SP, 1 * 8);
3065 emit_fsts_membase(cd, REG_SP, 1 * 8);
3068 emit_fstl_membase(cd, REG_SP, 1 * 8);
3074 /* remove native stackframe info */
3076 M_MOV(REG_SP, REG_ITMP1);
3077 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3078 M_IST_IMM(0, REG_SP, 1 * 4);
3081 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3083 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
3085 /* restore return value */
3087 switch (md->returntype.type) {
3090 M_ILD(REG_RESULT, REG_SP, 1 * 8);
3093 M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 8);
3096 emit_flds_membase(cd, REG_SP, 1 * 8);
3099 emit_fldl_membase(cd, REG_SP, 1 * 8);
3105 #if defined(ENABLE_GC_CACAO)
3106 /* restore callee saved int registers from stackframeinfo (GC might have */
3107 /* modified them during a collection). */
3109 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3110 OFFSET(stackframeinfo_t, intregs);
3112 for (i = 0; i < INT_SAV_CNT; i++)
3113 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3116 M_AADD_IMM(cd->stackframesize * 8 + 4, REG_SP);
3118 /* check for exception */
3125 /* handle exception */
3127 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3128 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3129 M_ASUB_IMM(2, REG_ITMP2_XPC);
3131 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3137 * These are local overrides for various environment variables in Emacs.
3138 * Please do not remove this and leave it at the end of the file, where
3139 * Emacs will automagically detect them.
3140 * ---------------------------------------------------------------------
3143 * indent-tabs-mode: t
3147 * vim:noexpandtab:sw=4:ts=4: