1 /* src/vm/jit/i386/codegen.c - machine code generator for i386
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "vm/jit/i386/md-abi.h"
38 #include "vm/jit/i386/codegen.h"
39 #include "vm/jit/i386/emit.h"
41 #include "mm/memory.h"
42 #include "native/jni.h"
43 #include "native/localref.h"
44 #include "native/native.h"
46 #include "threads/lock-common.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
51 #include "vm/stringlocal.h"
54 #include "vm/jit/abi.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher-common.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
64 #include "vm/jit/stacktrace.h"
66 #if defined(ENABLE_SSA)
67 # include "vm/jit/optimizing/lsra.h"
68 # include "vm/jit/optimizing/ssa.h"
69 #elif defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
75 #include "vmcore/utf8.h"
78 /* codegen_emit ****************************************************************
80 Generates machine code.
82 *******************************************************************************/
84 bool codegen_emit(jitdata *jd)
90 s4 len, s1, s2, s3, d, disp;
96 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
97 builtintable_entry *bte;
100 unresolved_field *uf;
103 #if defined(ENABLE_SSA)
105 bool last_cmd_was_goto;
107 last_cmd_was_goto = false;
111 /* get required compiler data */
118 /* prevent compiler warnings */
129 s4 savedregs_num = 0;
132 /* space to save used callee saved registers */
134 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
135 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
137 cd->stackframesize = rd->memuse + savedregs_num;
140 #if defined(ENABLE_THREADS)
141 /* space to save argument of monitor_enter */
143 if (checksync && (m->flags & ACC_SYNCHRONIZED))
144 cd->stackframesize++;
147 /* create method header */
149 /* Keep stack of non-leaf functions 16-byte aligned. */
151 if (!code_is_leafmethod(code)) {
152 ALIGN_ODD(cd->stackframesize); /* XXX this is wrong, +4 is missing */
155 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
156 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
158 #if defined(ENABLE_THREADS)
159 /* IsSync contains the offset relative to the stack pointer for the
160 argument of monitor_exit used in the exception handler. Since the
161 offset could be zero and give a wrong meaning of the flag it is
165 if (checksync && (m->flags & ACC_SYNCHRONIZED))
166 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
169 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
171 if (code_is_leafmethod(code))
172 (void) dseg_add_unique_s4(cd, 1); /* IsLeaf */
174 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
176 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
177 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
179 /* adds a reference for the length of the line number counter. We don't
180 know the size yet, since we evaluate the information during code
181 generation, to save one additional iteration over the whole
182 instructions. During code optimization the position could have changed
183 to the information gotten from the class file */
184 (void) dseg_addlinenumbertablesize(cd);
186 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
188 /* create exception table */
190 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
191 dseg_add_target(cd, ex->start);
192 dseg_add_target(cd, ex->end);
193 dseg_add_target(cd, ex->handler);
194 (void) dseg_add_unique_address(cd, ex->catchtype.any);
197 #if defined(ENABLE_PROFILING)
198 /* generate method profiling code */
200 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
201 /* count frequency */
203 M_MOV_IMM(code, REG_ITMP3);
204 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
208 /* create stack frame (if necessary) */
210 if (cd->stackframesize)
211 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
213 /* save return address and used callee saved registers */
215 p = cd->stackframesize;
216 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
217 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
219 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
220 p--; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 8);
223 /* take arguments out of register or stack frame */
228 for (p = 0, l = 0; p < md->paramcount; p++) {
229 t = md->paramtypes[p].type;
231 varindex = jd->local_map[l * 5 + t];
232 #if defined(ENABLE_SSA)
234 if (varindex != UNUSED)
235 varindex = ls->var_0[varindex];
236 if ((varindex != UNUSED) && (ls->lifetime[varindex].type == UNUSED))
241 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
244 if (varindex == UNUSED)
248 s1 = md->params[p].regoff;
251 if (IS_INT_LNG_TYPE(t)) { /* integer args */
252 if (!md->params[p].inmemory) { /* register arguments */
253 log_text("integer register argument");
255 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
256 /* rd->argintregs[md->params[p].regoff -> var->vv.regoff */
258 else { /* reg arg -> spilled */
259 /* rd->argintregs[md->params[p].regoff -> var->vv.regoff * 4 */
263 if (!(var->flags & INMEMORY)) {
264 M_ILD(d, REG_SP, cd->stackframesize * 8 + 4 + s1);
267 if (!IS_2_WORD_TYPE(t)) {
268 #if defined(ENABLE_SSA)
269 /* no copy avoiding by now possible with SSA */
271 emit_mov_membase_reg( /* + 4 for return address */
272 cd, REG_SP, cd->stackframesize * 8 + s1 + 4,
274 emit_mov_reg_membase(
275 cd, REG_ITMP1, REG_SP, var->vv.regoff);
278 #endif /*defined(ENABLE_SSA)*/
279 /* reuse stackslot */
280 var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
284 #if defined(ENABLE_SSA)
285 /* no copy avoiding by now possible with SSA */
287 emit_mov_membase_reg( /* + 4 for return address */
288 cd, REG_SP, cd->stackframesize * 8 + s1 + 4,
290 emit_mov_reg_membase(
291 cd, REG_ITMP1, REG_SP, var->vv.regoff);
292 emit_mov_membase_reg( /* + 4 for return address */
293 cd, REG_SP, cd->stackframesize * 8 + s1 + 4 + 4,
295 emit_mov_reg_membase(
296 cd, REG_ITMP1, REG_SP, var->vv.regoff + 4);
299 #endif /*defined(ENABLE_SSA)*/
300 /* reuse stackslot */
301 var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
306 else { /* floating args */
307 if (!md->params[p].inmemory) { /* register arguments */
308 log_text("There are no float argument registers!");
310 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
311 /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff */
312 } else { /* reg arg -> spilled */
313 /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff * 8 */
317 else { /* stack arguments */
318 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
321 cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
323 /* emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
328 cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
330 /* emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
333 } else { /* stack-arg -> spilled */
334 #if defined(ENABLE_SSA)
335 /* no copy avoiding by now possible with SSA */
337 emit_mov_membase_reg(
338 cd, REG_SP, cd->stackframesize * 8 + s1 + 4, REG_ITMP1);
339 emit_mov_reg_membase(
340 cd, REG_ITMP1, REG_SP, var->vv.regoff);
343 cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
344 emit_fstps_membase(cd, REG_SP, var->vv.regoff);
348 cd, REG_SP, cd->stackframesize * 8 + s1 + 4);
349 emit_fstpl_membase(cd, REG_SP, var->vv.regoff);
353 #endif /*defined(ENABLE_SSA)*/
354 /* reuse stackslot */
355 var->vv.regoff = cd->stackframesize * 8 + 4 + s1;
361 /* call monitorenter function */
363 #if defined(ENABLE_THREADS)
364 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
367 if (m->flags & ACC_STATIC) {
368 M_MOV_IMM(&m->class->object.header, REG_ITMP1);
371 M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + 4);
374 M_ALD_MEM(REG_ITMP1, EXCEPTION_HARDWARE_NULLPOINTER);
377 M_AST(REG_ITMP1, REG_SP, s1 * 8);
378 M_AST(REG_ITMP1, REG_SP, 0 * 4);
379 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
385 emit_verbosecall_enter(jd);
390 #if defined(ENABLE_SSA)
391 /* with SSA the Header is Basic Block 0 - insert phi Moves if necessary */
393 codegen_emit_phi_moves(jd, ls->basicblocks[0]);
396 /* end of header generation */
398 /* create replacement points */
400 REPLACEMENT_POINTS_INIT(cd, jd);
402 /* walk through all basic blocks */
404 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
406 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
408 if (bptr->flags >= BBREACHED) {
409 /* branch resolving */
411 codegen_resolve_branchrefs(cd, bptr);
413 /* handle replacement points */
415 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
417 #if defined(ENABLE_REPLACEMENT)
418 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
419 if (cd->replacementpoint[-1].flags & RPLPOINT_FLAG_COUNTDOWN) {
421 disp = (s4) &(m->hitcountdown);
422 M_ISUB_IMM_MEMABS(1, disp);
428 /* copy interface registers to their destination */
433 #if defined(ENABLE_PROFILING)
434 /* generate basic block profiling code */
436 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
437 /* count frequency */
439 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
440 M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
444 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
445 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
448 # if defined(ENABLE_SSA)
450 last_cmd_was_goto = false;
454 var = VAR(bptr->invars[len]);
455 if (bptr->type != BBTYPE_STD) {
456 if (!IS_2_WORD_TYPE(var->type)) {
457 if (bptr->type == BBTYPE_EXH) {
458 d = codegen_reg_of_var(0, var, REG_ITMP1);
459 M_INTMOVE(REG_ITMP1, d);
460 emit_store(jd, NULL, var, d);
464 log_text("copy interface registers(EXH, SBR): longs \
465 have to be in memory (begin 1)");
473 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
477 var = VAR(bptr->invars[len]);
478 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
479 if (!IS_2_WORD_TYPE(var->type)) {
480 if (bptr->type == BBTYPE_EXH) {
481 d = codegen_reg_of_var(0, var, REG_ITMP1);
482 M_INTMOVE(REG_ITMP1, d);
483 emit_store(jd, NULL, var, d);
487 log_text("copy interface registers: longs have to be in \
494 assert((var->flags & INOUT));
499 /* walk through all instructions */
504 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
505 if (iptr->line != currentline) {
506 dseg_addlinenumber(cd, iptr->line);
507 currentline = iptr->line;
510 MCODECHECK(1024); /* 1kB should be enough */
513 case ICMD_NOP: /* ... ==> ... */
514 case ICMD_POP: /* ..., value ==> ... */
515 case ICMD_POP2: /* ..., value, value ==> ... */
518 case ICMD_INLINE_START:
520 REPLACEMENT_POINT_INLINE_START(cd, iptr);
523 case ICMD_INLINE_BODY:
525 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
526 dseg_addlinenumber_inline_start(cd, iptr);
527 dseg_addlinenumber(cd, iptr->line);
530 case ICMD_INLINE_END:
532 dseg_addlinenumber_inline_end(cd, iptr);
533 dseg_addlinenumber(cd, iptr->line);
536 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539 emit_nullpointer_check(cd, iptr, s1);
542 /* constant operations ************************************************/
544 case ICMD_ICONST: /* ... ==> ..., constant */
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
547 ICONST(d, iptr->sx.val.i);
548 emit_store_dst(jd, iptr, d);
551 case ICMD_LCONST: /* ... ==> ..., constant */
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
554 LCONST(d, iptr->sx.val.l);
555 emit_store_dst(jd, iptr, d);
558 case ICMD_FCONST: /* ... ==> ..., constant */
560 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
561 if (iptr->sx.val.f == 0.0) {
565 if (iptr->sx.val.i == 0x80000000) {
569 } else if (iptr->sx.val.f == 1.0) {
572 } else if (iptr->sx.val.f == 2.0) {
578 disp = dseg_add_float(cd, iptr->sx.val.f);
579 emit_mov_imm_reg(cd, 0, REG_ITMP1);
581 emit_flds_membase(cd, REG_ITMP1, disp);
583 emit_store_dst(jd, iptr, d);
586 case ICMD_DCONST: /* ... ==> ..., constant */
588 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
589 if (iptr->sx.val.d == 0.0) {
593 if (iptr->sx.val.l == 0x8000000000000000LL) {
597 } else if (iptr->sx.val.d == 1.0) {
600 } else if (iptr->sx.val.d == 2.0) {
606 disp = dseg_add_double(cd, iptr->sx.val.d);
607 emit_mov_imm_reg(cd, 0, REG_ITMP1);
609 emit_fldl_membase(cd, REG_ITMP1, disp);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_ACONST: /* ... ==> ..., constant */
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
618 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
619 patcher_add_patch_ref(jd, PATCHER_aconst,
620 iptr->sx.val.c.ref, 0);
625 if (iptr->sx.val.anyptr == NULL)
628 M_MOV_IMM(iptr->sx.val.anyptr, d);
630 emit_store_dst(jd, iptr, d);
634 /* load/store/copy/move operations ************************************/
652 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
657 /* integer operations *************************************************/
659 case ICMD_INEG: /* ..., value ==> ..., - value */
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
665 emit_store_dst(jd, iptr, d);
668 case ICMD_LNEG: /* ..., value ==> ..., - value */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
673 M_NEG(GET_LOW_REG(d));
674 M_IADDC_IMM(0, GET_HIGH_REG(d));
675 M_NEG(GET_HIGH_REG(d));
676 emit_store_dst(jd, iptr, d);
679 case ICMD_I2L: /* ..., value ==> ..., value */
681 s1 = emit_load_s1(jd, iptr, EAX);
682 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
685 M_LNGMOVE(EAX_EDX_PACKED, d);
686 emit_store_dst(jd, iptr, d);
689 case ICMD_L2I: /* ..., value ==> ..., value */
691 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
712 emit_store_dst(jd, iptr, d);
715 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
720 emit_store_dst(jd, iptr, d);
724 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
728 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
735 emit_store_dst(jd, iptr, d);
739 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
740 /* sx.val.i = constant */
742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
745 /* `inc reg' is slower on p4's (regarding to ia32
746 optimization reference manual and benchmarks) and as
750 M_IADD_IMM(iptr->sx.val.i, d);
751 emit_store_dst(jd, iptr, d);
754 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
756 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
757 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
759 M_INTMOVE(s1, GET_LOW_REG(d));
760 M_IADD(s2, GET_LOW_REG(d));
761 /* don't use REG_ITMP1 */
762 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
763 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
764 M_INTMOVE(s1, GET_HIGH_REG(d));
765 M_IADDC(s2, GET_HIGH_REG(d));
766 emit_store_dst(jd, iptr, d);
769 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
770 /* sx.val.l = constant */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
775 M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
776 M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
777 emit_store_dst(jd, iptr, d);
780 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
786 M_INTMOVE(s1, REG_ITMP1);
787 M_ISUB(s2, REG_ITMP1);
788 M_INTMOVE(REG_ITMP1, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
798 /* sx.val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
803 M_ISUB_IMM(iptr->sx.val.i, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
809 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
810 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
812 if (s2 == GET_LOW_REG(d)) {
813 M_INTMOVE(s1, REG_ITMP1);
814 M_ISUB(s2, REG_ITMP1);
815 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
818 M_INTMOVE(s1, GET_LOW_REG(d));
819 M_ISUB(s2, GET_LOW_REG(d));
821 /* don't use REG_ITMP1 */
822 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
823 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
824 if (s2 == GET_HIGH_REG(d)) {
825 M_INTMOVE(s1, REG_ITMP2);
826 M_ISUBB(s2, REG_ITMP2);
827 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
830 M_INTMOVE(s1, GET_HIGH_REG(d));
831 M_ISUBB(s2, GET_HIGH_REG(d));
833 emit_store_dst(jd, iptr, d);
836 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
837 /* sx.val.l = constant */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
842 M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
843 M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
844 emit_store_dst(jd, iptr, d);
847 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
858 emit_store_dst(jd, iptr, d);
861 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
862 /* sx.val.i = constant */
864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 M_IMUL_IMM(s1, iptr->sx.val.i, d);
867 emit_store_dst(jd, iptr, d);
870 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
872 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
873 s2 = emit_load_s2_low(jd, iptr, EDX);
874 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
876 M_INTMOVE(s1, REG_ITMP2);
877 M_IMUL(s2, REG_ITMP2);
879 s1 = emit_load_s1_low(jd, iptr, EAX);
880 s2 = emit_load_s2_high(jd, iptr, EDX);
883 M_IADD(EDX, REG_ITMP2);
885 s1 = emit_load_s1_low(jd, iptr, EAX);
886 s2 = emit_load_s2_low(jd, iptr, EDX);
889 M_INTMOVE(EAX, GET_LOW_REG(d));
890 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
892 emit_store_dst(jd, iptr, d);
895 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
896 /* sx.val.l = constant */
898 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
899 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
900 ICONST(EAX, iptr->sx.val.l);
902 M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
903 M_IADD(REG_ITMP2, EDX);
904 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
905 M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
906 M_IADD(REG_ITMP2, EDX);
907 M_LNGMOVE(EAX_EDX_PACKED, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
913 s1 = emit_load_s1(jd, iptr, EAX);
914 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
915 d = codegen_reg_of_dst(jd, iptr, EAX);
916 emit_arithmetic_check(cd, iptr, s2);
918 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
920 /* check as described in jvm spec */
922 M_CMP_IMM(0x80000000, EAX);
929 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
930 emit_store_dst(jd, iptr, d);
933 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
935 s1 = emit_load_s1(jd, iptr, EAX);
936 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
937 d = codegen_reg_of_dst(jd, iptr, EDX);
938 emit_arithmetic_check(cd, iptr, s2);
940 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
942 /* check as described in jvm spec */
944 M_CMP_IMM(0x80000000, EAX);
952 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
953 emit_store_dst(jd, iptr, d);
956 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
957 /* sx.val.i = constant */
959 /* TODO: optimize for `/ 2' */
960 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
961 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
965 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
966 M_SRA_IMM(iptr->sx.val.i, d);
967 emit_store_dst(jd, iptr, d);
970 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
971 /* sx.val.i = constant */
973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
976 M_MOV(s1, REG_ITMP1);
980 M_AND_IMM(iptr->sx.val.i, d);
982 M_BGE(2 + 2 + 6 + 2);
983 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
985 M_AND_IMM32(iptr->sx.val.i, d); /* use 32-bit for jump offset */
987 emit_store_dst(jd, iptr, d);
990 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
991 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
993 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
994 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
996 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
997 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
998 /* XXX could be optimized */
999 emit_arithmetic_check(cd, iptr, REG_ITMP3);
1001 bte = iptr->sx.s23.s3.bte;
1004 M_LST(s2, REG_SP, 2 * 4);
1006 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1007 M_LST(s1, REG_SP, 0 * 4);
1009 M_MOV_IMM(bte->fp, REG_ITMP3);
1011 emit_store_dst(jd, iptr, d);
1014 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1015 /* sx.val.i = constant */
1017 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1018 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1020 M_TEST(GET_HIGH_REG(d));
1022 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
1023 M_IADDC_IMM(0, GET_HIGH_REG(d));
1024 M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1025 M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
1026 emit_store_dst(jd, iptr, d);
1030 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1031 /* sx.val.l = constant */
1033 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1034 if (iptr->dst.var->flags & INMEMORY) {
1035 if (iptr->s1.var->flags & INMEMORY) {
1036 /* Alpha algorithm */
1038 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8);
1040 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
1046 /* TODO: hmm, don't know if this is always correct */
1048 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
1050 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
1056 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
1057 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
1059 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1060 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1061 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->vv.regoff * 8 + 4);
1062 emit_jcc(cd, CC_GE, disp);
1064 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8, REG_ITMP1);
1065 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 8 + 4, REG_ITMP2);
1067 emit_neg_reg(cd, REG_ITMP1);
1068 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1069 emit_neg_reg(cd, REG_ITMP2);
1071 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1072 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1074 emit_neg_reg(cd, REG_ITMP1);
1075 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1076 emit_neg_reg(cd, REG_ITMP2);
1078 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->vv.regoff * 8);
1079 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->vv.regoff * 8 + 4);
1083 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1084 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1086 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1087 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1088 M_TEST(GET_LOW_REG(s1));
1094 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1096 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1097 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1098 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1099 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1106 /* sx.val.i = constant */
1108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1111 M_SLL_IMM(iptr->sx.val.i, d);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1119 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1120 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1123 emit_store_dst(jd, iptr, d);
1126 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1127 /* sx.val.i = constant */
1129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1132 M_SRA_IMM(iptr->sx.val.i, d);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1141 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1144 emit_store_dst(jd, iptr, d);
1147 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1148 /* sx.val.i = constant */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1153 M_SRL_IMM(iptr->sx.val.i, d);
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1159 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1160 s2 = emit_load_s2(jd, iptr, ECX);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1164 M_TEST_IMM(32, ECX);
1166 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1167 M_CLR(GET_LOW_REG(d));
1168 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1169 M_SLL(GET_LOW_REG(d));
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1174 /* sx.val.i = constant */
1176 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1179 if (iptr->sx.val.i & 0x20) {
1180 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1181 M_CLR(GET_LOW_REG(d));
1182 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1186 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1188 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1196 s2 = emit_load_s2(jd, iptr, ECX);
1197 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1200 M_TEST_IMM(32, ECX);
1202 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1203 M_SRA_IMM(31, GET_HIGH_REG(d));
1204 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1205 M_SRA(GET_HIGH_REG(d));
1206 emit_store_dst(jd, iptr, d);
1209 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1210 /* sx.val.i = constant */
1212 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1213 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1215 if (iptr->sx.val.i & 0x20) {
1216 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1217 M_SRA_IMM(31, GET_HIGH_REG(d));
1218 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1222 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1224 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1231 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1232 s2 = emit_load_s2(jd, iptr, ECX);
1233 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1236 M_TEST_IMM(32, ECX);
1238 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1239 M_CLR(GET_HIGH_REG(d));
1240 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1241 M_SRL(GET_HIGH_REG(d));
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1246 /* sx.val.l = constant */
1248 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1251 if (iptr->sx.val.i & 0x20) {
1252 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1253 M_CLR(GET_HIGH_REG(d));
1254 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1258 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1260 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1262 emit_store_dst(jd, iptr, d);
1265 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1268 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1269 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1276 emit_store_dst(jd, iptr, d);
1279 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1280 /* sx.val.i = constant */
1282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1283 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1285 M_AND_IMM(iptr->sx.val.i, d);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1291 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1292 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1294 if (s2 == GET_LOW_REG(d))
1295 M_AND(s1, GET_LOW_REG(d));
1297 M_INTMOVE(s1, GET_LOW_REG(d));
1298 M_AND(s2, GET_LOW_REG(d));
1300 /* REG_ITMP1 probably contains low 32-bit of destination */
1301 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1302 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1303 if (s2 == GET_HIGH_REG(d))
1304 M_AND(s1, GET_HIGH_REG(d));
1306 M_INTMOVE(s1, GET_HIGH_REG(d));
1307 M_AND(s2, GET_HIGH_REG(d));
1309 emit_store_dst(jd, iptr, d);
1312 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1313 /* sx.val.l = constant */
1315 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1318 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1319 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1326 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1338 /* sx.val.i = constant */
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1343 M_OR_IMM(iptr->sx.val.i, d);
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1349 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1350 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1351 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1352 if (s2 == GET_LOW_REG(d))
1353 M_OR(s1, GET_LOW_REG(d));
1355 M_INTMOVE(s1, GET_LOW_REG(d));
1356 M_OR(s2, GET_LOW_REG(d));
1358 /* REG_ITMP1 probably contains low 32-bit of destination */
1359 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1360 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1361 if (s2 == GET_HIGH_REG(d))
1362 M_OR(s1, GET_HIGH_REG(d));
1364 M_INTMOVE(s1, GET_HIGH_REG(d));
1365 M_OR(s2, GET_HIGH_REG(d));
1367 emit_store_dst(jd, iptr, d);
1370 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1371 /* sx.val.l = constant */
1373 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1376 M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1377 M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1378 emit_store_dst(jd, iptr, d);
1381 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1384 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1392 emit_store_dst(jd, iptr, d);
1395 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1396 /* sx.val.i = constant */
1398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1401 M_XOR_IMM(iptr->sx.val.i, d);
1402 emit_store_dst(jd, iptr, d);
1405 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1407 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1408 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1410 if (s2 == GET_LOW_REG(d))
1411 M_XOR(s1, GET_LOW_REG(d));
1413 M_INTMOVE(s1, GET_LOW_REG(d));
1414 M_XOR(s2, GET_LOW_REG(d));
1416 /* REG_ITMP1 probably contains low 32-bit of destination */
1417 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1418 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1419 if (s2 == GET_HIGH_REG(d))
1420 M_XOR(s1, GET_HIGH_REG(d));
1422 M_INTMOVE(s1, GET_HIGH_REG(d));
1423 M_XOR(s2, GET_HIGH_REG(d));
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1429 /* sx.val.l = constant */
1431 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1432 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1434 M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1435 M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1436 emit_store_dst(jd, iptr, d);
1440 /* floating operations ************************************************/
1442 case ICMD_FNEG: /* ..., value ==> ..., - value */
1444 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1445 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1447 emit_store_dst(jd, iptr, d);
1450 case ICMD_DNEG: /* ..., value ==> ..., - value */
1452 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1455 emit_store_dst(jd, iptr, d);
1458 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1461 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1462 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1464 emit_store_dst(jd, iptr, d);
1467 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1469 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1470 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1473 emit_store_dst(jd, iptr, d);
1476 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1479 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1480 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1482 emit_store_dst(jd, iptr, d);
1485 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1487 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1488 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1489 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1491 emit_store_dst(jd, iptr, d);
1494 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1496 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1497 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1498 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1505 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1506 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1509 emit_store_dst(jd, iptr, d);
1512 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1514 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1515 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1518 emit_store_dst(jd, iptr, d);
1521 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1523 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1524 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1525 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1527 emit_store_dst(jd, iptr, d);
1530 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1532 /* exchanged to skip fxch */
1533 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1534 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1535 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1536 /* emit_fxch(cd); */
1541 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1542 emit_store_dst(jd, iptr, d);
1543 emit_ffree_reg(cd, 0);
1547 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1549 /* exchanged to skip fxch */
1550 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1551 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1552 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1553 /* emit_fxch(cd); */
1558 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1559 emit_store_dst(jd, iptr, d);
1560 emit_ffree_reg(cd, 0);
1564 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1565 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1567 var = VAROP(iptr->s1);
1568 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1570 if (var->flags & INMEMORY) {
1571 emit_fildl_membase(cd, REG_SP, var->vv.regoff);
1573 /* XXX not thread safe! */
1574 disp = dseg_add_unique_s4(cd, 0);
1575 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1577 emit_mov_reg_membase(cd, var->vv.regoff, REG_ITMP1, disp);
1578 emit_fildl_membase(cd, REG_ITMP1, disp);
1581 emit_store_dst(jd, iptr, d);
1584 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1585 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1587 var = VAROP(iptr->s1);
1588 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1589 if (var->flags & INMEMORY) {
1590 emit_fildll_membase(cd, REG_SP, var->vv.regoff);
1593 log_text("L2F: longs have to be in memory");
1596 emit_store_dst(jd, iptr, d);
1599 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1601 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1602 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1604 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1607 /* Round to zero, 53-bit mode, exception masked */
1608 disp = dseg_add_s4(cd, 0x0e7f);
1609 emit_fldcw_membase(cd, REG_ITMP1, disp);
1611 var = VAROP(iptr->dst);
1612 var1 = VAROP(iptr->s1);
1614 if (var->flags & INMEMORY) {
1615 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1617 /* Round to nearest, 53-bit mode, exceptions masked */
1618 disp = dseg_add_s4(cd, 0x027f);
1619 emit_fldcw_membase(cd, REG_ITMP1, disp);
1621 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1622 REG_SP, var->vv.regoff);
1625 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1627 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1630 /* XXX not thread safe! */
1631 disp = dseg_add_unique_s4(cd, 0);
1632 emit_fistpl_membase(cd, REG_ITMP1, disp);
1633 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1635 /* Round to nearest, 53-bit mode, exceptions masked */
1636 disp = dseg_add_s4(cd, 0x027f);
1637 emit_fldcw_membase(cd, REG_ITMP1, disp);
1639 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1642 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1643 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1646 emit_jcc(cd, CC_NE, disp);
1648 /* XXX: change this when we use registers */
1649 emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1650 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1651 emit_call_reg(cd, REG_ITMP1);
1653 if (var->flags & INMEMORY) {
1654 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1657 M_INTMOVE(REG_RESULT, var->vv.regoff);
1661 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1663 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1664 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1666 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1669 /* Round to zero, 53-bit mode, exception masked */
1670 disp = dseg_add_s4(cd, 0x0e7f);
1671 emit_fldcw_membase(cd, REG_ITMP1, disp);
1673 var = VAROP(iptr->dst);
1674 var1 = VAROP(iptr->s1);
1676 if (var->flags & INMEMORY) {
1677 emit_fistpl_membase(cd, REG_SP, var->vv.regoff);
1679 /* Round to nearest, 53-bit mode, exceptions masked */
1680 disp = dseg_add_s4(cd, 0x027f);
1681 emit_fldcw_membase(cd, REG_ITMP1, disp);
1683 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1684 REG_SP, var->vv.regoff);
1687 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1689 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1692 /* XXX not thread safe! */
1693 disp = dseg_add_unique_s4(cd, 0);
1694 emit_fistpl_membase(cd, REG_ITMP1, disp);
1695 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1697 /* Round to nearest, 53-bit mode, exceptions masked */
1698 disp = dseg_add_s4(cd, 0x027f);
1699 emit_fldcw_membase(cd, REG_ITMP1, disp);
1701 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1704 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1705 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1708 emit_jcc(cd, CC_NE, disp);
1710 /* XXX: change this when we use registers */
1711 emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1712 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1713 emit_call_reg(cd, REG_ITMP1);
1715 if (var->flags & INMEMORY) {
1716 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1718 M_INTMOVE(REG_RESULT, var->vv.regoff);
1722 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1724 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1725 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1727 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1730 /* Round to zero, 53-bit mode, exception masked */
1731 disp = dseg_add_s4(cd, 0x0e7f);
1732 emit_fldcw_membase(cd, REG_ITMP1, disp);
1734 var = VAROP(iptr->dst);
1735 var1 = VAROP(iptr->s1);
1737 if (var->flags & INMEMORY) {
1738 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1740 /* Round to nearest, 53-bit mode, exceptions masked */
1741 disp = dseg_add_s4(cd, 0x027f);
1742 emit_fldcw_membase(cd, REG_ITMP1, disp);
1744 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1745 REG_SP, var->vv.regoff + 4);
1748 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1750 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1753 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1755 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1757 emit_jcc(cd, CC_NE, disp);
1759 emit_alu_imm_membase(cd, ALU_CMP, 0,
1760 REG_SP, var->vv.regoff);
1763 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1765 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1767 emit_jcc(cd, CC_NE, disp);
1769 /* XXX: change this when we use registers */
1770 emit_flds_membase(cd, REG_SP, var1->vv.regoff);
1771 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
1772 emit_call_reg(cd, REG_ITMP1);
1773 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1774 emit_mov_reg_membase(cd, REG_RESULT2,
1775 REG_SP, var->vv.regoff + 4);
1778 log_text("F2L: longs have to be in memory");
1783 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1785 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1786 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1788 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1791 /* Round to zero, 53-bit mode, exception masked */
1792 disp = dseg_add_s4(cd, 0x0e7f);
1793 emit_fldcw_membase(cd, REG_ITMP1, disp);
1795 var = VAROP(iptr->dst);
1796 var1 = VAROP(iptr->s1);
1798 if (var->flags & INMEMORY) {
1799 emit_fistpll_membase(cd, REG_SP, var->vv.regoff);
1801 /* Round to nearest, 53-bit mode, exceptions masked */
1802 disp = dseg_add_s4(cd, 0x027f);
1803 emit_fldcw_membase(cd, REG_ITMP1, disp);
1805 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1806 REG_SP, var->vv.regoff + 4);
1809 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1811 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1814 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1816 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff + 4);
1818 emit_jcc(cd, CC_NE, disp);
1820 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->vv.regoff);
1823 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff);
1825 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff);
1827 emit_jcc(cd, CC_NE, disp);
1829 /* XXX: change this when we use registers */
1830 emit_fldl_membase(cd, REG_SP, var1->vv.regoff);
1831 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
1832 emit_call_reg(cd, REG_ITMP1);
1833 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff);
1834 emit_mov_reg_membase(cd, REG_RESULT2,
1835 REG_SP, var->vv.regoff + 4);
1838 log_text("D2L: longs have to be in memory");
1843 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1845 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1846 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1848 emit_store_dst(jd, iptr, d);
1851 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1853 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1854 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1856 emit_store_dst(jd, iptr, d);
1859 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1862 /* exchanged to skip fxch */
1863 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1864 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1866 /* emit_fxch(cd); */
1869 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
1870 emit_jcc(cd, CC_E, 6);
1871 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
1873 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
1874 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1875 emit_jcc(cd, CC_B, 3 + 5);
1876 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1877 emit_jmp_imm(cd, 3);
1878 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1879 emit_store_dst(jd, iptr, d);
1882 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1885 /* exchanged to skip fxch */
1886 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1887 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1889 /* emit_fxch(cd); */
1892 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
1893 emit_jcc(cd, CC_E, 3);
1894 emit_movb_imm_reg(cd, 1, REG_AH);
1896 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
1897 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1898 emit_jcc(cd, CC_B, 3 + 5);
1899 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1900 emit_jmp_imm(cd, 3);
1901 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1902 emit_store_dst(jd, iptr, d);
1906 /* memory operations **************************************************/
1908 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1912 /* implicit null-pointer check */
1913 M_ILD(d, s1, OFFSET(java_array_t, size));
1914 emit_store_dst(jd, iptr, d);
1917 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1920 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1922 /* implicit null-pointer check */
1923 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1924 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray_t, data[0]),
1926 emit_store_dst(jd, iptr, d);
1929 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1934 /* implicit null-pointer check */
1935 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1936 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray_t, data[0]),
1938 emit_store_dst(jd, iptr, d);
1941 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1945 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1946 /* implicit null-pointer check */
1947 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1948 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray_t, data[0]),
1950 emit_store_dst(jd, iptr, d);
1953 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1956 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1958 /* implicit null-pointer check */
1959 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1960 emit_mov_memindex_reg(cd, OFFSET(java_intarray_t, data[0]),
1962 emit_store_dst(jd, iptr, d);
1965 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1968 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1970 /* implicit null-pointer check */
1971 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1973 var = VAROP(iptr->dst);
1975 assert(var->flags & INMEMORY);
1976 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]),
1977 s1, s2, 3, REG_ITMP3);
1978 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff);
1979 emit_mov_memindex_reg(cd, OFFSET(java_longarray_t, data[0]) + 4,
1980 s1, s2, 3, REG_ITMP3);
1981 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff + 4);
1984 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1988 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1989 /* implicit null-pointer check */
1990 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1991 emit_flds_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2, 2);
1992 emit_store_dst(jd, iptr, d);
1995 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1999 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2000 /* implicit null-pointer check */
2001 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2002 emit_fldl_memindex(cd, OFFSET(java_doublearray_t, data[0]), s1, s2,3);
2003 emit_store_dst(jd, iptr, d);
2006 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2011 /* implicit null-pointer check */
2012 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2013 emit_mov_memindex_reg(cd, OFFSET(java_objectarray_t, data[0]),
2015 emit_store_dst(jd, iptr, d);
2019 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2021 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2022 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2023 /* implicit null-pointer check */
2024 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2025 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2027 /* because EBP, ESI, EDI have no xH and xL nibbles */
2028 M_INTMOVE(s3, REG_ITMP3);
2031 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray_t, data[0]),
2035 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2038 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2039 /* implicit null-pointer check */
2040 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2041 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2042 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray_t, data[0]),
2046 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2049 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2050 /* implicit null-pointer check */
2051 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2052 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2053 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray_t, data[0]),
2057 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2060 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2061 /* implicit null-pointer check */
2062 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2063 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2064 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray_t, data[0]),
2068 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2070 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2071 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2072 /* implicit null-pointer check */
2073 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2075 var = VAROP(iptr->sx.s23.s3);
2077 assert(var->flags & INMEMORY);
2078 emit_mov_membase_reg(cd, REG_SP, var->vv.regoff, REG_ITMP3);
2079 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray_t, data[0])
2081 emit_mov_membase_reg(cd, REG_SP, var->vv.regoff + 4, REG_ITMP3);
2082 emit_mov_reg_memindex(cd, REG_ITMP3,
2083 OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
2086 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2090 /* implicit null-pointer check */
2091 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2092 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2093 emit_fstps_memindex(cd, OFFSET(java_floatarray_t, data[0]), s1, s2,2);
2096 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2098 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2099 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2100 /* implicit null-pointer check */
2101 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2102 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2103 emit_fstpl_memindex(cd, OFFSET(java_doublearray_t, data[0]),
2107 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2111 /* implicit null-pointer check */
2112 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2113 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2115 M_AST(s1, REG_SP, 0 * 4);
2116 M_AST(s3, REG_SP, 1 * 4);
2117 M_MOV_IMM(BUILTIN_FAST_canstore, REG_ITMP1);
2119 emit_arraystore_check(cd, iptr);
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2123 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2124 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray_t, data[0]),
2128 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2132 /* implicit null-pointer check */
2133 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2134 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
2135 OFFSET(java_bytearray_t, data[0]), s1, s2, 0);
2138 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142 /* implicit null-pointer check */
2143 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2144 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2145 OFFSET(java_chararray_t, data[0]), s1, s2, 1);
2148 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2152 /* implicit null-pointer check */
2153 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2154 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2155 OFFSET(java_shortarray_t, data[0]), s1, s2, 1);
2158 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2160 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2162 /* implicit null-pointer check */
2163 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2164 emit_mov_imm_memindex(cd, iptr->sx.s23.s3.constval,
2165 OFFSET(java_intarray_t, data[0]), s1, s2, 2);
2168 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2172 /* implicit null-pointer check */
2173 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2174 emit_mov_imm_memindex(cd,
2175 (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
2176 OFFSET(java_longarray_t, data[0]), s1, s2, 3);
2177 emit_mov_imm_memindex(cd,
2178 ((s4)iptr->sx.s23.s3.constval) >> 31,
2179 OFFSET(java_longarray_t, data[0]) + 4, s1, s2, 3);
2182 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2184 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2185 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2186 /* implicit null-pointer check */
2187 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2188 emit_mov_imm_memindex(cd, 0,
2189 OFFSET(java_objectarray_t, data[0]), s1, s2, 2);
2193 case ICMD_GETSTATIC: /* ... ==> ..., value */
2195 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2196 uf = iptr->sx.s23.s3.uf;
2197 fieldtype = uf->fieldref->parseddesc.fd->type;
2200 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2204 fi = iptr->sx.s23.s3.fmiref->p.field;
2205 fieldtype = fi->type;
2206 disp = (intptr_t) fi->value;
2208 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2209 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
2212 M_MOV_IMM(disp, REG_ITMP1);
2213 switch (fieldtype) {
2216 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2217 M_ILD(d, REG_ITMP1, 0);
2220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2221 M_LLD(d, REG_ITMP1, 0);
2224 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2225 M_FLD(d, REG_ITMP1, 0);
2228 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2229 M_DLD(d, REG_ITMP1, 0);
2232 emit_store_dst(jd, iptr, d);
2235 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2237 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2238 uf = iptr->sx.s23.s3.uf;
2239 fieldtype = uf->fieldref->parseddesc.fd->type;
2242 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2245 fi = iptr->sx.s23.s3.fmiref->p.field;
2246 fieldtype = fi->type;
2247 disp = (intptr_t) fi->value;
2249 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2250 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
2253 M_MOV_IMM(disp, REG_ITMP1);
2254 switch (fieldtype) {
2257 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2258 M_IST(s1, REG_ITMP1, 0);
2261 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2262 M_LST(s1, REG_ITMP1, 0);
2265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2266 emit_fstps_membase(cd, REG_ITMP1, 0);
2269 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2270 emit_fstpl_membase(cd, REG_ITMP1, 0);
2275 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2276 /* val = value (in current instruction) */
2277 /* following NOP) */
2279 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2280 uf = iptr->sx.s23.s3.uf;
2281 fieldtype = uf->fieldref->parseddesc.fd->type;
2284 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
2287 fi = iptr->sx.s23.s3.fmiref->p.field;
2288 fieldtype = fi->type;
2289 disp = (intptr_t) fi->value;
2291 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2292 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class, 0);
2295 M_MOV_IMM(disp, REG_ITMP1);
2296 switch (fieldtype) {
2299 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2302 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2303 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2310 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2313 emit_nullpointer_check(cd, iptr, s1);
2315 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2316 uf = iptr->sx.s23.s3.uf;
2317 fieldtype = uf->fieldref->parseddesc.fd->type;
2320 patcher_add_patch_ref(jd, PATCHER_getfield,
2321 iptr->sx.s23.s3.uf, 0);
2324 fi = iptr->sx.s23.s3.fmiref->p.field;
2325 fieldtype = fi->type;
2329 switch (fieldtype) {
2332 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2333 M_ILD32(d, s1, disp);
2336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2337 M_LLD32(d, s1, disp);
2340 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2341 M_FLD32(d, s1, disp);
2344 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2345 M_DLD32(d, s1, disp);
2348 emit_store_dst(jd, iptr, d);
2351 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354 emit_nullpointer_check(cd, iptr, s1);
2356 /* must be done here because of code patching */
2358 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2359 uf = iptr->sx.s23.s3.uf;
2360 fieldtype = uf->fieldref->parseddesc.fd->type;
2363 fi = iptr->sx.s23.s3.fmiref->p.field;
2364 fieldtype = fi->type;
2367 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2368 if (IS_2_WORD_TYPE(fieldtype))
2369 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2371 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2374 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2376 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2378 uf = iptr->sx.s23.s3.uf;
2381 patcher_add_patch_ref(jd, PATCHER_putfield, uf, 0);
2385 fi = iptr->sx.s23.s3.fmiref->p.field;
2389 switch (fieldtype) {
2392 M_IST32(s2, s1, disp);
2395 M_LST32(s2, s1, disp);
2398 emit_fstps_membase32(cd, s1, disp);
2401 emit_fstpl_membase32(cd, s1, disp);
2406 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2407 /* val = value (in current instruction) */
2408 /* following NOP) */
2410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2411 emit_nullpointer_check(cd, iptr, s1);
2413 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2414 uf = iptr->sx.s23.s3.uf;
2415 fieldtype = uf->fieldref->parseddesc.fd->type;
2418 patcher_add_patch_ref(jd, PATCHER_putfieldconst,
2422 fi = iptr->sx.s23.s3.fmiref->p.field;
2423 fieldtype = fi->type;
2427 switch (fieldtype) {
2430 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2433 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2434 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2442 /* branch operations **************************************************/
2444 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2447 M_INTMOVE(s1, REG_ITMP1_XPTR);
2449 #ifdef ENABLE_VERIFIER
2450 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2451 patcher_add_patch_ref(jd, PATCHER_resolve_class,
2452 iptr->sx.s23.s2.uc, 0);
2454 #endif /* ENABLE_VERIFIER */
2456 M_CALL_IMM(0); /* passing exception pc */
2457 M_POP(REG_ITMP2_XPC);
2459 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2463 case ICMD_GOTO: /* ... ==> ... */
2464 case ICMD_RET: /* ... ==> ... */
2466 #if defined(ENABLE_SSA)
2468 last_cmd_was_goto = true;
2470 /* In case of a Goto phimoves have to be inserted before the */
2473 codegen_emit_phi_moves(jd, bptr);
2476 emit_br(cd, iptr->dst.block);
2480 case ICMD_JSR: /* ... ==> ... */
2482 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2486 case ICMD_IFNULL: /* ..., value ==> ... */
2487 case ICMD_IFNONNULL:
2489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2491 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2494 case ICMD_IFEQ: /* ..., value ==> ... */
2501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2502 M_CMP_IMM(iptr->sx.val.i, s1);
2503 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2506 case ICMD_IF_LEQ: /* ..., value ==> ... */
2508 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2509 if (iptr->sx.val.l == 0) {
2510 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2511 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2514 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2515 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2516 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2517 M_OR(REG_ITMP2, REG_ITMP1);
2519 emit_beq(cd, iptr->dst.block);
2522 case ICMD_IF_LLT: /* ..., value ==> ... */
2524 if (iptr->sx.val.l == 0) {
2525 /* If high 32-bit are less than zero, then the 64-bits
2527 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2529 emit_blt(cd, iptr->dst.block);
2532 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2533 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2534 emit_blt(cd, iptr->dst.block);
2536 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2537 emit_bult(cd, iptr->dst.block);
2541 case ICMD_IF_LLE: /* ..., value ==> ... */
2543 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2544 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2545 emit_blt(cd, iptr->dst.block);
2547 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2548 emit_bule(cd, iptr->dst.block);
2551 case ICMD_IF_LNE: /* ..., value ==> ... */
2553 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2554 if (iptr->sx.val.l == 0) {
2555 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2556 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2559 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2560 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2561 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2562 M_OR(REG_ITMP2, REG_ITMP1);
2564 emit_bne(cd, iptr->dst.block);
2567 case ICMD_IF_LGT: /* ..., value ==> ... */
2569 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2570 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2571 emit_bgt(cd, iptr->dst.block);
2573 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2574 emit_bugt(cd, iptr->dst.block);
2577 case ICMD_IF_LGE: /* ..., value ==> ... */
2579 if (iptr->sx.val.l == 0) {
2580 /* If high 32-bit are greater equal zero, then the
2582 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2584 emit_bge(cd, iptr->dst.block);
2587 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2588 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2589 emit_bgt(cd, iptr->dst.block);
2591 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2592 emit_buge(cd, iptr->dst.block);
2596 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2597 case ICMD_IF_ICMPNE:
2598 case ICMD_IF_ICMPLT:
2599 case ICMD_IF_ICMPGT:
2600 case ICMD_IF_ICMPGE:
2601 case ICMD_IF_ICMPLE:
2603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2604 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2606 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2609 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2610 case ICMD_IF_ACMPNE:
2612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2615 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2618 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2620 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2621 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2622 M_INTMOVE(s1, REG_ITMP1);
2623 M_XOR(s2, REG_ITMP1);
2624 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2625 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2626 M_INTMOVE(s1, REG_ITMP2);
2627 M_XOR(s2, REG_ITMP2);
2628 M_OR(REG_ITMP1, REG_ITMP2);
2629 emit_beq(cd, iptr->dst.block);
2632 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2634 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2635 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2636 M_INTMOVE(s1, REG_ITMP1);
2637 M_XOR(s2, REG_ITMP1);
2638 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2639 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2640 M_INTMOVE(s1, REG_ITMP2);
2641 M_XOR(s2, REG_ITMP2);
2642 M_OR(REG_ITMP1, REG_ITMP2);
2643 emit_bne(cd, iptr->dst.block);
2646 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2648 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2649 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2651 emit_blt(cd, iptr->dst.block);
2652 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2653 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2656 emit_bult(cd, iptr->dst.block);
2659 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2661 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2662 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2664 emit_bgt(cd, iptr->dst.block);
2665 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2666 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2669 emit_bugt(cd, iptr->dst.block);
2672 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2674 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2675 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2677 emit_blt(cd, iptr->dst.block);
2678 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2679 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2682 emit_bule(cd, iptr->dst.block);
2685 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2687 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2688 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2690 emit_bgt(cd, iptr->dst.block);
2691 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2692 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2695 emit_buge(cd, iptr->dst.block);
2699 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2701 REPLACEMENT_POINT_RETURN(cd, iptr);
2702 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2703 M_INTMOVE(s1, REG_RESULT);
2704 goto nowperformreturn;
2706 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2708 REPLACEMENT_POINT_RETURN(cd, iptr);
2709 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2710 M_LNGMOVE(s1, REG_RESULT_PACKED);
2711 goto nowperformreturn;
2713 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2715 REPLACEMENT_POINT_RETURN(cd, iptr);
2716 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2717 M_INTMOVE(s1, REG_RESULT);
2719 #ifdef ENABLE_VERIFIER
2720 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2721 patcher_add_patch_ref(jd, PATCHER_resolve_class,
2722 iptr->sx.s23.s2.uc, 0);
2724 #endif /* ENABLE_VERIFIER */
2725 goto nowperformreturn;
2727 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2730 REPLACEMENT_POINT_RETURN(cd, iptr);
2731 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2732 goto nowperformreturn;
2734 case ICMD_RETURN: /* ... ==> ... */
2736 REPLACEMENT_POINT_RETURN(cd, iptr);
2742 p = cd->stackframesize;
2744 #if !defined(NDEBUG)
2745 emit_verbosecall_exit(jd);
2748 #if defined(ENABLE_THREADS)
2749 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2750 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 8);
2752 /* we need to save the proper return value */
2753 switch (iptr->opc) {
2756 M_IST(REG_RESULT, REG_SP, rd->memuse * 8);
2760 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2764 emit_fstps_membase(cd, REG_SP, rd->memuse * 8);
2768 emit_fstpl_membase(cd, REG_SP, rd->memuse * 8);
2772 M_AST(REG_ITMP2, REG_SP, 0);
2773 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
2776 /* and now restore the proper return value */
2777 switch (iptr->opc) {
2780 M_ILD(REG_RESULT, REG_SP, rd->memuse * 8);
2784 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2788 emit_flds_membase(cd, REG_SP, rd->memuse * 8);
2792 emit_fldl_membase(cd, REG_SP, rd->memuse * 8);
2798 /* restore saved registers */
2800 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2801 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2804 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2806 emit_fldl_membase(cd, REG_SP, p * 8);
2807 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
2809 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
2812 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
2816 /* deallocate stack */
2818 if (cd->stackframesize)
2819 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
2826 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2829 branch_target_t *table;
2831 table = iptr->dst.table;
2833 l = iptr->sx.s23.s2.tablelow;
2834 i = iptr->sx.s23.s3.tablehigh;
2836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2837 M_INTMOVE(s1, REG_ITMP1);
2840 M_ISUB_IMM(l, REG_ITMP1);
2846 M_CMP_IMM(i - 1, REG_ITMP1);
2847 emit_bugt(cd, table[0].block);
2849 /* build jump table top down and use address of lowest entry */
2854 dseg_add_target(cd, table->block);
2858 /* length of dataseg after last dseg_addtarget is used
2861 M_MOV_IMM(0, REG_ITMP2);
2863 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2869 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2872 lookup_target_t *lookup;
2874 lookup = iptr->dst.lookup;
2876 i = iptr->sx.s23.s2.lookupcount;
2878 MCODECHECK((i<<2)+8);
2879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2882 M_CMP_IMM(lookup->value, s1);
2883 emit_beq(cd, lookup->target.block);
2887 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2892 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2894 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2896 bte = iptr->sx.s23.s3.bte;
2900 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2902 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2903 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2904 case ICMD_INVOKEINTERFACE:
2906 REPLACEMENT_POINT_INVOKE(cd, iptr);
2908 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2909 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
2913 lm = iptr->sx.s23.s3.fmiref->p.method;
2914 md = lm->parseddesc;
2918 s3 = md->paramcount;
2920 MCODECHECK((s3 << 1) + 64);
2922 /* copy arguments to registers or stack location */
2924 for (s3 = s3 - 1; s3 >= 0; s3--) {
2925 var = VAR(iptr->sx.s23.s2.args[s3]);
2927 /* Already Preallocated (ARGVAR) ? */
2928 if (var->flags & PREALLOC)
2930 if (IS_INT_LNG_TYPE(var->type)) {
2931 if (!md->params[s3].inmemory) {
2932 log_text("No integer argument registers available!");
2936 if (IS_2_WORD_TYPE(var->type)) {
2937 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2938 M_LST(d, REG_SP, md->params[s3].regoff);
2940 d = emit_load(jd, iptr, var, REG_ITMP1);
2941 M_IST(d, REG_SP, md->params[s3].regoff);
2946 if (!md->params[s3].inmemory) {
2947 s1 = md->params[s3].regoff;
2948 d = emit_load(jd, iptr, var, s1);
2952 d = emit_load(jd, iptr, var, REG_FTMP1);
2953 if (IS_2_WORD_TYPE(var->type))
2954 M_DST(d, REG_SP, md->params[s3].regoff);
2956 M_FST(d, REG_SP, md->params[s3].regoff);
2961 switch (iptr->opc) {
2963 d = md->returntype.type;
2965 if (bte->stub == NULL) {
2966 M_MOV_IMM(bte->fp, REG_ITMP1);
2969 M_MOV_IMM(bte->stub, REG_ITMP1);
2974 case ICMD_INVOKESPECIAL:
2975 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
2976 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2979 case ICMD_INVOKESTATIC:
2981 unresolved_method *um = iptr->sx.s23.s3.um;
2983 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2987 d = md->returntype.type;
2990 disp = (ptrint) lm->stubroutine;
2991 d = lm->parseddesc->returntype.type;
2994 M_MOV_IMM(disp, REG_ITMP2);
2998 case ICMD_INVOKEVIRTUAL:
2999 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
3000 emit_nullpointer_check(cd, iptr, s1);
3003 unresolved_method *um = iptr->sx.s23.s3.um;
3005 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3008 d = md->returntype.type;
3011 s1 = OFFSET(vftbl_t, table[0]) +
3012 sizeof(methodptr) * lm->vftblindex;
3013 d = md->returntype.type;
3016 M_ALD(REG_METHODPTR, REG_ITMP1,
3017 OFFSET(java_object_t, vftbl));
3018 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3022 case ICMD_INVOKEINTERFACE:
3023 M_ALD(REG_ITMP1, REG_SP, 0 * 8);
3024 emit_nullpointer_check(cd, iptr, s1);
3027 unresolved_method *um = iptr->sx.s23.s3.um;
3029 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3033 d = md->returntype.type;
3036 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3037 sizeof(methodptr) * lm->class->index;
3039 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3041 d = md->returntype.type;
3044 M_ALD(REG_METHODPTR, REG_ITMP1,
3045 OFFSET(java_object_t, vftbl));
3046 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3047 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3052 /* store size of call code in replacement point */
3054 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3055 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
3057 /* d contains return type */
3059 if (d != TYPE_VOID) {
3060 #if defined(ENABLE_SSA)
3061 if ((ls == NULL) /* || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) */ ||
3062 (ls->lifetime[iptr->dst.varindex].type != UNUSED))
3063 /* a "living" stackslot */
3066 if (IS_INT_LNG_TYPE(d)) {
3067 if (IS_2_WORD_TYPE(d)) {
3068 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3069 M_LNGMOVE(REG_RESULT_PACKED, s1);
3072 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3073 M_INTMOVE(REG_RESULT, s1);
3077 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3079 emit_store_dst(jd, iptr, s1);
3085 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3087 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3088 /* object type cast-check */
3091 vftbl_t *supervftbl;
3094 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3100 super = iptr->sx.s23.s3.c.cls;
3101 superindex = super->index;
3102 supervftbl = super->vftbl;
3105 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3106 CODEGEN_CRITICAL_SECTION_NEW;
3108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3110 /* if class is not resolved, check which code to call */
3112 if (super == NULL) {
3114 emit_label_beq(cd, BRANCH_LABEL_1);
3116 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
3117 iptr->sx.s23.s3.c.ref, 0);
3119 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3120 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3121 emit_label_beq(cd, BRANCH_LABEL_2);
3124 /* interface checkcast code */
3126 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3127 if (super != NULL) {
3129 emit_label_beq(cd, BRANCH_LABEL_3);
3132 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3134 if (super == NULL) {
3135 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3136 iptr->sx.s23.s3.c.ref,
3141 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3142 M_ISUB_IMM32(superindex, REG_ITMP3);
3143 /* XXX do we need this one? */
3145 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
3147 M_ALD32(REG_ITMP3, REG_ITMP2,
3148 OFFSET(vftbl_t, interfacetable[0]) -
3149 superindex * sizeof(methodptr*));
3151 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
3154 emit_label_br(cd, BRANCH_LABEL_4);
3156 emit_label(cd, BRANCH_LABEL_3);
3159 /* class checkcast code */
3161 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3162 if (super == NULL) {
3163 emit_label(cd, BRANCH_LABEL_2);
3167 emit_label_beq(cd, BRANCH_LABEL_5);
3170 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3172 if (super == NULL) {
3173 patcher_add_patch_ref(jd, PATCHER_checkcast_class,
3174 iptr->sx.s23.s3.c.ref,
3178 M_MOV_IMM(supervftbl, REG_ITMP3);
3180 CODEGEN_CRITICAL_SECTION_START;
3182 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3184 /* if (s1 != REG_ITMP1) { */
3185 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3186 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3187 /* #if defined(ENABLE_THREADS) */
3188 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3190 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3193 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3194 M_ISUB(REG_ITMP3, REG_ITMP2);
3195 M_MOV_IMM(supervftbl, REG_ITMP3);
3196 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3198 CODEGEN_CRITICAL_SECTION_END;
3202 M_CMP(REG_ITMP3, REG_ITMP2);
3203 emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
3206 emit_label(cd, BRANCH_LABEL_5);
3209 if (super == NULL) {
3210 emit_label(cd, BRANCH_LABEL_1);
3211 emit_label(cd, BRANCH_LABEL_4);
3214 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3217 /* array type cast-check */
3219 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3220 M_AST(s1, REG_SP, 0 * 4);
3222 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3223 patcher_add_patch_ref(jd, PATCHER_builtin_arraycheckcast,
3224 iptr->sx.s23.s3.c.ref, 0);
3227 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3228 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3231 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3233 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3235 d = codegen_reg_of_dst(jd, iptr, s1);
3239 emit_store_dst(jd, iptr, d);
3242 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3246 vftbl_t *supervftbl;
3249 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3255 super = iptr->sx.s23.s3.c.cls;
3256 superindex = super->index;
3257 supervftbl = super->vftbl;
3260 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3261 CODEGEN_CRITICAL_SECTION_NEW;
3263 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3267 M_INTMOVE(s1, REG_ITMP1);
3273 /* if class is not resolved, check which code to call */
3275 if (super == NULL) {
3277 emit_label_beq(cd, BRANCH_LABEL_1);
3279 patcher_add_patch_ref(jd, PATCHER_checkcast_instanceof_flags,
3280 iptr->sx.s23.s3.c.ref, 0);
3282 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
3283 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3284 emit_label_beq(cd, BRANCH_LABEL_2);
3287 /* interface instanceof code */
3289 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3290 if (super != NULL) {
3292 emit_label_beq(cd, BRANCH_LABEL_3);
3295 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3297 if (super == NULL) {
3298 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3299 iptr->sx.s23.s3.c.ref, 0);
3303 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3304 M_ISUB_IMM32(superindex, REG_ITMP3);
3307 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3308 6 /* jcc */ + 5 /* mov_imm_reg */);
3311 M_ALD32(REG_ITMP1, REG_ITMP1,
3312 OFFSET(vftbl_t, interfacetable[0]) -
3313 superindex * sizeof(methodptr*));
3315 /* emit_setcc_reg(cd, CC_A, d); */
3316 /* emit_jcc(cd, CC_BE, 5); */
3321 emit_label_br(cd, BRANCH_LABEL_4);
3323 emit_label(cd, BRANCH_LABEL_3);
3326 /* class instanceof code */
3328 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3329 if (super == NULL) {
3330 emit_label(cd, BRANCH_LABEL_2);
3334 emit_label_beq(cd, BRANCH_LABEL_5);
3337 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3339 if (super == NULL) {
3340 patcher_add_patch_ref(jd, PATCHER_instanceof_class,
3341 iptr->sx.s23.s3.c.ref, 0);
3344 M_MOV_IMM(supervftbl, REG_ITMP2);
3346 CODEGEN_CRITICAL_SECTION_START;
3348 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3349 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3350 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3352 CODEGEN_CRITICAL_SECTION_END;
3354 M_ISUB(REG_ITMP2, REG_ITMP1);
3355 M_CLR(d); /* may be REG_ITMP2 */
3356 M_CMP(REG_ITMP3, REG_ITMP1);
3361 emit_label(cd, BRANCH_LABEL_5);
3364 if (super == NULL) {
3365 emit_label(cd, BRANCH_LABEL_1);
3366 emit_label(cd, BRANCH_LABEL_4);
3369 emit_store_dst(jd, iptr, d);
3373 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3375 /* check for negative sizes and copy sizes to stack if necessary */
3377 MCODECHECK((iptr->s1.argcount << 1) + 64);
3379 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3380 /* copy SAVEDVAR sizes to stack */
3381 var = VAR(iptr->sx.s23.s2.args[s1]);
3383 /* Already Preallocated? */
3384 if (!(var->flags & PREALLOC)) {
3385 if (var->flags & INMEMORY) {
3386 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff);
3387 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3390 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
3394 /* is a patcher function set? */
3396 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3397 patcher_add_patch_ref(jd, PATCHER_builtin_multianewarray,
3398 iptr->sx.s23.s3.c.ref, 0);
3404 disp = (ptrint) iptr->sx.s23.s3.c.cls;
3406 /* a0 = dimension count */
3408 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
3410 /* a1 = arraydescriptor */
3412 M_IST_IMM(disp, REG_SP, 1 * 4);
3414 /* a2 = pointer to dimensions = stack pointer */
3416 M_MOV(REG_SP, REG_ITMP1);
3417 M_AADD_IMM(3 * 4, REG_ITMP1);
3418 M_AST(REG_ITMP1, REG_SP, 2 * 4);
3420 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3423 /* check for exception before result assignment */
3425 emit_exception_check(cd, iptr);
3427 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3428 M_INTMOVE(REG_RESULT, s1);
3429 emit_store_dst(jd, iptr, s1);
3433 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3438 } /* for instruction */
3442 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
3445 #if defined(ENABLE_SSA)
3448 /* by edge splitting, in Blocks with phi moves there can only */
3449 /* be a goto as last command, no other Jump/Branch Command */
3451 if (!last_cmd_was_goto)
3452 codegen_emit_phi_moves(jd, bptr);
3457 /* At the end of a basic block we may have to append some nops,
3458 because the patcher stub calling code might be longer than the
3459 actual instruction. So codepatching does not change the
3460 following block unintentionally. */
3462 if (cd->mcodeptr < cd->lastmcodeptr) {
3463 while (cd->mcodeptr < cd->lastmcodeptr) {
3468 } /* if (bptr -> flags >= BBREACHED) */
3469 } /* for basic block */
3471 dseg_createlinenumbertable(cd);
3473 /* generate stubs */
3475 emit_patcher_traps(jd);
3477 /* everything's ok */
3483 /* codegen_emit_stub_native ****************************************************
3485 Emits a stub routine which calls a native method.
3487 *******************************************************************************/
3489 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3495 int i, j; /* count variables */
3498 #if defined(ENABLE_GC_CACAO)
3502 /* get required compiler data */
3508 /* set some variables */
3512 /* calculate stackframe size */
3514 cd->stackframesize =
3515 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3516 sizeof(localref_table) / SIZEOF_VOID_P +
3517 4 + /* 4 arguments (start_native_call) */
3520 /* keep stack 16-byte aligned */
3522 ALIGN_ODD(cd->stackframesize); /* XXX this is wrong, +4 is missing */
3524 /* create method header */
3526 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3527 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3528 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3529 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3530 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3531 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3532 (void) dseg_addlinenumbertablesize(cd);
3533 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3535 #if defined(ENABLE_PROFILING)
3536 /* generate native method profiling code */
3538 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3539 /* count frequency */
3541 M_MOV_IMM(code, REG_ITMP1);
3542 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
3546 /* calculate stackframe size for native function */
3548 M_ASUB_IMM(cd->stackframesize * 8, REG_SP);
3550 /* get function address (this must happen before the stackframeinfo) */
3552 funcdisp = dseg_add_functionptr(cd, f);
3555 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3557 /* Mark the whole fpu stack as free for native functions (only for saved */
3558 /* register count == 0). */
3560 emit_ffree_reg(cd, 0);
3561 emit_ffree_reg(cd, 1);
3562 emit_ffree_reg(cd, 2);
3563 emit_ffree_reg(cd, 3);
3564 emit_ffree_reg(cd, 4);
3565 emit_ffree_reg(cd, 5);
3566 emit_ffree_reg(cd, 6);
3567 emit_ffree_reg(cd, 7);
3569 #if defined(ENABLE_GC_CACAO)
3570 /* remember callee saved int registers in stackframeinfo (GC may need to */
3571 /* recover them during a collection). */
3573 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3574 OFFSET(stackframeinfo_t, intregs);
3576 for (i = 0; i < INT_SAV_CNT; i++)
3577 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3580 /* prepare data structures for native function call */
3582 M_MOV(REG_SP, REG_ITMP1);
3583 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3584 M_IST_IMM(0, REG_SP, 1 * 4);
3587 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3590 /* remember class argument */
3592 if (m->flags & ACC_STATIC)
3593 M_MOV(REG_RESULT, REG_ITMP3);
3595 /* Copy or spill arguments to new locations. */
3597 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3598 if (!md->params[i].inmemory)
3601 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
3602 s2 = nmd->params[j].regoff;
3604 /* float/double in memory can be copied like int/longs */
3606 switch (md->paramtypes[i].type) {
3610 M_ILD(REG_ITMP1, REG_SP, s1);
3611 M_IST(REG_ITMP1, REG_SP, s2);
3615 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3616 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3621 /* Handle native Java methods. */
3623 if (m->flags & ACC_NATIVE) {
3624 /* if function is static, put class into second argument */
3626 if (m->flags & ACC_STATIC)
3627 M_AST(REG_ITMP3, REG_SP, 1 * 4);
3629 /* put env into first argument */
3631 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
3634 /* call the native function */
3636 emit_mov_imm_reg(cd, 0, REG_ITMP3);
3638 M_ALD(REG_ITMP1, REG_ITMP3, funcdisp);
3641 /* save return value */
3643 switch (md->returntype.type) {
3646 M_IST(REG_RESULT, REG_SP, 1 * 8);
3649 M_LST(REG_RESULT_PACKED, REG_SP, 1 * 8);
3652 emit_fsts_membase(cd, REG_SP, 1 * 8);
3655 emit_fstl_membase(cd, REG_SP, 1 * 8);
3661 /* remove native stackframe info */
3663 M_MOV(REG_SP, REG_ITMP1);
3664 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3665 M_IST_IMM(0, REG_SP, 1 * 4);
3668 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3670 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
3672 /* restore return value */
3674 switch (md->returntype.type) {
3677 M_ILD(REG_RESULT, REG_SP, 1 * 8);
3680 M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 8);
3683 emit_flds_membase(cd, REG_SP, 1 * 8);
3686 emit_fldl_membase(cd, REG_SP, 1 * 8);
3692 #if defined(ENABLE_GC_CACAO)
3693 /* restore callee saved int registers from stackframeinfo (GC might have */
3694 /* modified them during a collection). */
3696 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3697 OFFSET(stackframeinfo_t, intregs);
3699 for (i = 0; i < INT_SAV_CNT; i++)
3700 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3703 M_AADD_IMM(cd->stackframesize * 8, REG_SP);
3705 /* check for exception */
3712 /* handle exception */
3714 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3715 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3716 M_ASUB_IMM(2, REG_ITMP2_XPC);
3718 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3721 /* generate patcher stubs */
3723 emit_patcher_traps(jd);
3728 * These are local overrides for various environment variables in Emacs.
3729 * Please do not remove this and leave it at the end of the file, where
3730 * Emacs will automagically detect them.
3731 * ---------------------------------------------------------------------
3734 * indent-tabs-mode: t
3738 * vim:noexpandtab:sw=4:ts=4: