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 7794 2007-04-23 19:57:45Z 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 ************************************/
662 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
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 = 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 d = md->returntype.type;
2984 if (bte->stub == NULL) {
2985 M_MOV_IMM(bte->fp, REG_ITMP1);
2987 M_MOV_IMM(bte->stub, REG_ITMP1);
2991 emit_exception_check(cd, iptr);
2994 case ICMD_INVOKESPECIAL:
2995 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
2996 emit_nullpointer_check(cd, iptr, REG_ITMP1);
2999 case ICMD_INVOKESTATIC:
3001 unresolved_method *um = iptr->sx.s23.s3.um;
3003 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3007 d = md->returntype.type;
3010 disp = (ptrint) lm->stubroutine;
3011 d = lm->parseddesc->returntype.type;
3014 M_MOV_IMM(disp, REG_ITMP2);
3018 case ICMD_INVOKEVIRTUAL:
3019 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3020 emit_nullpointer_check(cd, iptr, s1);
3023 unresolved_method *um = iptr->sx.s23.s3.um;
3025 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3028 d = md->returntype.type;
3031 s1 = OFFSET(vftbl_t, table[0]) +
3032 sizeof(methodptr) * lm->vftblindex;
3033 d = md->returntype.type;
3036 M_ALD(REG_METHODPTR, REG_ITMP1,
3037 OFFSET(java_objectheader, vftbl));
3038 M_ALD32(REG_ITMP3, REG_METHODPTR, s1);
3042 case ICMD_INVOKEINTERFACE:
3043 M_ALD(REG_ITMP1, REG_SP, 0 * 4);
3044 emit_nullpointer_check(cd, iptr, s1);
3047 unresolved_method *um = iptr->sx.s23.s3.um;
3049 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3053 d = md->returntype.type;
3056 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3057 sizeof(methodptr) * lm->class->index;
3059 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3061 d = md->returntype.type;
3064 M_ALD(REG_METHODPTR, REG_ITMP1,
3065 OFFSET(java_objectheader, vftbl));
3066 M_ALD32(REG_METHODPTR, REG_METHODPTR, s1);
3067 M_ALD32(REG_ITMP3, REG_METHODPTR, s2);
3072 /* store size of call code in replacement point */
3074 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3076 /* d contains return type */
3078 if (d != TYPE_VOID) {
3079 #if defined(ENABLE_SSA)
3080 if ((ls == NULL) || (!IS_TEMPVAR_INDEX(iptr->dst.varindex)) ||
3081 (ls->lifetime[-iptr->dst.varindex-1].type != -1))
3082 /* a "living" stackslot */
3085 if (IS_INT_LNG_TYPE(d)) {
3086 if (IS_2_WORD_TYPE(d)) {
3087 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3088 M_LNGMOVE(REG_RESULT_PACKED, s1);
3091 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3092 M_INTMOVE(REG_RESULT, s1);
3096 s1 = codegen_reg_of_dst(jd, iptr, REG_NULL);
3098 emit_store_dst(jd, iptr, s1);
3104 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3105 /* val.a: (classinfo*) superclass */
3107 /* superclass is an interface:
3109 * OK if ((sub == NULL) ||
3110 * (sub->vftbl->interfacetablelength > super->index) &&
3111 * (sub->vftbl->interfacetable[-super->index] != NULL));
3113 * superclass is a class:
3115 * OK if ((sub == NULL) || (0
3116 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3117 * super->vftbl->diffval));
3120 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3121 /* object type cast-check */
3124 vftbl_t *supervftbl;
3127 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3133 super = iptr->sx.s23.s3.c.cls;
3134 superindex = super->index;
3135 supervftbl = super->vftbl;
3138 #if defined(ENABLE_THREADS)
3139 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3143 /* if class is not resolved, check which code to call */
3145 if (super == NULL) {
3147 emit_label_beq(cd, BRANCH_LABEL_1);
3149 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3150 iptr->sx.s23.s3.c.ref, 0);
3152 M_MOV_IMM(0, REG_ITMP2); /* super->flags */
3153 M_AND_IMM32(ACC_INTERFACE, REG_ITMP2);
3154 emit_label_beq(cd, BRANCH_LABEL_2);
3157 /* interface checkcast code */
3159 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3160 if (super != NULL) {
3162 emit_label_beq(cd, BRANCH_LABEL_3);
3165 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3167 if (super == NULL) {
3168 codegen_addpatchref(cd, PATCHER_checkcast_interface,
3169 iptr->sx.s23.s3.c.ref,
3174 REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3175 M_ISUB_IMM32(superindex, REG_ITMP3);
3176 /* XXX do we need this one? */
3178 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
3180 M_ALD32(REG_ITMP3, REG_ITMP2,
3181 OFFSET(vftbl_t, interfacetable[0]) -
3182 superindex * sizeof(methodptr*));
3184 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
3187 emit_label_br(cd, BRANCH_LABEL_4);
3189 emit_label(cd, BRANCH_LABEL_3);
3192 /* class checkcast code */
3194 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3195 if (super == NULL) {
3196 emit_label(cd, BRANCH_LABEL_2);
3200 emit_label_beq(cd, BRANCH_LABEL_5);
3203 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3205 if (super == NULL) {
3206 codegen_addpatchref(cd, PATCHER_checkcast_class,
3207 iptr->sx.s23.s3.c.ref,
3211 M_MOV_IMM(supervftbl, REG_ITMP3);
3212 #if defined(ENABLE_THREADS)
3213 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3215 M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3217 /* if (s1 != REG_ITMP1) { */
3218 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */
3219 /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */
3220 /* #if defined(ENABLE_THREADS) */
3221 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3223 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3226 M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3227 M_ISUB(REG_ITMP3, REG_ITMP2);
3228 M_MOV_IMM(supervftbl, REG_ITMP3);
3229 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3230 #if defined(ENABLE_THREADS)
3231 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3235 M_CMP(REG_ITMP3, REG_ITMP2);
3236 emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1);
3239 emit_label(cd, BRANCH_LABEL_5);
3242 if (super == NULL) {
3243 emit_label(cd, BRANCH_LABEL_1);
3244 emit_label(cd, BRANCH_LABEL_4);
3247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3250 /* array type cast-check */
3252 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3253 M_AST(s1, REG_SP, 0 * 4);
3255 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3256 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3257 iptr->sx.s23.s3.c.ref, 0);
3260 M_AST_IMM(iptr->sx.s23.s3.c.cls, REG_SP, 1 * 4);
3261 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP3);
3264 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3266 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
3268 d = codegen_reg_of_dst(jd, iptr, s1);
3272 emit_store_dst(jd, iptr, d);
3275 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3276 /* val.a: (classinfo*) superclass */
3278 /* superclass is an interface:
3280 * return (sub != NULL) &&
3281 * (sub->vftbl->interfacetablelength > super->index) &&
3282 * (sub->vftbl->interfacetable[-super->index] != NULL);
3284 * superclass is a class:
3286 * return ((sub != NULL) && (0
3287 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3288 * super->vftbl->diffvall));
3293 vftbl_t *supervftbl;
3296 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3302 super = iptr->sx.s23.s3.c.cls;
3303 superindex = super->index;
3304 supervftbl = super->vftbl;
3307 #if defined(ENABLE_THREADS)
3308 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3312 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3315 M_INTMOVE(s1, REG_ITMP1);
3321 /* if class is not resolved, check which code to call */
3323 if (super == NULL) {
3325 emit_label_beq(cd, BRANCH_LABEL_1);
3327 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3328 iptr->sx.s23.s3.c.ref, 0);
3330 M_MOV_IMM(0, REG_ITMP3); /* super->flags */
3331 M_AND_IMM32(ACC_INTERFACE, REG_ITMP3);
3332 emit_label_beq(cd, BRANCH_LABEL_2);
3335 /* interface instanceof code */
3337 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3338 if (super != NULL) {
3340 emit_label_beq(cd, BRANCH_LABEL_3);
3343 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3345 if (super == NULL) {
3346 codegen_addpatchref(cd, PATCHER_instanceof_interface,
3347 iptr->sx.s23.s3.c.ref, 0);
3351 REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3352 M_ISUB_IMM32(superindex, REG_ITMP3);
3355 disp = (2 + 4 /* mov_membase32_reg */ + 2 /* test */ +
3356 6 /* jcc */ + 5 /* mov_imm_reg */);
3359 M_ALD32(REG_ITMP1, REG_ITMP1,
3360 OFFSET(vftbl_t, interfacetable[0]) -
3361 superindex * sizeof(methodptr*));
3363 /* emit_setcc_reg(cd, CC_A, d); */
3364 /* emit_jcc(cd, CC_BE, 5); */
3369 emit_label_br(cd, BRANCH_LABEL_4);
3371 emit_label(cd, BRANCH_LABEL_3);
3374 /* class instanceof code */
3376 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3377 if (super == NULL) {
3378 emit_label(cd, BRANCH_LABEL_2);
3382 emit_label_beq(cd, BRANCH_LABEL_5);
3385 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3387 if (super == NULL) {
3388 codegen_addpatchref(cd, PATCHER_instanceof_class,
3389 iptr->sx.s23.s3.c.ref, 0);
3392 M_MOV_IMM(supervftbl, REG_ITMP2);
3393 #if defined(ENABLE_THREADS)
3394 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3396 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3397 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval));
3398 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3399 #if defined(ENABLE_THREADS)
3400 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3402 M_ISUB(REG_ITMP2, REG_ITMP1);
3403 M_CLR(d); /* may be REG_ITMP2 */
3404 M_CMP(REG_ITMP3, REG_ITMP1);
3409 emit_label(cd, BRANCH_LABEL_5);
3412 if (super == NULL) {
3413 emit_label(cd, BRANCH_LABEL_1);
3414 emit_label(cd, BRANCH_LABEL_4);
3417 emit_store_dst(jd, iptr, d);
3421 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3423 /* check for negative sizes and copy sizes to stack if necessary */
3425 MCODECHECK((iptr->s1.argcount << 1) + 64);
3427 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3428 /* copy SAVEDVAR sizes to stack */
3429 var = VAR(iptr->sx.s23.s2.args[s1]);
3431 /* Already Preallocated? */
3432 if (!(var->flags & PREALLOC)) {
3433 if (var->flags & INMEMORY) {
3434 M_ILD(REG_ITMP1, REG_SP, var->vv.regoff * 4);
3435 M_IST(REG_ITMP1, REG_SP, (s1 + 3) * 4);
3438 M_IST(var->vv.regoff, REG_SP, (s1 + 3) * 4);
3442 /* is a patcher function set? */
3444 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3445 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3446 iptr->sx.s23.s3.c.ref, 0);
3452 disp = (ptrint) iptr->sx.s23.s3.c.cls;
3454 /* a0 = dimension count */
3456 M_IST_IMM(iptr->s1.argcount, REG_SP, 0 * 4);
3458 /* a1 = arraydescriptor */
3460 M_IST_IMM(disp, REG_SP, 1 * 4);
3462 /* a2 = pointer to dimensions = stack pointer */
3464 M_MOV(REG_SP, REG_ITMP1);
3465 M_AADD_IMM(3 * 4, REG_ITMP1);
3466 M_AST(REG_ITMP1, REG_SP, 2 * 4);
3468 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3471 /* check for exception before result assignment */
3473 emit_exception_check(cd, iptr);
3475 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3476 M_INTMOVE(REG_RESULT, s1);
3477 emit_store_dst(jd, iptr, s1);
3481 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3486 } /* for instruction */
3490 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
3493 #if defined(ENABLE_SSA)
3495 /* by edge splitting, in Blocks with phi moves there can only */
3496 /* be a goto as last command, no other Jump/Branch Command */
3497 if (!last_cmd_was_goto)
3498 codegen_insert_phi_moves(jd, bptr);
3503 /* At the end of a basic block we may have to append some nops,
3504 because the patcher stub calling code might be longer than the
3505 actual instruction. So codepatching does not change the
3506 following block unintentionally. */
3508 if (cd->mcodeptr < cd->lastmcodeptr) {
3509 while (cd->mcodeptr < cd->lastmcodeptr) {
3514 } /* if (bptr -> flags >= BBREACHED) */
3515 } /* for basic block */
3517 dseg_createlinenumbertable(cd);
3519 /* generate stubs */
3521 emit_patcher_stubs(jd);
3522 REPLACEMENT_EMIT_STUBS(jd);
3524 /* everything's ok */
3529 #if defined(ENABLE_SSA)
3530 void codegen_insert_phi_moves(jitdata *jd, basicblock *bptr) {
3531 /* look for phi moves */
3532 int t_a,s_a,i, type;
3533 int t_lt, s_lt; /* lifetime indices of phi_moves */
3534 s4 t_regoff, s_regoff, s_flags, t_flags;
3543 /* Moves from phi functions with highest indices have to be */
3544 /* inserted first, since this is the order as is used for */
3545 /* conflict resolution */
3546 for(i = ls->num_phi_moves[bptr->nr] - 1; i >= 0 ; i--) {
3547 t_a = ls->phi_moves[bptr->nr][i][0];
3548 s_a = ls->phi_moves[bptr->nr][i][1];
3549 #if defined(SSA_DEBUG_VERBOSE)
3551 printf("BB %3i Move %3i <- %3i ", bptr->nr, t_a, s_a);
3554 /* local var lifetimes */
3555 t_lt = ls->maxlifetimes + t_a;
3556 type = ls->lifetime[t_lt].type;
3560 type = ls->lifetime[t_lt].local_ss->s->type;
3561 /* stackslot lifetime */
3565 #if defined(SSA_DEBUG_VERBOSE)
3567 printf("...returning - phi lifetimes where joined\n");
3573 /* local var lifetimes */
3574 s_lt = ls->maxlifetimes + s_a;
3575 type = ls->lifetime[s_lt].type;
3579 type = ls->lifetime[s_lt].type;
3580 /* stackslot lifetime */
3584 #if defined(SSA_DEBUG_VERBOSE)
3586 printf("...returning - phi lifetimes where joined\n");
3592 t_flags = VAR(t_a)->flags;
3593 t_regoff = VAR(t_a)->vv.regoff;
3597 t_flags = ls->lifetime[t_lt].local_ss->s->flags;
3598 t_regoff = ls->lifetime[t_lt].local_ss->s->regoff;
3602 /* local var move */
3603 s_flags = VAR(s_a)->flags;
3604 s_regoff = VAR(s_a)->vv.regoff;
3606 /* stackslot lifetime */
3607 s_flags = ls->lifetime[s_lt].local_ss->s->flags;
3608 s_regoff = ls->lifetime[s_lt].local_ss->s->regoff;
3612 #if defined(SSA_DEBUG_VERBOSE)
3614 printf("...returning - phi lifetimes where joined\n");
3619 cg_move(cd, type, s_regoff, s_flags, t_regoff, t_flags);
3621 #if defined(SSA_DEBUG_VERBOSE)
3622 if (compileverbose) {
3623 if (IS_INMEMORY(t_flags) && IS_INMEMORY(s_flags)) {
3625 printf("M%3i <- M%3i",t_regoff,s_regoff);
3627 else if (IS_INMEMORY(s_flags)) {
3629 printf("R%3i <- M%3i",t_regoff,s_regoff);
3631 else if (IS_INMEMORY(t_flags)) {
3633 printf("M%3i <- R%3i",t_regoff,s_regoff);
3637 printf("R%3i <- R%3i",t_regoff,s_regoff);
3641 #endif /* defined(SSA_DEBUG_VERBOSE) */
3645 void cg_move(codegendata *cd, s4 type, s4 src_regoff, s4 src_flags,
3646 s4 dst_regoff, s4 dst_flags) {
3647 if ((IS_INMEMORY(dst_flags)) && (IS_INMEMORY(src_flags))) {
3649 if (dst_regoff != src_regoff) {
3650 if (!IS_2_WORD_TYPE(type)) {
3651 if (IS_FLT_DBL_TYPE(type)) {
3652 emit_flds_membase(cd, REG_SP, src_regoff * 4);
3653 emit_fstps_membase(cd, REG_SP, dst_regoff * 4);
3655 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
3657 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
3659 } else { /* LONG OR DOUBLE */
3660 if (IS_FLT_DBL_TYPE(type)) {
3661 emit_fldl_membase( cd, REG_SP, src_regoff * 4);
3662 emit_fstpl_membase(cd, REG_SP, dst_regoff * 4);
3664 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4,
3666 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP, dst_regoff * 4);
3667 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4 + 4,
3669 emit_mov_reg_membase(cd, REG_ITMP1, REG_SP,
3670 dst_regoff * 4 + 4);
3675 if (IS_FLT_DBL_TYPE(type)) {
3676 log_text("cg_move: flt/dbl type have to be in memory\n");
3679 if (IS_2_WORD_TYPE(type)) {
3680 log_text("cg_move: longs have to be in memory\n");
3683 if (IS_INMEMORY(src_flags)) {
3685 emit_mov_membase_reg(cd, REG_SP, src_regoff * 4, dst_regoff);
3686 } else if (IS_INMEMORY(dst_flags)) {
3688 emit_mov_reg_membase(cd, src_regoff, REG_SP, dst_regoff * 4);
3691 /* only ints can be in regs on i386 */
3692 M_INTMOVE(src_regoff,dst_regoff);
3696 #endif /* defined(ENABLE_SSA) */
3699 /* codegen_emit_stub_compiler **************************************************
3701 Emit a stub routine which calls the compiler.
3703 *******************************************************************************/
3705 void codegen_emit_stub_compiler(jitdata *jd)
3710 /* get required compiler data */
3715 /* code for the stub */
3717 M_MOV_IMM(m, REG_ITMP1);
3718 M_MOV_IMM(asm_call_jit_compiler, REG_ITMP3);
3723 /* codegen_emit_stub_builtin ***************************************************
3725 Creates a stub routine which calls a builtin function.
3727 *******************************************************************************/
3729 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
3738 /* get required compiler data */
3743 /* set some variables */
3747 /* calculate stack frame size */
3749 cd->stackframesize =
3750 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3751 4; /* 4 arguments or return value */
3753 cd->stackframesize |= 0x3; /* keep stack 16-byte aligned */
3755 /* create method header */
3757 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3758 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3759 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3760 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3761 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3762 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3763 (void) dseg_addlinenumbertablesize(cd);
3764 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3766 /* generate stub code */
3768 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
3770 #if defined(ENABLE_GC_CACAO)
3771 /* Save callee saved integer registers in stackframeinfo (GC may
3772 need to recover them during a collection). */
3774 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3775 OFFSET(stackframeinfo, intregs);
3777 for (i = 0; i < INT_SAV_CNT; i++)
3778 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3781 /* create dynamic stack info */
3783 M_MOV(REG_SP, REG_ITMP1);
3784 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3785 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3787 M_IST_IMM(0, REG_SP, 1 * 4);
3790 M_MOV(REG_SP, REG_ITMP2);
3791 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
3792 M_AST(REG_ITMP2, REG_SP, 2 * 4);
3794 M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
3795 M_AST(REG_ITMP3, REG_SP, 3 * 4);
3797 M_MOV_IMM(codegen_stub_builtin_enter, REG_ITMP1);
3800 /* builtins are allowed to have 4 arguments max */
3802 assert(md->paramcount <= 4);
3804 /* copy arguments into new stackframe */
3806 for (i = 0; i < md->paramcount; i++) {
3807 if (!md->params[i].inmemory) {
3808 log_text("No integer argument registers available!");
3811 } else { /* float/double in memory can be copied like int/longs */
3812 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
3813 s2 = md->params[i].regoff * 4;
3815 M_ILD(REG_ITMP1, REG_SP, s1);
3816 M_IST(REG_ITMP1, REG_SP, s2);
3817 if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
3818 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
3819 M_IST(REG_ITMP1, REG_SP, s2 + 4);
3825 /* call the builtin function */
3827 M_MOV_IMM(bte->fp, REG_ITMP3);
3830 /* save return value */
3832 if (md->returntype.type != TYPE_VOID) {
3833 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3834 if (IS_2_WORD_TYPE(md->returntype.type))
3835 M_IST(REG_RESULT2, REG_SP, 2 * 4);
3836 M_IST(REG_RESULT, REG_SP, 1 * 4);
3839 if (IS_2_WORD_TYPE(md->returntype.type))
3840 emit_fstl_membase(cd, REG_SP, 1 * 4);
3842 emit_fsts_membase(cd, REG_SP, 1 * 4);
3846 /* remove native stackframe info */
3848 M_MOV(REG_SP, REG_ITMP1);
3849 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3850 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3852 M_MOV_IMM(codegen_stub_builtin_exit, REG_ITMP1);
3855 /* restore return value */
3857 if (md->returntype.type != TYPE_VOID) {
3858 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3859 if (IS_2_WORD_TYPE(md->returntype.type))
3860 M_ILD(REG_RESULT2, REG_SP, 2 * 4);
3861 M_ILD(REG_RESULT, REG_SP, 1 * 4);
3864 if (IS_2_WORD_TYPE(md->returntype.type))
3865 emit_fldl_membase(cd, REG_SP, 1 * 4);
3867 emit_flds_membase(cd, REG_SP, 1 * 4);
3871 #if defined(ENABLE_GC_CACAO)
3872 /* Restore callee saved integer registers from stackframeinfo (GC
3873 might have modified them during a collection). */
3875 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3876 OFFSET(stackframeinfo, intregs);
3878 for (i = 0; i < INT_SAV_CNT; i++)
3879 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3882 /* remove stackframe */
3884 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
3889 /* codegen_emit_stub_native ****************************************************
3891 Emits a stub routine which calls a native method.
3893 *******************************************************************************/
3895 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3902 s4 i, j; /* count variables */
3907 /* get required compiler data */
3913 /* set some variables */
3916 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3918 /* calculate stackframe size */
3920 cd->stackframesize =
3921 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3922 sizeof(localref_table) / SIZEOF_VOID_P +
3923 1 + /* function pointer */
3924 4 + /* 4 arguments (start_native_call) */
3927 /* keep stack 16-byte aligned */
3929 cd->stackframesize |= 0x3;
3931 /* create method header */
3933 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3934 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3935 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3936 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3937 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3938 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3939 (void) dseg_addlinenumbertablesize(cd);
3940 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3942 #if defined(ENABLE_PROFILING)
3943 /* generate native method profiling code */
3945 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3946 /* count frequency */
3948 M_MOV_IMM(code, REG_ITMP1);
3949 M_IADD_IMM_MEMBASE(1, REG_ITMP1, OFFSET(codeinfo, frequency));
3953 /* calculate stackframe size for native function */
3955 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
3957 #if !defined(NDEBUG)
3958 emit_verbosecall_enter(jd);
3961 /* get function address (this must happen before the stackframeinfo) */
3963 #if !defined(WITH_STATIC_CLASSPATH)
3965 codegen_addpatchref(cd, PATCHER_resolve_native, m, 0);
3968 M_AST_IMM((ptrint) f, REG_SP, 4 * 4);
3970 /* Mark the whole fpu stack as free for native functions (only for saved */
3971 /* register count == 0). */
3973 emit_ffree_reg(cd, 0);
3974 emit_ffree_reg(cd, 1);
3975 emit_ffree_reg(cd, 2);
3976 emit_ffree_reg(cd, 3);
3977 emit_ffree_reg(cd, 4);
3978 emit_ffree_reg(cd, 5);
3979 emit_ffree_reg(cd, 6);
3980 emit_ffree_reg(cd, 7);
3982 #if defined(ENABLE_GC_CACAO)
3983 /* remember callee saved int registers in stackframeinfo (GC may need to */
3984 /* recover them during a collection). */
3986 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3987 OFFSET(stackframeinfo, intregs);
3989 for (i = 0; i < INT_SAV_CNT; i++)
3990 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3993 /* prepare data structures for native function call */
3995 M_MOV(REG_SP, REG_ITMP1);
3996 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
3998 M_AST(REG_ITMP1, REG_SP, 0 * 4);
3999 M_IST_IMM(0, REG_SP, 1 * 4);
4002 M_MOV(REG_SP, REG_ITMP2);
4003 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ITMP2);
4005 M_AST(REG_ITMP2, REG_SP, 2 * 4);
4006 M_ALD(REG_ITMP3, REG_SP, cd->stackframesize * 4);
4007 M_AST(REG_ITMP3, REG_SP, 3 * 4);
4008 M_MOV_IMM(codegen_start_native_call, REG_ITMP1);
4011 M_ALD(REG_ITMP3, REG_SP, 4 * 4);
4013 /* copy arguments into new stackframe */
4015 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4016 t = md->paramtypes[i].type;
4018 if (!md->params[i].inmemory) {
4019 /* no integer argument registers */
4020 } else { /* float/double in memory can be copied like int/longs */
4021 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
4022 s2 = nmd->params[j].regoff * 4;
4024 M_ILD(REG_ITMP1, REG_SP, s1);
4025 M_IST(REG_ITMP1, REG_SP, s2);
4026 if (IS_2_WORD_TYPE(t)) {
4027 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
4028 M_IST(REG_ITMP1, REG_SP, s2 + 4);
4033 /* if function is static, put class into second argument */
4035 if (m->flags & ACC_STATIC)
4036 M_AST_IMM(m->class, REG_SP, 1 * 4);
4038 /* put env into first argument */
4040 M_AST_IMM(_Jv_env, REG_SP, 0 * 4);
4042 /* call the native function */
4046 /* save return value */
4048 switch (md->returntype.type) {
4051 M_IST(REG_RESULT, REG_SP, 1 * 4);
4054 M_LST(REG_RESULT_PACKED, REG_SP, 1 * 4);
4057 emit_fsts_membase(cd, REG_SP, 1 * 4);
4060 emit_fstl_membase(cd, REG_SP, 1 * 4);
4066 #if !defined(NDEBUG)
4067 emit_verbosecall_exit(jd);
4070 /* remove native stackframe info */
4072 M_MOV(REG_SP, REG_ITMP1);
4073 M_AADD_IMM(cd->stackframesize * 4, REG_ITMP1);
4075 M_AST(REG_ITMP1, REG_SP, 0 * 4);
4076 M_MOV_IMM(codegen_finish_native_call, REG_ITMP1);
4078 M_MOV(REG_RESULT, REG_ITMP2); /* REG_ITMP3 == REG_RESULT2 */
4080 /* restore return value */
4082 switch (md->returntype.type) {
4085 M_ILD(REG_RESULT, REG_SP, 1 * 4);
4088 M_LLD(REG_RESULT_PACKED, REG_SP, 1 * 4);
4091 emit_flds_membase(cd, REG_SP, 1 * 4);
4094 emit_fldl_membase(cd, REG_SP, 1 * 4);
4100 #if defined(ENABLE_GC_CACAO)
4101 /* restore callee saved int registers from stackframeinfo (GC might have */
4102 /* modified them during a collection). */
4104 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
4105 OFFSET(stackframeinfo, intregs);
4107 for (i = 0; i < INT_SAV_CNT; i++)
4108 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
4111 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
4113 /* check for exception */
4120 /* handle exception */
4122 M_MOV(REG_ITMP2, REG_ITMP1_XPTR);
4123 M_ALD(REG_ITMP2_XPC, REG_SP, 0);
4124 M_ASUB_IMM(2, REG_ITMP2_XPC);
4126 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4129 /* generate patcher stubs */
4131 emit_patcher_stubs(jd);
4136 * These are local overrides for various environment variables in Emacs.
4137 * Please do not remove this and leave it at the end of the file, where
4138 * Emacs will automagically detect them.
4139 * ---------------------------------------------------------------------
4142 * indent-tabs-mode: t
4146 * vim:noexpandtab:sw=4:ts=4: