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
25 $Id: codegen.c 7601 2007-03-28 23:02:50Z michi $
37 #include "vm/jit/i386/md-abi.h"
39 #include "vm/jit/i386/codegen.h"
40 #include "vm/jit/i386/emit.h"
42 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/native.h"
46 #if defined(ENABLE_THREADS)
47 # include "threads/native/lock.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
53 #include "vm/stringlocal.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.h"
66 #include "vm/jit/stacktrace.h"
68 #if defined(ENABLE_SSA)
69 # include "vm/jit/optimizing/lsra.h"
70 # include "vm/jit/optimizing/ssa.h"
71 #elif defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
75 #include "vmcore/loader.h"
76 #include "vmcore/options.h"
77 #include "vmcore/utf8.h"
80 /* codegen_emit ****************************************************************
82 Generates machine code.
84 *******************************************************************************/
86 #if defined(ENABLE_SSA)
87 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
88 s4 dst_regoff, s4 dst_flags);
89 void codegen_insert_phi_moves(jitdata *jd, basicblock *bptr);
92 bool codegen_emit(jitdata *jd)
98 s4 len, s1, s2, s3, d, disp;
104 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
105 builtintable_entry *bte;
108 unresolved_field *uf;
111 #if defined(ENABLE_SSA)
113 bool last_cmd_was_goto;
115 last_cmd_was_goto = false;
119 /* get required compiler data */
126 /* prevent compiler warnings */
137 s4 savedregs_num = 0;
140 /* space to save used callee saved registers */
142 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
144 /* float register are saved on 2 4-byte stackslots */
145 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
147 cd->stackframesize = rd->memuse + savedregs_num;
150 #if defined(ENABLE_THREADS)
151 /* space to save argument of monitor_enter */
153 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
154 /* reserve 2 slots for long/double return values for monitorexit */
156 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
157 cd->stackframesize += 2;
159 cd->stackframesize++;
163 /* create method header */
165 /* Keep stack of non-leaf functions 16-byte aligned. */
167 if (!jd->isleafmethod)
168 cd->stackframesize |= 0x3;
170 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
171 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
173 #if defined(ENABLE_THREADS)
174 /* IsSync contains the offset relative to the stack pointer for the
175 argument of monitor_exit used in the exception handler. Since the
176 offset could be zero and give a wrong meaning of the flag it is
180 if (checksync && (m->flags & ACC_SYNCHRONIZED))
181 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync */
184 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
186 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
187 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
188 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
190 /* adds a reference for the length of the line number counter. We don't
191 know the size yet, since we evaluate the information during code
192 generation, to save one additional iteration over the whole
193 instructions. During code optimization the position could have changed
194 to the information gotten from the class file */
195 (void) dseg_addlinenumbertablesize(cd);
197 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
199 /* create exception table */
201 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
202 dseg_add_target(cd, ex->start);
203 dseg_add_target(cd, ex->end);
204 dseg_add_target(cd, ex->handler);
205 (void) dseg_add_unique_address(cd, ex->catchtype.any);
208 #if defined(ENABLE_PROFILING)
209 /* generate method profiling code */
211 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
212 /* count frequency */
214 M_MOV_IMM(code, REG_ITMP3);
215 M_IADD_IMM_MEMBASE(1, REG_ITMP3, OFFSET(codeinfo, frequency));
219 /* create stack frame (if necessary) */
221 if (cd->stackframesize)
222 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
224 /* save return address and used callee saved registers */
226 p = cd->stackframesize;
227 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
228 p--; M_AST(rd->savintregs[i], REG_SP, p * 4);
230 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
231 p-=2; emit_fld_reg(cd, rd->savfltregs[i]); emit_fstpl_membase(cd, REG_SP, p * 4);
234 /* take arguments out of register or stack frame */
239 for (p = 0, l = 0; p < md->paramcount; p++) {
240 t = md->paramtypes[p].type;
242 #if defined(ENABLE_SSA)
247 varindex = jd->local_map[l * 5 + t];
249 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
252 if (varindex == UNUSED)
257 s1 = md->params[p].regoff;
259 if (IS_INT_LNG_TYPE(t)) { /* integer args */
260 if (!md->params[p].inmemory) { /* register arguments */
261 log_text("integer register argument");
263 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
264 /* rd->argintregs[md->params[p].regoff -> var->vv.regoff */
266 else { /* reg arg -> spilled */
267 /* rd->argintregs[md->params[p].regoff -> var->vv.regoff * 4 */
270 else { /* stack arguments */
271 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
272 emit_mov_membase_reg( /* + 4 for return address */
273 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, var->vv.regoff);
274 /* + 4 for return address */
276 else { /* stack arg -> spilled */
277 if (!IS_2_WORD_TYPE(t)) {
278 #if defined(ENABLE_SSA)
279 /* no copy avoiding by now possible with SSA */
281 emit_mov_membase_reg( /* + 4 for return address */
282 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
284 emit_mov_reg_membase(
285 cd, REG_ITMP1, REG_SP, var->vv.regoff * 4);
288 #endif /*defined(ENABLE_SSA)*/
289 /* reuse Stackslotand avoid copying */
290 var->vv.regoff = cd->stackframesize + s1 + 1;
294 #if defined(ENABLE_SSA)
295 /* no copy avoiding by now possible with SSA */
297 emit_mov_membase_reg( /* + 4 for return address */
298 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4,
300 emit_mov_reg_membase(
301 cd, REG_ITMP1, REG_SP, var->vv.regoff * 4);
302 emit_mov_membase_reg( /* + 4 for return address */
303 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4 + 4,
305 emit_mov_reg_membase(
306 cd, REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
309 #endif /*defined(ENABLE_SSA)*/
310 /* reuse Stackslotand avoid copying */
311 var->vv.regoff = cd->stackframesize + s1 + 1;
316 else { /* floating args */
317 if (!md->params[p].inmemory) { /* register arguments */
318 log_text("There are no float argument registers!");
320 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
321 /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff */
322 } else { /* reg arg -> spilled */
323 /* rd->argfltregs[md->params[p].regoff -> var->vv.regoff * 4 */
327 else { /* stack arguments */
328 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
331 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
333 /* emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
338 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
340 /* emit_fstp_reg(cd, var->vv.regoff + fpu_st_offset); */
343 } else { /* stack-arg -> spilled */
344 #if defined(ENABLE_SSA)
345 /* no copy avoiding by now possible with SSA */
347 emit_mov_membase_reg(
348 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4, REG_ITMP1);
349 emit_mov_reg_membase(
350 cd, REG_ITMP1, REG_SP, var->vv.regoff * 4);
353 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
354 emit_fstps_membase(cd, REG_SP, var->vv.regoff * 4);
358 cd, REG_SP, (cd->stackframesize + s1) * 4 + 4);
359 emit_fstpl_membase(cd, REG_SP, var->vv.regoff * 4);
363 #endif /*defined(ENABLE_SSA)*/
364 /* reuse Stackslotand avoid copying */
365 var->vv.regoff = cd->stackframesize + s1 + 1;
371 /* call monitorenter function */
373 #if defined(ENABLE_THREADS)
374 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
377 if (m->flags & ACC_STATIC) {
378 M_MOV_IMM(&m->class->object.header, REG_ITMP1);
381 M_ALD(REG_ITMP1, REG_SP, cd->stackframesize * 4 + 4);
384 M_ALD_MEM(REG_ITMP1, EXCEPTION_HARDWARE_NULLPOINTER);
387 M_AST(REG_ITMP1, REG_SP, s1 * 4);
388 M_AST(REG_ITMP1, REG_SP, 0 * 4);
389 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP3);
395 emit_verbosecall_enter(jd);
400 #if defined(ENABLE_SSA)
401 /* with SSA Header is Basic Block 0 - insert phi Moves if necessary */
403 codegen_insert_phi_moves(jd, ls->basicblocks[0]);
406 /* end of header generation */
408 /* create replacement points */
410 REPLACEMENT_POINTS_INIT(cd, jd);
412 /* walk through all basic blocks */
414 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
416 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
418 if (bptr->flags >= BBREACHED) {
419 /* branch resolving */
421 codegen_resolve_branchrefs(cd, bptr);
423 /* handle replacement points */
425 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
427 #if defined(ENABLE_REPLACEMENT)
428 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
429 if (cd->replacementpoint[-1].flags & RPLPOINT_FLAG_COUNTDOWN) {
431 disp = (s4) &(m->hitcountdown);
432 M_ISUB_IMM_MEMABS(1, disp);
438 /* copy interface registers to their destination */
443 #if defined(ENABLE_PROFILING)
444 /* generate basic block profiling code */
446 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
447 /* count frequency */
449 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
450 M_IADD_IMM_MEMBASE(1, REG_ITMP3, bptr->nr * 4);
454 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
455 # if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
458 # if defined(ENABLE_SSA)
460 last_cmd_was_goto = false;
464 var = VAR(bptr->invars[len]);
465 if (bptr->type != BBTYPE_STD) {
466 if (!IS_2_WORD_TYPE(var->type)) {
467 if (bptr->type == BBTYPE_EXH) {
468 d = codegen_reg_of_var(0, var, REG_ITMP1);
469 M_INTMOVE(REG_ITMP1, d);
470 emit_store(jd, NULL, var, d);
474 log_text("copy interface registers(EXH, SBR): longs \
475 have to be in memory (begin 1)");
483 #endif /* defined(ENABLE_LSRA) || defined(ENABLE_SSA) */
487 var = VAR(bptr->invars[len]);
488 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
489 if (!IS_2_WORD_TYPE(var->type)) {
490 if (bptr->type == BBTYPE_EXH) {
491 d = codegen_reg_of_var(0, var, REG_ITMP1);
492 M_INTMOVE(REG_ITMP1, d);
493 emit_store(jd, NULL, var, d);
497 log_text("copy interface registers: longs have to be in \
504 assert((var->flags & INOUT));
509 /* walk through all instructions */
514 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
515 if (iptr->line != currentline) {
516 dseg_addlinenumber(cd, iptr->line);
517 currentline = iptr->line;
520 MCODECHECK(1024); /* 1kB should be enough */
523 case ICMD_NOP: /* ... ==> ... */
524 case ICMD_POP: /* ..., value ==> ... */
525 case ICMD_POP2: /* ..., value, value ==> ... */
528 case ICMD_INLINE_START:
530 REPLACEMENT_POINT_INLINE_START(cd, iptr);
533 case ICMD_INLINE_BODY:
535 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
536 dseg_addlinenumber_inline_start(cd, iptr);
537 dseg_addlinenumber(cd, iptr->line);
540 case ICMD_INLINE_END:
542 dseg_addlinenumber_inline_end(cd, iptr);
543 dseg_addlinenumber(cd, iptr->line);
546 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549 emit_nullpointer_check(cd, iptr, s1);
552 /* constant operations ************************************************/
554 case ICMD_ICONST: /* ... ==> ..., constant */
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
557 ICONST(d, iptr->sx.val.i);
558 emit_store_dst(jd, iptr, d);
561 case ICMD_LCONST: /* ... ==> ..., constant */
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
564 LCONST(d, iptr->sx.val.l);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_FCONST: /* ... ==> ..., constant */
570 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
571 if (iptr->sx.val.f == 0.0) {
575 if (iptr->sx.val.i == 0x80000000) {
579 } else if (iptr->sx.val.f == 1.0) {
582 } else if (iptr->sx.val.f == 2.0) {
588 disp = dseg_add_float(cd, iptr->sx.val.f);
589 emit_mov_imm_reg(cd, 0, REG_ITMP1);
591 emit_flds_membase(cd, REG_ITMP1, disp);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_DCONST: /* ... ==> ..., constant */
598 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
599 if (iptr->sx.val.d == 0.0) {
603 if (iptr->sx.val.l == 0x8000000000000000LL) {
607 } else if (iptr->sx.val.d == 1.0) {
610 } else if (iptr->sx.val.d == 2.0) {
616 disp = dseg_add_double(cd, iptr->sx.val.d);
617 emit_mov_imm_reg(cd, 0, REG_ITMP1);
619 emit_fldl_membase(cd, REG_ITMP1, disp);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_ACONST: /* ... ==> ..., constant */
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
628 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
629 codegen_addpatchref(cd, PATCHER_aconst,
630 iptr->sx.val.c.ref, 0);
635 if (iptr->sx.val.anyptr == NULL)
638 M_MOV_IMM(iptr->sx.val.anyptr, d);
640 emit_store_dst(jd, iptr, d);
644 /* load/store/copy/move operations ************************************/
658 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
662 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
663 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
667 /* integer operations *************************************************/
669 case ICMD_INEG: /* ..., value ==> ..., - value */
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
675 emit_store_dst(jd, iptr, d);
678 case ICMD_LNEG: /* ..., value ==> ..., - value */
680 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
683 M_NEG(GET_LOW_REG(d));
684 M_IADDC_IMM(0, GET_HIGH_REG(d));
685 M_NEG(GET_HIGH_REG(d));
686 emit_store_dst(jd, iptr, d);
689 case ICMD_I2L: /* ..., value ==> ..., value */
691 s1 = emit_load_s1(jd, iptr, EAX);
692 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
695 M_LNGMOVE(EAX_EDX_PACKED, d);
696 emit_store_dst(jd, iptr, d);
699 case ICMD_L2I: /* ..., value ==> ..., value */
701 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
722 emit_store_dst(jd, iptr, d);
725 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
728 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
730 emit_store_dst(jd, iptr, d);
734 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
737 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
745 emit_store_dst(jd, iptr, d);
749 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
750 /* sx.val.i = constant */
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
755 /* `inc reg' is slower on p4's (regarding to ia32
756 optimization reference manual and benchmarks) and as
760 M_IADD_IMM(iptr->sx.val.i, d);
761 emit_store_dst(jd, iptr, d);
764 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
766 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
767 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
769 M_INTMOVE(s1, GET_LOW_REG(d));
770 M_IADD(s2, GET_LOW_REG(d));
771 /* don't use REG_ITMP1 */
772 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
773 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
774 M_INTMOVE(s1, GET_HIGH_REG(d));
775 M_IADDC(s2, GET_HIGH_REG(d));
776 emit_store_dst(jd, iptr, d);
779 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
780 /* sx.val.l = constant */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
785 M_IADD_IMM(iptr->sx.val.l, GET_LOW_REG(d));
786 M_IADDC_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
787 emit_store_dst(jd, iptr, d);
790 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
793 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
796 M_INTMOVE(s1, REG_ITMP1);
797 M_ISUB(s2, REG_ITMP1);
798 M_INTMOVE(REG_ITMP1, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
808 /* sx.val.i = constant */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
813 M_ISUB_IMM(iptr->sx.val.i, d);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
819 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
820 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
822 if (s2 == GET_LOW_REG(d)) {
823 M_INTMOVE(s1, REG_ITMP1);
824 M_ISUB(s2, REG_ITMP1);
825 M_INTMOVE(REG_ITMP1, GET_LOW_REG(d));
828 M_INTMOVE(s1, GET_LOW_REG(d));
829 M_ISUB(s2, GET_LOW_REG(d));
831 /* don't use REG_ITMP1 */
832 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
833 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
834 if (s2 == GET_HIGH_REG(d)) {
835 M_INTMOVE(s1, REG_ITMP2);
836 M_ISUBB(s2, REG_ITMP2);
837 M_INTMOVE(REG_ITMP2, GET_HIGH_REG(d));
840 M_INTMOVE(s1, GET_HIGH_REG(d));
841 M_ISUBB(s2, GET_HIGH_REG(d));
843 emit_store_dst(jd, iptr, d);
846 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
847 /* sx.val.l = constant */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
852 M_ISUB_IMM(iptr->sx.val.l, GET_LOW_REG(d));
853 M_ISUBB_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
854 emit_store_dst(jd, iptr, d);
857 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 emit_store_dst(jd, iptr, d);
871 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
872 /* sx.val.i = constant */
874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 M_IMUL_IMM(s1, iptr->sx.val.i, d);
877 emit_store_dst(jd, iptr, d);
880 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
882 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
883 s2 = emit_load_s2_low(jd, iptr, EDX);
884 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
886 M_INTMOVE(s1, REG_ITMP2);
887 M_IMUL(s2, REG_ITMP2);
889 s1 = emit_load_s1_low(jd, iptr, EAX);
890 s2 = emit_load_s2_high(jd, iptr, EDX);
893 M_IADD(EDX, REG_ITMP2);
895 s1 = emit_load_s1_low(jd, iptr, EAX);
896 s2 = emit_load_s2_low(jd, iptr, EDX);
899 M_INTMOVE(EAX, GET_LOW_REG(d));
900 M_IADD(REG_ITMP2, GET_HIGH_REG(d));
902 emit_store_dst(jd, iptr, d);
905 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
906 /* sx.val.l = constant */
908 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
909 d = codegen_reg_of_dst(jd, iptr, EAX_EDX_PACKED);
910 ICONST(EAX, iptr->sx.val.l);
912 M_IMUL_IMM(s1, iptr->sx.val.l >> 32, REG_ITMP2);
913 M_IADD(REG_ITMP2, EDX);
914 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
915 M_IMUL_IMM(s1, iptr->sx.val.l, REG_ITMP2);
916 M_IADD(REG_ITMP2, EDX);
917 M_LNGMOVE(EAX_EDX_PACKED, d);
918 emit_store_dst(jd, iptr, d);
921 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
923 s1 = emit_load_s1(jd, iptr, EAX);
924 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
925 d = codegen_reg_of_dst(jd, iptr, EAX);
926 emit_arithmetic_check(cd, iptr, s2);
928 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
930 /* check as described in jvm spec */
932 M_CMP_IMM(0x80000000, EAX);
939 M_INTMOVE(EAX, d); /* if INMEMORY then d is already EAX */
940 emit_store_dst(jd, iptr, d);
943 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
945 s1 = emit_load_s1(jd, iptr, EAX);
946 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
947 d = codegen_reg_of_dst(jd, iptr, EDX);
948 emit_arithmetic_check(cd, iptr, s2);
950 M_INTMOVE(s1, EAX); /* we need the first operand in EAX */
952 /* check as described in jvm spec */
954 M_CMP_IMM(0x80000000, EAX);
962 M_INTMOVE(EDX, d); /* if INMEMORY then d is already EDX */
963 emit_store_dst(jd, iptr, d);
966 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
967 /* sx.val.i = constant */
969 /* TODO: optimize for `/ 2' */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
975 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, d);/* 32-bit for jump off */
976 M_SRA_IMM(iptr->sx.val.i, d);
977 emit_store_dst(jd, iptr, d);
980 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
981 /* sx.val.i = constant */
983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
984 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
986 M_MOV(s1, REG_ITMP1);
990 M_AND_IMM(iptr->sx.val.i, d);
992 M_BGE(2 + 2 + 6 + 2);
993 M_MOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
995 M_AND_IMM32(iptr->sx.val.i, d); /* use 32-bit for jump offset */
997 emit_store_dst(jd, iptr, d);
1000 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1001 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1003 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1004 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1006 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
1007 M_OR(GET_HIGH_REG(s2), REG_ITMP3);
1008 /* XXX could be optimized */
1009 emit_arithmetic_check(cd, iptr, REG_ITMP3);
1011 bte = iptr->sx.s23.s3.bte;
1014 M_LST(s2, REG_SP, 2 * 4);
1016 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1017 M_LST(s1, REG_SP, 0 * 4);
1019 M_MOV_IMM(bte->fp, REG_ITMP3);
1021 emit_store_dst(jd, iptr, d);
1024 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1025 /* sx.val.i = constant */
1027 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1028 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1030 M_TEST(GET_HIGH_REG(d));
1032 M_IADD_IMM32((1 << iptr->sx.val.i) - 1, GET_LOW_REG(d));
1033 M_IADDC_IMM(0, GET_HIGH_REG(d));
1034 M_SRLD_IMM(iptr->sx.val.i, GET_HIGH_REG(d), GET_LOW_REG(d));
1035 M_SRA_IMM(iptr->sx.val.i, GET_HIGH_REG(d));
1036 emit_store_dst(jd, iptr, d);
1040 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1041 /* sx.val.l = constant */
1043 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1044 if (iptr->dst.var->flags & INMEMORY) {
1045 if (iptr->s1.var->flags & INMEMORY) {
1046 /* Alpha algorithm */
1048 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 4);
1050 CALCOFFSETBYTES(disp, REG_SP, iptr->s1.var->vv.regoff * 4 + 4);
1056 /* TODO: hmm, don't know if this is always correct */
1058 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l & 0x00000000ffffffff);
1060 CALCIMMEDIATEBYTES(disp, iptr->sx.val.l >> 32);
1066 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 4, REG_ITMP1);
1067 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 4 + 4, REG_ITMP2);
1069 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1070 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1071 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, iptr->s1.var->vv.regoff * 4 + 4);
1072 emit_jcc(cd, CC_GE, disp);
1074 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 4, REG_ITMP1);
1075 emit_mov_membase_reg(cd, REG_SP, iptr->s1.var->vv.regoff * 4 + 4, REG_ITMP2);
1077 emit_neg_reg(cd, REG_ITMP1);
1078 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1079 emit_neg_reg(cd, REG_ITMP2);
1081 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l, REG_ITMP1);
1082 emit_alu_imm_reg(cd, ALU_AND, iptr->sx.val.l >> 32, REG_ITMP2);
1084 emit_neg_reg(cd, REG_ITMP1);
1085 emit_alu_imm_reg(cd, ALU_ADC, 0, REG_ITMP2);
1086 emit_neg_reg(cd, REG_ITMP2);
1088 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, iptr->dst.var->vv.regoff * 4);
1089 emit_mov_reg_membase(cd, REG_ITMP2, REG_SP, iptr->dst.var->vv.regoff * 4 + 4);
1093 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1094 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1096 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1097 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1098 M_TEST(GET_LOW_REG(s1));
1104 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1107 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1108 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1109 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1116 /* sx.val.i = constant */
1118 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1119 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1121 M_SLL_IMM(iptr->sx.val.i, d);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1128 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1129 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1130 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1137 /* sx.val.i = constant */
1139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1142 M_SRA_IMM(iptr->sx.val.i, d);
1143 emit_store_dst(jd, iptr, d);
1146 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1148 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1149 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1151 M_INTMOVE(s2, ECX); /* s2 may be equal to d */
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1158 /* sx.val.i = constant */
1160 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1163 M_SRL_IMM(iptr->sx.val.i, d);
1164 emit_store_dst(jd, iptr, d);
1167 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1169 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1170 s2 = emit_load_s2(jd, iptr, ECX);
1171 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1174 M_TEST_IMM(32, ECX);
1176 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1177 M_CLR(GET_LOW_REG(d));
1178 M_SLLD(GET_LOW_REG(d), GET_HIGH_REG(d));
1179 M_SLL(GET_LOW_REG(d));
1180 emit_store_dst(jd, iptr, d);
1183 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1184 /* sx.val.i = constant */
1186 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1189 if (iptr->sx.val.i & 0x20) {
1190 M_MOV(GET_LOW_REG(d), GET_HIGH_REG(d));
1191 M_CLR(GET_LOW_REG(d));
1192 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1196 M_SLLD_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d),
1198 M_SLL_IMM(iptr->sx.val.i & 0x3f, GET_LOW_REG(d));
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1205 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1206 s2 = emit_load_s2(jd, iptr, ECX);
1207 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1210 M_TEST_IMM(32, ECX);
1212 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1213 M_SRA_IMM(31, GET_HIGH_REG(d));
1214 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1215 M_SRA(GET_HIGH_REG(d));
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1220 /* sx.val.i = constant */
1222 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1223 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1225 if (iptr->sx.val.i & 0x20) {
1226 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1227 M_SRA_IMM(31, GET_HIGH_REG(d));
1228 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1232 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1234 M_SRA_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1236 emit_store_dst(jd, iptr, d);
1239 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1241 s1 = emit_load_s1(jd, iptr, REG_ITMP13_PACKED);
1242 s2 = emit_load_s2(jd, iptr, ECX);
1243 d = codegen_reg_of_dst(jd, iptr, REG_ITMP13_PACKED);
1246 M_TEST_IMM(32, ECX);
1248 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1249 M_CLR(GET_HIGH_REG(d));
1250 M_SRLD(GET_HIGH_REG(d), GET_LOW_REG(d));
1251 M_SRL(GET_HIGH_REG(d));
1252 emit_store_dst(jd, iptr, d);
1255 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1256 /* sx.val.l = constant */
1258 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1259 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1261 if (iptr->sx.val.i & 0x20) {
1262 M_MOV(GET_HIGH_REG(d), GET_LOW_REG(d));
1263 M_CLR(GET_HIGH_REG(d));
1264 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1268 M_SRLD_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d),
1270 M_SRL_IMM(iptr->sx.val.i & 0x3f, GET_HIGH_REG(d));
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1277 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1278 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1279 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1290 /* sx.val.i = constant */
1292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1295 M_AND_IMM(iptr->sx.val.i, d);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1301 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1302 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1304 if (s2 == GET_LOW_REG(d))
1305 M_AND(s1, GET_LOW_REG(d));
1307 M_INTMOVE(s1, GET_LOW_REG(d));
1308 M_AND(s2, GET_LOW_REG(d));
1310 /* REG_ITMP1 probably contains low 32-bit of destination */
1311 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1312 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1313 if (s2 == GET_HIGH_REG(d))
1314 M_AND(s1, GET_HIGH_REG(d));
1316 M_INTMOVE(s1, GET_HIGH_REG(d));
1317 M_AND(s2, GET_HIGH_REG(d));
1319 emit_store_dst(jd, iptr, d);
1322 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1323 /* sx.val.l = constant */
1325 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1326 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1328 M_AND_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1329 M_AND_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1330 emit_store_dst(jd, iptr, d);
1333 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1335 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1336 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1337 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1348 /* sx.val.i = constant */
1350 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1351 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1353 M_OR_IMM(iptr->sx.val.i, d);
1354 emit_store_dst(jd, iptr, d);
1357 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1359 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1360 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1361 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1362 if (s2 == GET_LOW_REG(d))
1363 M_OR(s1, GET_LOW_REG(d));
1365 M_INTMOVE(s1, GET_LOW_REG(d));
1366 M_OR(s2, GET_LOW_REG(d));
1368 /* REG_ITMP1 probably contains low 32-bit of destination */
1369 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1370 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1371 if (s2 == GET_HIGH_REG(d))
1372 M_OR(s1, GET_HIGH_REG(d));
1374 M_INTMOVE(s1, GET_HIGH_REG(d));
1375 M_OR(s2, GET_HIGH_REG(d));
1377 emit_store_dst(jd, iptr, d);
1380 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1381 /* sx.val.l = constant */
1383 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1384 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1386 M_OR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1387 M_OR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1388 emit_store_dst(jd, iptr, d);
1391 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1394 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1402 emit_store_dst(jd, iptr, d);
1405 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1406 /* sx.val.i = constant */
1408 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1411 M_XOR_IMM(iptr->sx.val.i, d);
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1417 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1418 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1420 if (s2 == GET_LOW_REG(d))
1421 M_XOR(s1, GET_LOW_REG(d));
1423 M_INTMOVE(s1, GET_LOW_REG(d));
1424 M_XOR(s2, GET_LOW_REG(d));
1426 /* REG_ITMP1 probably contains low 32-bit of destination */
1427 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1428 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1429 if (s2 == GET_HIGH_REG(d))
1430 M_XOR(s1, GET_HIGH_REG(d));
1432 M_INTMOVE(s1, GET_HIGH_REG(d));
1433 M_XOR(s2, GET_HIGH_REG(d));
1435 emit_store_dst(jd, iptr, d);
1438 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1439 /* sx.val.l = constant */
1441 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1444 M_XOR_IMM(iptr->sx.val.l, GET_LOW_REG(d));
1445 M_XOR_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(d));
1446 emit_store_dst(jd, iptr, d);
1450 /* floating operations ************************************************/
1452 case ICMD_FNEG: /* ..., value ==> ..., - value */
1454 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1455 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_DNEG: /* ..., value ==> ..., - value */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1465 emit_store_dst(jd, iptr, d);
1468 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1471 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1474 emit_store_dst(jd, iptr, d);
1477 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1480 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1481 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1483 emit_store_dst(jd, iptr, d);
1486 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1488 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1489 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1492 emit_store_dst(jd, iptr, d);
1495 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1497 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1498 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1499 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1501 emit_store_dst(jd, iptr, d);
1504 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1506 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1507 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1508 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1510 emit_store_dst(jd, iptr, d);
1513 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1515 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1516 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1517 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1519 emit_store_dst(jd, iptr, d);
1522 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1524 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1525 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1528 emit_store_dst(jd, iptr, d);
1531 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1533 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1534 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1535 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1537 emit_store_dst(jd, iptr, d);
1540 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1542 /* exchanged to skip fxch */
1543 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1544 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1545 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1546 /* emit_fxch(cd); */
1551 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1552 emit_store_dst(jd, iptr, d);
1553 emit_ffree_reg(cd, 0);
1557 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1559 /* exchanged to skip fxch */
1560 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1561 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1562 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1563 /* emit_fxch(cd); */
1568 emit_jcc(cd, CC_P, -(2 + 1 + 2 + 1 + 6));
1569 emit_store_dst(jd, iptr, d);
1570 emit_ffree_reg(cd, 0);
1574 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1575 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1577 var = VAROP(iptr->s1);
1578 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1580 if (var->flags & INMEMORY) {
1581 emit_fildl_membase(cd, REG_SP, var->vv.regoff * 4);
1583 /* XXX not thread safe! */
1584 disp = dseg_add_unique_s4(cd, 0);
1585 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1587 emit_mov_reg_membase(cd, var->vv.regoff, REG_ITMP1, disp);
1588 emit_fildl_membase(cd, REG_ITMP1, disp);
1591 emit_store_dst(jd, iptr, d);
1594 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1595 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1597 var = VAROP(iptr->s1);
1598 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1599 if (var->flags & INMEMORY) {
1600 emit_fildll_membase(cd, REG_SP, var->vv.regoff * 4);
1603 log_text("L2F: longs have to be in memory");
1606 emit_store_dst(jd, iptr, d);
1609 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1611 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1612 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1614 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1617 /* Round to zero, 53-bit mode, exception masked */
1618 disp = dseg_add_s4(cd, 0x0e7f);
1619 emit_fldcw_membase(cd, REG_ITMP1, disp);
1621 var = VAROP(iptr->dst);
1622 var1 = VAROP(iptr->s1);
1624 if (var->flags & INMEMORY) {
1625 emit_fistpl_membase(cd, REG_SP, var->vv.regoff * 4);
1627 /* Round to nearest, 53-bit mode, exceptions masked */
1628 disp = dseg_add_s4(cd, 0x027f);
1629 emit_fldcw_membase(cd, REG_ITMP1, disp);
1631 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1632 REG_SP, var->vv.regoff * 4);
1635 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1637 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1640 /* XXX not thread safe! */
1641 disp = dseg_add_unique_s4(cd, 0);
1642 emit_fistpl_membase(cd, REG_ITMP1, disp);
1643 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1645 /* Round to nearest, 53-bit mode, exceptions masked */
1646 disp = dseg_add_s4(cd, 0x027f);
1647 emit_fldcw_membase(cd, REG_ITMP1, disp);
1649 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1652 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1653 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1656 emit_jcc(cd, CC_NE, disp);
1658 /* XXX: change this when we use registers */
1659 emit_flds_membase(cd, REG_SP, var1->vv.regoff * 4);
1660 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2i, REG_ITMP1);
1661 emit_call_reg(cd, REG_ITMP1);
1663 if (var->flags & INMEMORY) {
1664 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff * 4);
1667 M_INTMOVE(REG_RESULT, var->vv.regoff);
1671 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1673 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1674 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1676 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1679 /* Round to zero, 53-bit mode, exception masked */
1680 disp = dseg_add_s4(cd, 0x0e7f);
1681 emit_fldcw_membase(cd, REG_ITMP1, disp);
1683 var = VAROP(iptr->dst);
1684 var1 = VAROP(iptr->s1);
1686 if (var->flags & INMEMORY) {
1687 emit_fistpl_membase(cd, REG_SP, var->vv.regoff * 4);
1689 /* Round to nearest, 53-bit mode, exceptions masked */
1690 disp = dseg_add_s4(cd, 0x027f);
1691 emit_fldcw_membase(cd, REG_ITMP1, disp);
1693 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1694 REG_SP, var->vv.regoff * 4);
1697 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1699 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1702 /* XXX not thread safe! */
1703 disp = dseg_add_unique_s4(cd, 0);
1704 emit_fistpl_membase(cd, REG_ITMP1, disp);
1705 emit_mov_membase_reg(cd, REG_ITMP1, disp, var->vv.regoff);
1707 /* Round to nearest, 53-bit mode, exceptions masked */
1708 disp = dseg_add_s4(cd, 0x027f);
1709 emit_fldcw_membase(cd, REG_ITMP1, disp);
1711 emit_alu_imm_reg(cd, ALU_CMP, 0x80000000, var->vv.regoff);
1714 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1715 disp += 5 + 2 + ((REG_RESULT == var->vv.regoff) ? 0 : 2);
1718 emit_jcc(cd, CC_NE, disp);
1720 /* XXX: change this when we use registers */
1721 emit_fldl_membase(cd, REG_SP, var1->vv.regoff * 4);
1722 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2i, REG_ITMP1);
1723 emit_call_reg(cd, REG_ITMP1);
1725 if (var->flags & INMEMORY) {
1726 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff * 4);
1728 M_INTMOVE(REG_RESULT, var->vv.regoff);
1732 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1734 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1735 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1737 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1740 /* Round to zero, 53-bit mode, exception masked */
1741 disp = dseg_add_s4(cd, 0x0e7f);
1742 emit_fldcw_membase(cd, REG_ITMP1, disp);
1744 var = VAROP(iptr->dst);
1745 var1 = VAROP(iptr->s1);
1747 if (var->flags & INMEMORY) {
1748 emit_fistpll_membase(cd, REG_SP, var->vv.regoff * 4);
1750 /* Round to nearest, 53-bit mode, exceptions masked */
1751 disp = dseg_add_s4(cd, 0x027f);
1752 emit_fldcw_membase(cd, REG_ITMP1, disp);
1754 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1755 REG_SP, var->vv.regoff * 4 + 4);
1758 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1760 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1763 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1765 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4 + 4);
1767 emit_jcc(cd, CC_NE, disp);
1769 emit_alu_imm_membase(cd, ALU_CMP, 0,
1770 REG_SP, var->vv.regoff * 4);
1773 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1775 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1777 emit_jcc(cd, CC_NE, disp);
1779 /* XXX: change this when we use registers */
1780 emit_flds_membase(cd, REG_SP, var1->vv.regoff * 4);
1781 emit_mov_imm_reg(cd, (ptrint) asm_builtin_f2l, REG_ITMP1);
1782 emit_call_reg(cd, REG_ITMP1);
1783 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff * 4);
1784 emit_mov_reg_membase(cd, REG_RESULT2,
1785 REG_SP, var->vv.regoff * 4 + 4);
1788 log_text("F2L: longs have to be in memory");
1793 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1795 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1796 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1798 emit_mov_imm_reg(cd, 0, REG_ITMP1);
1801 /* Round to zero, 53-bit mode, exception masked */
1802 disp = dseg_add_s4(cd, 0x0e7f);
1803 emit_fldcw_membase(cd, REG_ITMP1, disp);
1805 var = VAROP(iptr->dst);
1806 var1 = VAROP(iptr->s1);
1808 if (var->flags & INMEMORY) {
1809 emit_fistpll_membase(cd, REG_SP, var->vv.regoff * 4);
1811 /* Round to nearest, 53-bit mode, exceptions masked */
1812 disp = dseg_add_s4(cd, 0x027f);
1813 emit_fldcw_membase(cd, REG_ITMP1, disp);
1815 emit_alu_imm_membase(cd, ALU_CMP, 0x80000000,
1816 REG_SP, var->vv.regoff * 4 + 4);
1819 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1821 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1824 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1826 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4 + 4);
1828 emit_jcc(cd, CC_NE, disp);
1830 emit_alu_imm_membase(cd, ALU_CMP, 0, REG_SP, var->vv.regoff * 4);
1833 CALCOFFSETBYTES(disp, REG_SP, var1->vv.regoff * 4);
1835 CALCOFFSETBYTES(disp, REG_SP, var->vv.regoff * 4);
1837 emit_jcc(cd, CC_NE, disp);
1839 /* XXX: change this when we use registers */
1840 emit_fldl_membase(cd, REG_SP, var1->vv.regoff * 4);
1841 emit_mov_imm_reg(cd, (ptrint) asm_builtin_d2l, REG_ITMP1);
1842 emit_call_reg(cd, REG_ITMP1);
1843 emit_mov_reg_membase(cd, REG_RESULT, REG_SP, var->vv.regoff * 4);
1844 emit_mov_reg_membase(cd, REG_RESULT2,
1845 REG_SP, var->vv.regoff * 4 + 4);
1848 log_text("D2L: longs have to be in memory");
1853 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1855 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1856 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1858 emit_store_dst(jd, iptr, d);
1861 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1863 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1864 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1866 emit_store_dst(jd, iptr, d);
1869 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1872 /* exchanged to skip fxch */
1873 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1874 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1876 /* emit_fxch(cd); */
1879 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as GT */
1880 emit_jcc(cd, CC_E, 6);
1881 emit_alu_imm_reg(cd, ALU_AND, 0x000000ff, EAX);
1883 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
1884 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1885 emit_jcc(cd, CC_B, 3 + 5);
1886 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1887 emit_jmp_imm(cd, 3);
1888 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1889 emit_store_dst(jd, iptr, d);
1892 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1895 /* exchanged to skip fxch */
1896 s2 = emit_load_s1(jd, iptr, REG_FTMP1);
1897 s1 = emit_load_s2(jd, iptr, REG_FTMP2);
1898 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1899 /* emit_fxch(cd); */
1902 emit_test_imm_reg(cd, 0x400, EAX); /* unordered treat as LT */
1903 emit_jcc(cd, CC_E, 3);
1904 emit_movb_imm_reg(cd, 1, REG_AH);
1906 emit_mov_imm_reg(cd, 0, d); /* does not affect flags */
1907 emit_jcc(cd, CC_E, 6 + 3 + 5 + 3);
1908 emit_jcc(cd, CC_B, 3 + 5);
1909 emit_alu_imm_reg(cd, ALU_SUB, 1, d);
1910 emit_jmp_imm(cd, 3);
1911 emit_alu_imm_reg(cd, ALU_ADD, 1, d);
1912 emit_store_dst(jd, iptr, d);
1916 /* memory operations **************************************************/
1918 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1922 /* implicit null-pointer check */
1923 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1924 emit_store_dst(jd, iptr, d);
1927 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1932 /* implicit null-pointer check */
1933 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1934 emit_movsbl_memindex_reg(cd, OFFSET(java_bytearray, data[0]),
1936 emit_store_dst(jd, iptr, d);
1939 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1942 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1943 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1944 /* implicit null-pointer check */
1945 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1946 emit_movzwl_memindex_reg(cd, OFFSET(java_chararray, data[0]),
1948 emit_store_dst(jd, iptr, d);
1951 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1954 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1955 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1956 /* implicit null-pointer check */
1957 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1958 emit_movswl_memindex_reg(cd, OFFSET(java_shortarray, data[0]),
1960 emit_store_dst(jd, iptr, d);
1963 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1966 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1968 /* implicit null-pointer check */
1969 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1970 emit_mov_memindex_reg(cd, OFFSET(java_intarray, data[0]),
1972 emit_store_dst(jd, iptr, d);
1975 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1978 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1979 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1980 /* implicit null-pointer check */
1981 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1983 var = VAROP(iptr->dst);
1985 assert(var->flags & INMEMORY);
1986 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]),
1987 s1, s2, 3, REG_ITMP3);
1988 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff * 4);
1989 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]) + 4,
1990 s1, s2, 3, REG_ITMP3);
1991 emit_mov_reg_membase(cd, REG_ITMP3, REG_SP, var->vv.regoff * 4 + 4);
1994 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1996 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1997 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1998 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1999 /* implicit null-pointer check */
2000 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2001 emit_flds_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2002 emit_store_dst(jd, iptr, d);
2005 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
2007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2008 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2009 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
2010 /* implicit null-pointer check */
2011 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2012 emit_fldl_memindex(cd, OFFSET(java_doublearray, data[0]), s1, s2,3);
2013 emit_store_dst(jd, iptr, d);
2016 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
2018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2021 /* implicit null-pointer check */
2022 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2023 emit_mov_memindex_reg(cd, OFFSET(java_objectarray, data[0]),
2025 emit_store_dst(jd, iptr, d);
2029 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
2031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2032 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2033 /* implicit null-pointer check */
2034 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2035 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2037 /* because EBP, ESI, EDI have no xH and xL nibbles */
2038 M_INTMOVE(s3, REG_ITMP3);
2041 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]),
2045 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
2047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2049 /* implicit null-pointer check */
2050 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2051 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2052 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]),
2056 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2059 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2060 /* implicit null-pointer check */
2061 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2062 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2063 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]),
2067 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
2069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2071 /* implicit null-pointer check */
2072 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2073 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2074 emit_mov_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]),
2078 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
2080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2081 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2082 /* implicit null-pointer check */
2083 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2085 var = VAROP(iptr->sx.s23.s3);
2087 assert(var->flags & INMEMORY);
2088 emit_mov_membase_reg(cd, REG_SP, var->vv.regoff * 4, REG_ITMP3);
2089 emit_mov_reg_memindex(cd, REG_ITMP3, OFFSET(java_longarray, data[0])
2091 emit_mov_membase_reg(cd, REG_SP, var->vv.regoff * 4 + 4, REG_ITMP3);
2092 emit_mov_reg_memindex(cd, REG_ITMP3,
2093 OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2096 case ICMD_FASTORE: /* ..., 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_fstps_memindex(cd, OFFSET(java_floatarray, data[0]), s1, s2,2);
2106 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2109 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2110 /* implicit null-pointer check */
2111 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2112 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
2113 emit_fstpl_memindex(cd, OFFSET(java_doublearray, data[0]),
2117 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2120 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2121 /* implicit null-pointer check */
2122 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2123 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2125 M_AST(s1, REG_SP, 0 * 4);
2126 M_AST(s3, REG_SP, 1 * 4);
2127 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2129 emit_exception_check(cd, iptr);
2131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2133 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2134 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]),
2138 case ICMD_BASTORECONST: /* ..., 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_movb_imm_memindex(cd, iptr->sx.s23.s3.constval,
2145 OFFSET(java_bytearray, data[0]), s1, s2, 0);
2148 case ICMD_CASTORECONST: /* ..., 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_chararray, data[0]), s1, s2, 1);
2158 case ICMD_SASTORECONST: /* ..., 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_movw_imm_memindex(cd, iptr->sx.s23.s3.constval,
2165 OFFSET(java_shortarray, data[0]), s1, s2, 1);
2168 case ICMD_IASTORECONST: /* ..., 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, iptr->sx.s23.s3.constval,
2175 OFFSET(java_intarray, data[0]), s1, s2, 2);
2178 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2181 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2182 /* implicit null-pointer check */
2183 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2184 emit_mov_imm_memindex(cd,
2185 (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff),
2186 OFFSET(java_longarray, data[0]), s1, s2, 3);
2187 emit_mov_imm_memindex(cd,
2188 ((s4)iptr->sx.s23.s3.constval) >> 31,
2189 OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2192 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2196 /* implicit null-pointer check */
2197 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2198 emit_mov_imm_memindex(cd, 0,
2199 OFFSET(java_objectarray, data[0]), s1, s2, 2);
2203 case ICMD_GETSTATIC: /* ... ==> ..., value */
2205 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2206 uf = iptr->sx.s23.s3.uf;
2207 fieldtype = uf->fieldref->parseddesc.fd->type;
2210 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
2214 fi = iptr->sx.s23.s3.fmiref->p.field;
2215 fieldtype = fi->type;
2216 disp = (ptrint) &(fi->value);
2218 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2219 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2222 M_MOV_IMM(disp, REG_ITMP1);
2223 switch (fieldtype) {
2226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2227 M_ILD(d, REG_ITMP1, 0);
2230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2231 M_LLD(d, REG_ITMP1, 0);
2234 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2235 M_FLD(d, REG_ITMP1, 0);
2238 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2239 M_DLD(d, REG_ITMP1, 0);
2242 emit_store_dst(jd, iptr, d);
2245 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2247 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2248 uf = iptr->sx.s23.s3.uf;
2249 fieldtype = uf->fieldref->parseddesc.fd->type;
2252 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
2255 fi = iptr->sx.s23.s3.fmiref->p.field;
2256 fieldtype = fi->type;
2257 disp = (ptrint) &(fi->value);
2259 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2260 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2263 M_MOV_IMM(disp, REG_ITMP1);
2264 switch (fieldtype) {
2267 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2268 M_IST(s1, REG_ITMP1, 0);
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2272 M_LST(s1, REG_ITMP1, 0);
2275 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2276 emit_fstps_membase(cd, REG_ITMP1, 0);
2279 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
2280 emit_fstpl_membase(cd, REG_ITMP1, 0);
2285 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2286 /* val = value (in current instruction) */
2287 /* following NOP) */
2289 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2290 uf = iptr->sx.s23.s3.uf;
2291 fieldtype = uf->fieldref->parseddesc.fd->type;
2294 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
2297 fi = iptr->sx.s23.s3.fmiref->p.field;
2298 fieldtype = fi->type;
2299 disp = (ptrint) &(fi->value);
2301 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2302 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2305 M_MOV_IMM(disp, REG_ITMP1);
2306 switch (fieldtype) {
2309 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2312 M_IST_IMM(iptr->sx.s23.s2.constval & 0xffffffff, REG_ITMP1, 0);
2313 M_IST_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, REG_ITMP1, 4);
2320 case ICMD_GETFIELD: /* .., objectref. ==> ..., value */
2322 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2323 emit_nullpointer_check(cd, iptr, s1);
2325 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2326 unresolved_field *uf = iptr->sx.s23.s3.uf;
2328 fieldtype = uf->fieldref->parseddesc.fd->type;
2330 codegen_addpatchref(cd, PATCHER_getfield,
2331 iptr->sx.s23.s3.uf, 0);
2337 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2339 fieldtype = fi->type;
2343 switch (fieldtype) {
2346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2347 M_ILD32(d, s1, disp);
2350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2351 M_LLD32(d, s1, disp);
2354 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2355 M_FLD32(d, s1, disp);
2358 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2359 M_DLD32(d, s1, disp);
2362 emit_store_dst(jd, iptr, d);
2365 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2368 emit_nullpointer_check(cd, iptr, s1);
2370 /* must be done here because of code patching */
2372 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2373 unresolved_field *uf = iptr->sx.s23.s3.uf;
2375 fieldtype = uf->fieldref->parseddesc.fd->type;
2378 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2380 fieldtype = fi->type;
2383 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2384 if (IS_2_WORD_TYPE(fieldtype))
2385 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2387 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2390 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2392 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2393 unresolved_field *uf = iptr->sx.s23.s3.uf;
2395 codegen_addpatchref(cd, PATCHER_putfield, uf, 0);
2401 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2406 switch (fieldtype) {
2409 M_IST32(s2, s1, disp);
2412 M_LST32(s2, s1, disp);
2415 emit_fstps_membase32(cd, s1, disp);
2418 emit_fstpl_membase32(cd, s1, disp);
2423 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2424 /* val = value (in current instruction) */
2425 /* following NOP) */
2427 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2428 emit_nullpointer_check(cd, iptr, s1);
2430 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2431 unresolved_field *uf = iptr->sx.s23.s3.uf;
2433 fieldtype = uf->fieldref->parseddesc.fd->type;
2435 codegen_addpatchref(cd, PATCHER_putfieldconst,
2443 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2445 fieldtype = fi->type;
2450 switch (fieldtype) {
2453 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2456 M_IST32_IMM(iptr->sx.s23.s2.constval & 0xffffffff, s1, disp);
2457 M_IST32_IMM(((s4)iptr->sx.s23.s2.constval) >> 31, s1, disp + 4);
2465 /* branch operations **************************************************/
2467 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2469 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2470 M_INTMOVE(s1, REG_ITMP1_XPTR);
2472 #ifdef ENABLE_VERIFIER
2473 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2474 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2475 iptr->sx.s23.s2.uc, 0);
2477 #endif /* ENABLE_VERIFIER */
2479 M_CALL_IMM(0); /* passing exception pc */
2480 M_POP(REG_ITMP2_XPC);
2482 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2486 case ICMD_GOTO: /* ... ==> ... */
2487 case ICMD_RET: /* ... ==> ... */
2489 #if defined(ENABLE_SSA)
2491 last_cmd_was_goto = true;
2492 /* In case of a Goto phimoves have to be inserted before the */
2494 codegen_insert_phi_moves(jd, bptr);
2497 emit_br(cd, iptr->dst.block);
2501 case ICMD_JSR: /* ... ==> ... */
2503 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2507 case ICMD_IFNULL: /* ..., value ==> ... */
2508 case ICMD_IFNONNULL:
2510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2512 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
2515 case ICMD_IFEQ: /* ..., value ==> ... */
2522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2523 M_CMP_IMM(iptr->sx.val.i, s1);
2524 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
2527 case ICMD_IF_LEQ: /* ..., value ==> ... */
2529 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2530 if (iptr->sx.val.l == 0) {
2531 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2532 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2535 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2536 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2537 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2538 M_OR(REG_ITMP2, REG_ITMP1);
2540 emit_beq(cd, iptr->dst.block);
2543 case ICMD_IF_LLT: /* ..., value ==> ... */
2545 if (iptr->sx.val.l == 0) {
2546 /* If high 32-bit are less than zero, then the 64-bits
2548 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2550 emit_blt(cd, iptr->dst.block);
2553 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2554 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2555 emit_blt(cd, iptr->dst.block);
2557 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2558 emit_bult(cd, iptr->dst.block);
2562 case ICMD_IF_LLE: /* ..., value ==> ... */
2564 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2565 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2566 emit_blt(cd, iptr->dst.block);
2568 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2569 emit_bule(cd, iptr->dst.block);
2572 case ICMD_IF_LNE: /* ..., value ==> ... */
2574 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2575 if (iptr->sx.val.l == 0) {
2576 M_INTMOVE(GET_LOW_REG(s1), REG_ITMP1);
2577 M_OR(GET_HIGH_REG(s1), REG_ITMP1);
2580 M_LNGMOVE(s1, REG_ITMP12_PACKED);
2581 M_XOR_IMM(iptr->sx.val.l, REG_ITMP1);
2582 M_XOR_IMM(iptr->sx.val.l >> 32, REG_ITMP2);
2583 M_OR(REG_ITMP2, REG_ITMP1);
2585 emit_bne(cd, iptr->dst.block);
2588 case ICMD_IF_LGT: /* ..., value ==> ... */
2590 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2591 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2592 emit_bgt(cd, iptr->dst.block);
2594 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2595 emit_bugt(cd, iptr->dst.block);
2598 case ICMD_IF_LGE: /* ..., value ==> ... */
2600 if (iptr->sx.val.l == 0) {
2601 /* If high 32-bit are greater equal zero, then the
2603 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2605 emit_bge(cd, iptr->dst.block);
2608 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2609 M_CMP_IMM(iptr->sx.val.l >> 32, GET_HIGH_REG(s1));
2610 emit_bgt(cd, iptr->dst.block);
2612 M_CMP_IMM32(iptr->sx.val.l, GET_LOW_REG(s1));
2613 emit_buge(cd, iptr->dst.block);
2617 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2618 case ICMD_IF_ICMPNE:
2619 case ICMD_IF_ICMPLT:
2620 case ICMD_IF_ICMPGT:
2621 case ICMD_IF_ICMPGE:
2622 case ICMD_IF_ICMPLE:
2624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2627 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2630 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2631 case ICMD_IF_ACMPNE:
2633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2634 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2636 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2639 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2641 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2642 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2643 M_INTMOVE(s1, REG_ITMP1);
2644 M_XOR(s2, REG_ITMP1);
2645 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2646 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2647 M_INTMOVE(s1, REG_ITMP2);
2648 M_XOR(s2, REG_ITMP2);
2649 M_OR(REG_ITMP1, REG_ITMP2);
2650 emit_beq(cd, iptr->dst.block);
2653 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2655 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2656 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2657 M_INTMOVE(s1, REG_ITMP1);
2658 M_XOR(s2, REG_ITMP1);
2659 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2660 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
2661 M_INTMOVE(s1, REG_ITMP2);
2662 M_XOR(s2, REG_ITMP2);
2663 M_OR(REG_ITMP1, REG_ITMP2);
2664 emit_bne(cd, iptr->dst.block);
2667 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2669 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2670 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2672 emit_blt(cd, iptr->dst.block);
2673 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2674 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2677 emit_bult(cd, iptr->dst.block);
2680 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2682 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2683 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2685 emit_bgt(cd, iptr->dst.block);
2686 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2687 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2690 emit_bugt(cd, iptr->dst.block);
2693 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2695 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2696 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2698 emit_blt(cd, iptr->dst.block);
2699 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2700 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2703 emit_bule(cd, iptr->dst.block);
2706 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2708 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2709 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2711 emit_bgt(cd, iptr->dst.block);
2712 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2713 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2716 emit_buge(cd, iptr->dst.block);
2720 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2722 REPLACEMENT_POINT_RETURN(cd, iptr);
2723 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2724 M_INTMOVE(s1, REG_RESULT);
2725 goto nowperformreturn;
2727 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2729 REPLACEMENT_POINT_RETURN(cd, iptr);
2730 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2731 M_LNGMOVE(s1, REG_RESULT_PACKED);
2732 goto nowperformreturn;
2734 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2736 REPLACEMENT_POINT_RETURN(cd, iptr);
2737 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2738 M_INTMOVE(s1, REG_RESULT);
2740 #ifdef ENABLE_VERIFIER
2741 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2742 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2743 iptr->sx.s23.s2.uc, 0);
2745 #endif /* ENABLE_VERIFIER */
2746 goto nowperformreturn;
2748 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2751 REPLACEMENT_POINT_RETURN(cd, iptr);
2752 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2753 goto nowperformreturn;
2755 case ICMD_RETURN: /* ... ==> ... */
2757 REPLACEMENT_POINT_RETURN(cd, iptr);
2763 p = cd->stackframesize;
2765 #if !defined(NDEBUG)
2766 emit_verbosecall_exit(jd);
2769 #if defined(ENABLE_THREADS)
2770 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2771 M_ALD(REG_ITMP2, REG_SP, rd->memuse * 4);
2773 /* we need to save the proper return value */
2774 switch (iptr->opc) {
2777 M_IST(REG_RESULT, REG_SP, rd->memuse * 4);
2781 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
2785 emit_fstps_membase(cd, REG_SP, rd->memuse * 4);
2789 emit_fstpl_membase(cd, REG_SP, rd->memuse * 4);
2793 M_AST(REG_ITMP2, REG_SP, 0);
2794 M_MOV_IMM(LOCK_monitor_exit, REG_ITMP3);
2797 /* and now restore the proper return value */
2798 switch (iptr->opc) {
2801 M_ILD(REG_RESULT, REG_SP, rd->memuse * 4);
2805 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
2809 emit_flds_membase(cd, REG_SP, rd->memuse * 4);
2813 emit_fldl_membase(cd, REG_SP, rd->memuse * 4);
2819 /* restore saved registers */
2821 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2822 p--; M_ALD(rd->savintregs[i], REG_SP, p * 4);
2825 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2827 emit_fldl_membase(cd, REG_SP, p * 4);
2828 if (iptr->opc == ICMD_FRETURN || iptr->opc == ICMD_DRETURN) {
2830 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset + 1); */
2833 /* emit_fstp_reg(cd, rd->savfltregs[i] + fpu_st_offset); */
2837 /* deallocate stack */
2839 if (cd->stackframesize)
2840 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2847 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2850 branch_target_t *table;
2852 table = iptr->dst.table;
2854 l = iptr->sx.s23.s2.tablelow;
2855 i = iptr->sx.s23.s3.tablehigh;
2857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2858 M_INTMOVE(s1, REG_ITMP1);
2861 M_ISUB_IMM(l, REG_ITMP1);
2867 M_CMP_IMM(i - 1, REG_ITMP1);
2868 emit_bugt(cd, table[0].block);
2870 /* build jump table top down and use address of lowest entry */
2875 dseg_add_target(cd, table->block);
2879 /* length of dataseg after last dseg_addtarget is used
2882 M_MOV_IMM(0, REG_ITMP2);
2884 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 2, REG_ITMP1);
2890 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2893 lookup_target_t *lookup;
2895 lookup = iptr->dst.lookup;
2897 i = iptr->sx.s23.s2.lookupcount;
2899 MCODECHECK((i<<2)+8);
2900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2903 M_CMP_IMM(lookup->value, s1);
2904 emit_beq(cd, lookup->target.block);
2908 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2913 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2915 bte = iptr->sx.s23.s3.bte;
2919 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2921 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2922 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2923 case ICMD_INVOKEINTERFACE:
2925 REPLACEMENT_POINT_INVOKE(cd, iptr);
2927 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2928 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
2932 lm = iptr->sx.s23.s3.fmiref->p.method;
2933 md = lm->parseddesc;
2937 s3 = md->paramcount;
2939 MCODECHECK((s3 << 1) + 64);
2941 /* copy arguments to registers or stack location */
2943 for (s3 = s3 - 1; s3 >= 0; s3--) {
2944 var = VAR(iptr->sx.s23.s2.args[s3]);
2946 /* Already Preallocated (ARGVAR) ? */
2947 if (var->flags & PREALLOC)
2949 if (IS_INT_LNG_TYPE(var->type)) {
2950 if (!md->params[s3].inmemory) {
2951 log_text("No integer argument registers available!");
2955 if (IS_2_WORD_TYPE(var->type)) {
2956 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2957 M_LST(d, REG_SP, md->params[s3].regoff * 4);
2959 d = emit_load(jd, iptr, var, REG_ITMP1);
2960 M_IST(d, REG_SP, md->params[s3].regoff * 4);
2965 if (!md->params[s3].inmemory) {
2966 s1 = rd->argfltregs[md->params[s3].regoff];
2967 d = emit_load(jd, iptr, var, s1);
2971 d = emit_load(jd, iptr, var, REG_FTMP1);
2972 if (IS_2_WORD_TYPE(var->type))
2973 M_DST(d, REG_SP, md->params[s3].regoff * 4);
2975 M_FST(d, REG_SP, md->params[s3].regoff * 4);
2980 switch (iptr->opc) {
2982 disp = (ptrint) bte->fp;
2983 d = md->returntype.type;
2985 M_MOV_IMM(disp, REG_ITMP1);
2988 emit_exception_check(cd, iptr);
2991 case ICMD_INVOKESPECIAL:
2992 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
2993 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2996 case ICMD_INVOKESTATIC:
2998 unresolved_method *um = iptr->sx.s23.s3.um;
3000 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3004 d = md->returntype.type;
3007 disp = (ptrint) lm->stubroutine;
3008 d = lm->parseddesc->returntype.type;
3011 M_MOV_IMM(disp, REG_ITMP2);
3015 case ICMD_INVOKEVIRTUAL:
3016 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3017 emit_nullpointer_check(cd, iptr, s1);
3020 unresolved_method *um = iptr->sx.s23.s3.um;
3022 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3025 d = md->returntype.type;
3028 s1 = OFFSET(vftbl_t, table[0]) +
3029 sizeof(methodptr) * lm->vftblindex;
3030 d = md->returntype.type;
3033 M_ALD(REG_METHODPTR, REG_ITMP1,
3034 OFFSET(java_objectheader, vftbl));
3035 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3039 case ICMD_INVOKEINTERFACE:
3040 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3041 emit_nullpointer_check(cd, iptr, s1);
3044 unresolved_method *um = iptr->sx.s23.s3.um;
3046 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3050 d = md->returntype.type;
3053 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3054 sizeof(methodptr) * lm->class->index;
3056 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3058 d = md->returntype.type;
3061 M_ALD(REG_METHODPTR, REG_ITMP1,
3062 OFFSET(java_objectheader, vftbl));
3063 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3064 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3069 /* store size of call code in replacement point */
3071 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3073 /* d contains return type */
3075 if (d != TYPE_VOID) {
3076 #if defined(ENABLE_SSA)
3077 if ((ls == NULL) || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) ||
3078 (ls->lifetime[-iptr->dst.varindex-1].type != -1))
3079 /* a "living" stackslot */
3082 if (IS_INT_LNG_TYPE(d)) {
3083 if (IS_2_WORD_TYPE(d)) {
3084 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3085 M_LNGMOVE(REG_RESULT_PACKED, s1);
3088 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3089 M_INTMOVE(REG_RESULT, s1);
3093 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3095 emit_store_dst(jd, iptr, s1);
3101 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3102 /* val.a: (classinfo*) superclass */
3104 /* superclass is an interface:
3106 * OK if ((sub == NULL) ||
3107 * (sub->vftbl->interfacetablelength > super->index) &&
3108 * (sub->vftbl->interfacetable[-super->index] != NULL));
3110 * superclass is a class:
3112 * OK if ((sub == NULL) || (0
3113 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3114 * super->vftbl->diffval));
3117 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3118 /* object type cast-check */
3121 vftbl_t *supervftbl;
3124 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3130 super = iptr->sx.s23.s3.c.cls;
3131 superindex = super->index;
3132 supervftbl = super->vftbl;
3135 #if defined(ENABLE_THREADS)
3136 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3138 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3140 /* if class is not resolved, check which code to call */
3142 if (super == NULL) {
3144 emit_label_beq(cd, BRANCH_LABEL_1);
3146 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3147 iptr->sx.s23.s3.c.ref, 0);
3149 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3150 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3151 emit_label_beq(cd, BRANCH_LABEL_2);
3154 /* interface checkcast code */
3156 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3157 if (super != NULL) {
3159 emit_label_beq(cd, BRANCH_LABEL_3);
3162 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3164 if (super == NULL) {
3165 codegen_addpatchref(cd, PATCHER_checkcast_interface,
3166 iptr->sx.s23.s3.c.ref,
3171 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3172 M_ISUB_IMM32(superindex, REG_ITMP3);
3173 /* XXX do we need this one? */
3175 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
3177 M_ALD32(REG_ITMP3, REG_ITMP2,
3178 OFFSET(vftbl_t, interfacetable[0]) -
3179 superindex * sizeof(methodptr*));
3181 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
3184 emit_label_br(cd, BRANCH_LABEL_4);
3186 emit_label(cd, BRANCH_LABEL_3);
3189 /* class checkcast code */
3191 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3192 if (super == NULL) {
3193 emit_label(cd, BRANCH_LABEL_2);
3197 emit_label_beq(cd, BRANCH_LABEL_5);
3200 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3202 if (super == NULL) {
3203 codegen_addpatchref(cd, PATCHER_checkcast_class,
3204 iptr->sx.s23.s3.c.ref,
3208 M_MOV_IMM(supervftbl, REG_ITMP3);
3209 #if defined(ENABLE_THREADS)
3210 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3212 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3214 /* if (s1 != REG_ITMP1) { */
3215 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3216 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3217 /* #if defined(ENABLE_THREADS) */
3218 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3220 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3223 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3224 M_ISUB(REG_ITMP3, REG_ITMP2);
3225 M_MOV_IMM(supervftbl, REG_ITMP3);
3226 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3227 #if defined(ENABLE_THREADS)
3228 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3232 M_CMP(REG_ITMP3, REG_ITMP2);
3233 emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
3236 emit_label(cd, BRANCH_LABEL_5);
3239 if (super == NULL) {
3240 emit_label(cd, BRANCH_LABEL_1);
3241 emit_label(cd, BRANCH_LABEL_4);
3244 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3247 /* array type cast-check */
3249 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3250 M_AST(s1, REG_SP, 0 * 4);
3252 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3253 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3254 iptr->sx.s23.s3.c.ref, 0);
3257 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3258 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3261 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3263 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3265 d = codegen_reg_of_dst(jd, iptr, s1);
3269 emit_store_dst(jd, iptr, d);
3272 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3273 /* val.a: (classinfo*) superclass */
3275 /* superclass is an interface:
3277 * return (sub != NULL) &&
3278 * (sub->vftbl->interfacetablelength > super->index) &&
3279 * (sub->vftbl->interfacetable[-super->index] != NULL);
3281 * superclass is a class:
3283 * return ((sub != NULL) && (0
3284 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3285 * super->vftbl->diffvall));
3290 vftbl_t *supervftbl;
3293 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3299 super = iptr->sx.s23.s3.c.cls;
3300 superindex = super->index;
3301 supervftbl = super->vftbl;
3304 #if defined(ENABLE_THREADS)
3305 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3309 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3312 M_INTMOVE(s1, REG_ITMP1);
3318 /* if class is not resolved, check which code to call */
3320 if (super == NULL) {
3322 emit_label_beq(cd, BRANCH_LABEL_1);
3324 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3325 iptr->sx.s23.s3.c.ref, 0);
3327 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
3328 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3329 emit_label_beq(cd, BRANCH_LABEL_2);
3332 /* interface instanceof code */
3334 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3335 if (super != NULL) {
3337 emit_label_beq(cd, BRANCH_LABEL_3);
3340 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3342 if (super == NULL) {
3343 codegen_addpatchref(cd, PATCHER_instanceof_interface,
3344 iptr->sx.s23.s3.c.ref, 0);
3348 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3349 M_ISUB_IMM32(superindex, REG_ITMP3);
3352 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3353 6 /* jcc */ + 5 /* mov_imm_reg */);
3356 M_ALD32(REG_ITMP1, REG_ITMP1,
3357 OFFSET(vftbl_t, interfacetable[0]) -
3358 superindex * sizeof(methodptr*));
3360 /* emit_setcc_reg(cd, CC_A, d); */
3361 /* emit_jcc(cd, CC_BE, 5); */
3366 emit_label_br(cd, BRANCH_LABEL_4);
3368 emit_label(cd, BRANCH_LABEL_3);
3371 /* class instanceof code */
3373 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3374 if (super == NULL) {
3375 emit_label(cd, BRANCH_LABEL_2);
3379 emit_label_beq(cd, BRANCH_LABEL_5);
3382 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3384 if (super == NULL) {
3385 codegen_addpatchref(cd, PATCHER_instanceof_class,
3386 iptr->sx.s23.s3.c.ref, 0);
3389 M_MOV_IMM(supervftbl, REG_ITMP2);
3390 #if defined(ENABLE_THREADS)
3391 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3393 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3394 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3395 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3396 #if defined(ENABLE_THREADS)
3397 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3399 M_ISUB(REG_ITMP2, REG_ITMP1);
3400 M_CLR(d); /* may be REG_ITMP2 */
3401 M_CMP(REG_ITMP3, REG_ITMP1);
3406 emit_label(cd, BRANCH_LABEL_5);
3409 if (super == NULL) {
3410 emit_label(cd, BRANCH_LABEL_1);
3411 emit_label(cd, BRANCH_LABEL_4);
3414 emit_store_dst(jd, iptr, d);
3418 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3420 /* check for negative sizes and copy sizes to stack if necessary */
3422 MCODECHECK((iptr->s1.argcount << 1) + 64);
3424 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3425 /* copy SAVEDVAR sizes to stack */
3426 var = VAR(iptr->sx.s23.s2.args[s1]);
3428 /* Already Preallocated? */
3429 if (!(var->flags & PREALLOC)) {
3430 if (var->flags & INMEMORY) {
3431 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff * 4);
3432 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3435 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
3439 /* is a patcher function set? */
3441 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3442 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3443 iptr->sx.s23.s3.c.ref, 0);
3449 disp = (ptrint) iptr->sx.s23.s3.c.cls;
3451 /* a0 = dimension count */
3453 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
3455 /* a1 = arraydescriptor */
3457 M_IST_IMM(disp, REG_SP, 1 * 4);
3459 /* a2 = pointer to dimensions = stack pointer */
3461 M_MOV(REG_SP, REG_ITMP1);
3462 M_AADD_IMM(3 * 4, REG_ITMP1);
3463 M_AST(REG_ITMP1, REG_SP, 2 * 4);
3465 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3468 /* check for exception before result assignment */
3470 emit_exception_check(cd, iptr);
3472 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3473 M_INTMOVE(REG_RESULT, s1);
3474 emit_store_dst(jd, iptr, s1);
3478 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3483 } /* for instruction */
3487 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
3490 #if defined(ENABLE_SSA)
3492 /* by edge splitting, in Blocks with phi moves there can only */
3493 /* be a goto as last command, no other Jump/Branch Command */
3494 if (!last_cmd_was_goto)
3495 codegen_insert_phi_moves(jd, bptr);
3500 /* At the end of a basic block we may have to append some nops,
3501 because the patcher stub calling code might be longer than the
3502 actual instruction. So codepatching does not change the
3503 following block unintentionally. */
3505 if (cd->mcodeptr < cd->lastmcodeptr) {
3506 while (cd->mcodeptr < cd->lastmcodeptr) {
3511 } /* if (bptr -> flags >= BBREACHED) */
3512 } /* for basic block */
3514 dseg_createlinenumbertable(cd);
3516 /* generate stubs */
3518 emit_patcher_stubs(jd);
3519 REPLACEMENT_EMIT_STUBS(jd);
3521 /* everything's ok */
3526 #if defined(ENABLE_SSA)
3527 void codegen_insert_phi_moves(jitdata *jd, basicblock *bptr) {
3528 /* look for phi moves */
3529 int t_a,s_a,i, type;
3530 int t_lt, s_lt; /* lifetime indices of phi_moves */
3531 s4 t_regoff, s_regoff, s_flags, t_flags;
3540 /* Moves from phi functions with highest indices have to be */
3541 /* inserted first, since this is the order as is used for */
3542 /* conflict resolution */
3543 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
3544 t_a = ls->phi_moves[bptr->nr][i][0];
3545 s_a = ls->phi_moves[bptr->nr][i][1];
3546 #if defined(SSA_DEBUG_VERBOSE)
3548 printf("BB %3i Move %3i <- %3i ", bptr->nr, t_a, s_a);
3551 /* local var lifetimes */
3552 t_lt = ls->maxlifetimes + t_a;
3553 type = ls->lifetime[t_lt].type;
3557 type = ls->lifetime[t_lt].local_ss->s->type;
3558 /* stackslot lifetime */
3562 #if defined(SSA_DEBUG_VERBOSE)
3564 printf("...returning - phi lifetimes where joined\n");
3570 /* local var lifetimes */
3571 s_lt = ls->maxlifetimes + s_a;
3572 type = ls->lifetime[s_lt].type;
3576 type = ls->lifetime[s_lt].type;
3577 /* stackslot lifetime */
3581 #if defined(SSA_DEBUG_VERBOSE)
3583 printf("...returning - phi lifetimes where joined\n");
3589 t_flags = VAR(t_a)->flags;
3590 t_regoff = VAR(t_a)->vv.regoff;
3594 t_flags = ls->lifetime[t_lt].local_ss->s->flags;
3595 t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
3599 /* local var move */
3600 s_flags = VAR(s_a)->flags;
3601 s_regoff = VAR(s_a)->vv.regoff;
3603 /* stackslot lifetime */
3604 s_flags = ls->lifetime[s_lt].local_ss->s->flags;
3605 s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
3609 #if defined(SSA_DEBUG_VERBOSE)
3611 printf("...returning - phi lifetimes where joined\n");
3616 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
3618 #if defined(SSA_DEBUG_VERBOSE)
3619 if (compileverbose) {
3620 if (IS_INMEMORY(t_flags) && IS_INMEMORY(s_flags)) {
3622 printf("M%3i <- M%3i",t_regoff,s_regoff);
3624 else if (IS_INMEMORY(s_flags)) {
3626 printf("R%3i <- M%3i",t_regoff,s_regoff);
3628 else if (IS_INMEMORY(t_flags)) {
3630 printf("M%3i <- R%3i",t_regoff,s_regoff);
3634 printf("R%3i <- R%3i",t_regoff,s_regoff);
3638 #endif /* defined(SSA_DEBUG_VERBOSE) */
3642 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
3643 s4 dst_regoff, s4 dst_flags) {
3644 if ((IS_INMEMORY(dst_flags)) && (IS_INMEMORY(src_flags))) {
3646 if (dst_regoff != src_regoff) {
3647 if (!IS_2_WORD_TYPE(type)) {
3648 if (IS_FLT_DBL_TYPE(type)) {
3649 emit_flds_membase(cd, REG_SP, src_regoff * 4);
3650 emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
3652 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
3654 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
3656 } else { /* LONG OR DOUBLE */
3657 if (IS_FLT_DBL_TYPE(type)) {
3658 emit_fldl_membase( cd, REG_SP, src_regoff * 4);
3659 emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
3661 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
3663 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
3664 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
3666 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP,
3667 dst_regoff * 4 + 4);
3672 if (IS_FLT_DBL_TYPE(type)) {
3673 log_text("cg_move: flt/dbl type have to be in memory\n");
3676 if (IS_2_WORD_TYPE(type)) {
3677 log_text("cg_move: longs have to be in memory\n");
3680 if (IS_INMEMORY(src_flags)) {
3682 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
3683 } else if (IS_INMEMORY(dst_flags)) {
3685 emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
3688 /* only ints can be in regs on i386 */
3689 M_INTMOVE(src_regoff,dst_regoff);
3693 #endif /* defined(ENABLE_SSA) */
3695 /* createcompilerstub **********************************************************
3697 Creates a stub routine which calls the compiler.
3699 *******************************************************************************/
3701 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3702 #define COMPILERSTUB_CODESIZE 12
3704 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3707 u1 *createcompilerstub(methodinfo *m)
3709 u1 *s; /* memory to hold the stub */
3714 s = CNEW(u1, COMPILERSTUB_SIZE);
3716 /* set data pointer and code pointer */
3719 s = s + COMPILERSTUB_DATASIZE;
3721 /* mark start of dump memory area */
3723 dumpsize = dump_size();
3725 cd = DNEW(codegendata);
3728 /* The codeinfo pointer is actually a pointer to the
3729 methodinfo. This fakes a codeinfo structure. */
3731 d[0] = (ptrint) asm_call_jit_compiler;
3733 d[2] = (ptrint) &d[1]; /* fake code->m */
3735 /* code for the stub */
3737 M_MOV_IMM(m, REG_ITMP1); /* method info */
3738 M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
3741 #if defined(ENABLE_STATISTICS)
3743 count_cstub_len += COMPILERSTUB_SIZE;
3746 /* release dump area */
3748 dump_release(dumpsize);
3754 /* createnativestub ************************************************************
3756 Creates a stub routine which calls a native method.
3758 *******************************************************************************/
3760 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3768 s4 i, j; /* count variables */
3772 /* get required compiler data */
3779 /* set some variables */
3782 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3784 /* calculate stackframe size */
3786 cd->stackframesize =
3787 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3788 sizeof(localref_table) / SIZEOF_VOID_P +
3789 1 + /* function pointer */
3790 4 * 4 + /* 4 arguments (start_native_call) */
3793 /* keep stack 16-byte aligned */
3795 cd->stackframesize |= 0x3;
3797 /* create method header */
3799 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3800 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3801 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3802 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3803 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3804 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3805 (void) dseg_addlinenumbertablesize(cd);
3806 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3808 #if defined(ENABLE_PROFILING)
3809 /* generate native method profiling code */
3811 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3812 /* count frequency */
3814 M_MOV_IMM(code, REG_ITMP1);
3815 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
3819 /* calculate stackframe size for native function */
3821 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
3823 #if !defined(NDEBUG)
3824 emit_verbosecall_enter(jd);
3827 /* get function address (this must happen before the stackframeinfo) */
3829 #if !defined(WITH_STATIC_CLASSPATH)
3831 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
3834 M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
3836 /* Mark the whole fpu stack as free for native functions (only for saved */
3837 /* register count == 0). */
3839 emit_ffree_reg(cd, 0);
3840 emit_ffree_reg(cd, 1);
3841 emit_ffree_reg(cd, 2);
3842 emit_ffree_reg(cd, 3);
3843 emit_ffree_reg(cd, 4);
3844 emit_ffree_reg(cd, 5);
3845 emit_ffree_reg(cd, 6);
3846 emit_ffree_reg(cd, 7);
3848 #if defined(ENABLE_GC_CACAO)
3849 /* remember callee saved int registers in stackframeinfo (GC may need to */
3850 /* recover them during a collection). */
3852 j = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3853 OFFSET(stackframeinfo, intregs);
3854 for (i=0; i<INT_REG_CNT; ++i) {
3855 if (nregdescint[i] == REG_SAV) {
3856 M_AST(i, REG_SP, j);
3862 /* prepare data structures for native function call */
3864 M_MOV(REG_SP, REG_ITMP1);
3865 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3867 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3868 M_IST_IMM(0, REG_SP, 1 * 4);
3871 M_MOV(REG_SP, REG_ITMP2);
3872 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
3874 M_AST(REG_ITMP2, REG_SP, 2 * 4);
3875 M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
3876 M_AST(REG_ITMP3, REG_SP, 3 * 4);
3877 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
3880 M_ALD(REG_ITMP3, REG_SP, 4 * 4);
3882 /* copy arguments into new stackframe */
3884 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3885 t = md->paramtypes[i].type;
3887 if (!md->params[i].inmemory) {
3888 /* no integer argument registers */
3889 } else { /* float/double in memory can be copied like int/longs */
3890 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
3891 s2 = nmd->params[j].regoff * 4;
3893 M_ILD(REG_ITMP1, REG_SP, s1);
3894 M_IST(REG_ITMP1, REG_SP, s2);
3895 if (IS_2_WORD_TYPE(t)) {
3896 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
3897 M_IST(REG_ITMP1, REG_SP, s2 + 4);
3902 /* if function is static, put class into second argument */
3904 if (m->flags & ACC_STATIC)
3905 M_AST_IMM(m->class, REG_SP, 1 * 4);
3907 /* put env into first argument */
3909 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
3911 /* call the native function */
3915 /* save return value */
3917 if (md->returntype.type != TYPE_VOID) {
3918 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3919 if (IS_2_WORD_TYPE(md->returntype.type))
3920 M_IST(REG_RESULT2, REG_SP, 2 * 4);
3921 M_IST(REG_RESULT, REG_SP, 1 * 4);
3924 if (IS_2_WORD_TYPE(md->returntype.type))
3925 emit_fstl_membase(cd, REG_SP, 1 * 4);
3927 emit_fsts_membase(cd, REG_SP, 1 * 4);
3931 #if !defined(NDEBUG)
3932 emit_verbosecall_exit(jd);
3935 /* remove native stackframe info */
3937 M_MOV(REG_SP, REG_ITMP1);
3938 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3940 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3941 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
3943 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
3945 /* restore return value */
3947 if (md->returntype.type != TYPE_VOID) {
3948 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3949 if (IS_2_WORD_TYPE(md->returntype.type))
3950 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
3951 M_ILD(REG_RESULT, REG_SP, 1 * 4);
3954 if (IS_2_WORD_TYPE(md->returntype.type))
3955 emit_fldl_membase(cd, REG_SP, 1 * 4);
3957 emit_flds_membase(cd, REG_SP, 1 * 4);
3961 #if defined(ENABLE_GC_CACAO)
3962 /* restore callee saved int registers from stackframeinfo (GC might have */
3963 /* modified them during a collection). */
3965 j = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3966 OFFSET(stackframeinfo, intregs);
3967 for (i=0; i<INT_REG_CNT; ++i) {
3968 if (nregdescint[i] == REG_SAV) {
3969 M_ALD(i, REG_SP, j);
3975 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3977 /* check for exception */
3984 /* handle exception */
3986 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
3987 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
3988 M_ASUB_IMM(2, REG_ITMP2_XPC);
3990 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
3994 /* generate patcher stubs */
3996 emit_patcher_stubs(jd);
4000 return code->entrypoint;
4005 * These are local overrides for various environment variables in Emacs.
4006 * Please do not remove this and leave it at the end of the file, where
4007 * Emacs will automagically detect them.
4008 * ---------------------------------------------------------------------
4011 * indent-tabs-mode: t
4015 * vim:noexpandtab:sw=4:ts=4: