1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
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 4644 2006-03-16 18:44:46Z edwin $
39 /* #include "vm/jit/sparc64/arch.h" */
40 #include "vm/jit/sparc64/codegen.h"
42 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
50 #include "vm/jit/abi.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/codegen-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/sparc64/emit.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/patcher.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
65 #include "vm/jit/sparc64/solaris/macro_rename.h"
67 #define BUILTIN_FLOAT_ARGS 1
69 /* XXX use something like this for window control ?
70 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
72 #define REG_PV REG_PV_CALLEE
77 if ((disp < -4096) || (disp > 4095))
78 printf("disp %d\n", disp);
81 return (disp >= -4096) && (disp <= 4095);
84 s4 get_lopart_disp(disp)
89 lodisp = setlo_part(disp);
91 if (setlo_part(disp) == 0)
94 lodisp = setlo_part(disp) | 0x1c00;
101 /* codegen_emit ****************************************************************
103 Generates machine code.
105 *******************************************************************************/
107 bool codegen_emit(jitdata *jd)
113 s4 len, s1, s2, s3, d, disp, slots;
119 constant_classref *cr;
120 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
121 unresolved_method *um;
122 builtintable_entry *bte;
125 unresolved_field *uf;
129 /* get required compiler data */
136 /* prevent compiler warnings */
147 #if 0 /* no leaf optimization yet */
148 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
150 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
153 /* space to save used callee saved registers */
155 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
156 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
158 cd->stackframesize = rd->memuse + savedregs_num;
160 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
161 if (checksync && (m->flags & ACC_SYNCHRONIZED))
162 cd->stackframesize++;
165 /* keep stack 16-byte aligned (ABI requirement) */
167 if (cd->stackframesize & 1)
168 cd->stackframesize++;
170 /* create method header */
172 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
173 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
175 #if defined(ENABLE_THREADS)
176 /* IsSync contains the offset relative to the stack pointer for the
177 argument of monitor_exit used in the exception handler. Since the
178 offset could be zero and give a wrong meaning of the flag it is
182 if (checksync && (m->flags & ACC_SYNCHRONIZED))
183 (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
186 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
188 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
189 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
190 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
191 dseg_addlinenumbertablesize(cd);
192 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
194 /* create exception table */
196 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
197 dseg_add_target(cd, ex->start);
198 dseg_add_target(cd, ex->end);
199 dseg_add_target(cd, ex->handler);
200 (void) dseg_add_unique_address(cd, ex->catchtype.any);
203 /* save register window and create stack frame (if necessary) */
205 if (cd->stackframesize)
206 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
209 /* save callee saved float registers (none right now) */
211 p = cd->stackframesize;
212 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
213 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
218 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
219 emit_verbosecall_enter(jd);
223 /* call monitorenter function */
224 #if defined(ENABLE_THREADS)
225 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
226 /* stack offset for monitor argument */
230 /* save float argument registers */
234 ALIGN_STACK_SLOTS(slots);
236 M_LDA(REG_SP, REG_SP, -(slots * 8));
237 for (i = 0; i < FLT_ARG_CNT; i++)
238 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
242 /* get correct lock object */
244 if (m->flags & ACC_STATIC) {
245 disp = dseg_add_address(cd, &m->class->object.header);
246 M_ALD(REG_OUT0, REG_PV, disp);
247 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
248 M_ALD(REG_ITMP3, REG_PV, disp);
251 /* copy class pointer: $i0 -> $o0 */
252 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
254 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
255 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
256 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
259 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
260 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
262 /* restore float argument registers */
264 for (i = 0; i < FLT_ARG_CNT; i++)
265 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
267 M_LDA(REG_SP, REG_SP, slots * 8);
272 /* take arguments out of register or stack frame */
276 for (p = 0, l = 0; p < md->paramcount; p++) {
277 t = md->paramtypes[p].type;
279 varindex = jd->local_map[l * 5 + t];
282 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
285 if (varindex == UNUSED)
289 s1 = md->params[p].regoff;
291 if (IS_INT_LNG_TYPE(t)) { /* integer args */
295 if (!md->params[p].inmemory) { /* register arguments */
296 s1 = REG_WINDOW_TRANSPOSE(s1);
298 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
300 /* the register allocator does not know about the window. */
301 /* avoid copying the locals from save to save regs by */
302 /* swapping variables. */
305 int old_dest = var->vv.regoff;
306 int new_dest = p + 24;
308 /* run through all variables */
310 for (i = 0; i < jd->varcount; i++) {
311 varinfo* uvar = VAR(i);
313 if (IS_FLT_DBL_TYPE(uvar->type))
316 s2 = uvar->vv.regoff;
318 /* free the in reg by moving all other references */
320 if (s2 == new_dest) {
321 uvar->vv.regoff = old_dest;
322 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
325 /* move all variables to the in reg */
327 if (s2 == old_dest) {
328 uvar->vv.regoff = new_dest;
329 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
337 else { /* reg arg -> spilled */
338 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
341 } else { /* stack arguments */
342 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
343 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
345 } else { /* stack arg -> spilled */
346 /* add the callers window save registers */
347 var->vv.regoff = cd->stackframesize * 8 + s1;
351 } else { /* floating args */
352 if (!md->params[p].inmemory) { /* register arguments */
353 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
354 M_FLTMOVE(s1, var->vv.regoff);
356 } else { /* reg arg -> spilled */
357 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
360 } else { /* stack arguments */
361 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
362 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
364 } else { /* stack-arg -> spilled */
365 var->vv.regoff = cd->stackframesize * 8 + s1;
374 /* end of header generation */
376 /* create replacement points */
378 REPLACEMENT_POINTS_INIT(cd, jd);
380 /* walk through all basic blocks */
382 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
384 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
386 if (bptr->flags >= BBREACHED) {
388 /* branch resolving */
390 codegen_resolve_branchrefs(cd, bptr);
392 /* handle replacement points */
395 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
396 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
402 /* copy interface registers to their destination */
407 #if defined(ENABLE_LSRA)
408 #error XXX LSRA not tested yet
412 src = bptr->invars[len];
413 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
414 /* d = reg_of_var(m, src, REG_ITMP1); */
415 if (!(src->flags & INMEMORY))
419 M_INTMOVE(REG_ITMP1, d);
420 emit_store(jd, NULL, src, d);
427 var = VAR(bptr->invars[len]);
428 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
429 d = codegen_reg_of_var(0, var, REG_ITMP1);
430 M_INTMOVE(REG_ITMP2_XPTR, d);
431 emit_store(jd, NULL, var, d);
434 assert((var->flags & INOUT));
437 #if defined(ENABLE_LSRA)
440 /* walk through all instructions */
444 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
445 if (iptr->line != currentline) {
446 dseg_addlinenumber(cd, iptr->line);
447 currentline = iptr->line;
450 MCODECHECK(64); /* an instruction usually needs < 64 words */
454 case ICMD_INLINE_START:
455 case ICMD_INLINE_END:
458 case ICMD_NOP: /* ... ==> ... */
461 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
464 emit_nullpointer_check(cd, iptr, s1);
467 /* constant operations ************************************************/
469 case ICMD_ICONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
472 ICONST(d, iptr->sx.val.i);
473 emit_store_dst(jd, iptr, d);
476 case ICMD_LCONST: /* ... ==> ..., constant */
478 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
479 LCONST(d, iptr->sx.val.l);
480 emit_store_dst(jd, iptr, d);
483 case ICMD_FCONST: /* ... ==> ..., constant */
485 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
486 disp = dseg_add_float(cd, iptr->sx.val.f);
487 M_FLD(d, REG_PV, disp);
488 emit_store_dst(jd, iptr, d);
491 case ICMD_DCONST: /* ... ==> ..., constant */
493 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
494 disp = dseg_add_double(cd, iptr->sx.val.d);
495 M_DLD(d, REG_PV, disp);
496 emit_store_dst(jd, iptr, d);
499 case ICMD_ACONST: /* ... ==> ..., constant */
501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
503 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
504 cr = iptr->sx.val.c.ref;
505 disp = dseg_add_unique_address(cd, cr);
507 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
509 M_ALD(d, REG_PV, disp);
513 if (iptr->sx.val.anyptr == NULL) {
514 M_INTMOVE(REG_ZERO, d);
517 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
518 M_ALD(d, REG_PV, disp);
521 emit_store_dst(jd, iptr, d);
525 /* load/store/copy/move operations ************************************/
527 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
532 case ICMD_ISTORE: /* ..., value ==> ... */
543 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
548 /* pop/dup/swap operations ********************************************/
550 /* attention: double and longs are only one entry in CACAO ICMDs */
552 case ICMD_POP: /* ..., value ==> ... */
553 case ICMD_POP2: /* ..., value, value ==> ... */
557 /* integer operations *************************************************/
559 case ICMD_INEG: /* ..., value ==> ..., - value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 M_SUB(REG_ZERO, s1, d);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_I2L: /* ..., value ==> ..., value */
570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 emit_store_dst(jd, iptr, d);
576 case ICMD_L2I: /* ..., value ==> ..., value */
578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
581 emit_store_dst(jd, iptr, d);
584 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
588 M_SLLX_IMM(s1, 56, d);
589 M_SRAX_IMM( d, 56, d);
590 emit_store_dst(jd, iptr, d);
593 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
597 M_SLLX_IMM(s1, 48, d);
598 M_SRLX_IMM( d, 48, d);
599 emit_store_dst(jd, iptr, d);
602 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
606 M_SLLX_IMM(s1, 48, d);
607 M_SRAX_IMM( d, 48, d);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618 emit_store_dst(jd, iptr, d);
622 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
623 /* sx.val.i = constant */
625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
628 M_ADD_IMM(s1, iptr->sx.val.i, d);
630 ICONST(REG_ITMP2, iptr->sx.val.i);
631 M_ADD(s1, REG_ITMP2, d);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
637 /* sx.val.l = constant */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
642 M_ADD_IMM(s1, iptr->sx.val.l, d);
644 LCONST(REG_ITMP2, iptr->sx.val.l);
645 M_ADD(s1, REG_ITMP2, d);
647 emit_store_dst(jd, iptr, d);
650 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 emit_store_dst(jd, iptr, d);
660 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
661 /* sx.val.i = constant */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
665 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
666 M_SUB_IMM(s1, iptr->sx.val.i, d);
668 ICONST(REG_ITMP2, iptr->sx.val.i);
669 M_SUB(s1, REG_ITMP2, d);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
675 /* sx.val.l = constant */
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
680 M_SUB_IMM(s1, iptr->sx.val.l, d);
682 LCONST(REG_ITMP2, iptr->sx.val.l);
683 M_SUB(s1, REG_ITMP2, d);
685 emit_store_dst(jd, iptr, d);
688 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
692 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
693 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695 emit_store_dst(jd, iptr, d);
698 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
699 /* sx.val.i = constant */
701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
703 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
704 M_MULX_IMM(s1, iptr->sx.val.i, d);
706 ICONST(REG_ITMP2, iptr->sx.val.i);
707 M_MULX(s1, REG_ITMP2, d);
709 emit_store_dst(jd, iptr, d);
712 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
713 /* sx.val.l = constant */
715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
716 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
717 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
718 M_MULX_IMM(s1, iptr->sx.val.l, d);
720 LCONST(REG_ITMP2, iptr->sx.val.l);
721 M_MULX(s1, REG_ITMP2, d);
723 emit_store_dst(jd, iptr, d);
726 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
727 /* XXX could also clear Y and use 32bit div */
728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
731 emit_arithmetic_check(cd, iptr, s2);
733 /* XXX trim s2 like s1 ? */
735 emit_store_dst(jd, iptr, d);
738 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
741 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
743 emit_arithmetic_check(cd, iptr, s2);
745 emit_store_dst(jd, iptr, d);
748 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
753 emit_arithmetic_check(cd, iptr, s2);
755 /* XXX trim s2 like s1 ? */
756 M_DIVX(s1, s2, REG_ITMP3);
757 M_MULX(s2, REG_ITMP3, REG_ITMP3);
758 M_SUB(s1, REG_ITMP3, d);
759 emit_store_dst(jd, iptr, d);
762 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
767 emit_arithmetic_check(cd, iptr, s2);
768 M_DIVX(s1, s2, REG_ITMP3);
769 M_MULX(s2, REG_ITMP3, REG_ITMP3);
770 M_SUB(s1, REG_ITMP3, d);
771 emit_store_dst(jd, iptr, d);
774 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
775 case ICMD_LDIVPOW2: /* val.i = constant */
777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
778 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
779 M_SRAX_IMM(s1, 63, REG_ITMP2);
780 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
781 M_ADD(s1, REG_ITMP2, REG_ITMP2);
782 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
789 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792 emit_store_dst(jd, iptr, d);
795 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
801 emit_store_dst(jd, iptr, d);
804 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
805 /* val.i = constant */
807 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809 M_SLL_IMM(s1, iptr->sx.val.i, d);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
814 /* val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
818 M_SLLX_IMM(s1, iptr->sx.val.i, d);
819 emit_store_dst(jd, iptr, d);
822 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
832 /* sx.val.i = constant */
834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
836 M_SRA_IMM(s1, iptr->sx.val.i, d);
837 emit_store_dst(jd, iptr, d);
840 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
843 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
844 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
846 emit_store_dst(jd, iptr, d);
849 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
850 /* sx.val.i = constant */
852 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
853 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
854 M_SRL_IMM(s1, iptr->sx.val.i, d);
855 emit_store_dst(jd, iptr, d);
858 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
861 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
862 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
864 emit_store_dst(jd, iptr, d);
867 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
868 /* sx.val.i = constant */
870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
872 M_SRAX_IMM(s1, iptr->sx.val.i, d);
873 emit_store_dst(jd, iptr, d);
876 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
878 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
879 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
880 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
882 emit_store_dst(jd, iptr, d);
885 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
886 /* sx.val.i = constant */
888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
889 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
890 M_SRLX_IMM(s1, iptr->sx.val.i, d);
891 emit_store_dst(jd, iptr, d);
894 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
897 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
898 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
901 emit_store_dst(jd, iptr, d);
904 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
905 /* sx.val.i = constant */
907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
908 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
909 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
910 M_AND_IMM(s1, iptr->sx.val.i, d);
912 ICONST(REG_ITMP2, iptr->sx.val.i);
913 M_AND(s1, REG_ITMP2, d);
915 emit_store_dst(jd, iptr, d);
918 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
919 /* sx.val.i = constant */
920 /* constant is actually constant - 1 */
922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
925 M_MOV(s1, REG_ITMP1);
928 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
929 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
930 M_AND_IMM(s1, iptr->sx.val.i, d);
933 M_SUB(REG_ZERO, s1, d);
934 M_AND_IMM(d, iptr->sx.val.i, d);
936 ICONST(REG_ITMP2, iptr->sx.val.i);
937 M_AND(s1, REG_ITMP2, d);
940 M_SUB(REG_ZERO, s1, d);
941 M_AND(d, REG_ITMP2, d);
943 M_SUB(REG_ZERO, d, d);
944 emit_store_dst(jd, iptr, d);
947 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
948 /* sx.val.l = constant */
950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
952 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
953 M_AND_IMM(s1, iptr->sx.val.l, d);
955 LCONST(REG_ITMP2, iptr->sx.val.l);
956 M_AND(s1, REG_ITMP2, d);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
962 /* sx.val.l = constant */
964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
965 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
967 M_MOV(s1, REG_ITMP1);
970 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
971 M_AND_IMM(s1, iptr->sx.val.l, d);
974 M_SUB(REG_ZERO, s1, d);
975 M_AND_IMM(d, iptr->sx.val.l, d);
977 LCONST(REG_ITMP2, iptr->sx.val.l);
978 M_AND(s1, REG_ITMP2, d);
981 M_SUB(REG_ZERO, s1, d);
982 M_AND(d, REG_ITMP2, d);
984 M_SUB(REG_ZERO, d, d);
985 emit_store_dst(jd, iptr, d);
988 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
992 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
993 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
995 emit_store_dst(jd, iptr, d);
998 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
999 /* sx.val.i = constant */
1001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1004 M_OR_IMM(s1, iptr->sx.val.i, d);
1006 ICONST(REG_ITMP2, iptr->sx.val.i);
1007 M_OR(s1, REG_ITMP2, d);
1009 emit_store_dst(jd, iptr, d);
1012 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1013 /* sx.val.l = constant */
1015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1017 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1018 M_OR_IMM(s1, iptr->sx.val.l, d);
1020 LCONST(REG_ITMP2, iptr->sx.val.l);
1021 M_OR(s1, REG_ITMP2, d);
1023 emit_store_dst(jd, iptr, d);
1026 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1030 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1031 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1037 /* sx.val.i = constant */
1039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1041 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1042 M_XOR_IMM(s1, iptr->sx.val.i, d);
1044 ICONST(REG_ITMP2, iptr->sx.val.i);
1045 M_XOR(s1, REG_ITMP2, d);
1047 emit_store_dst(jd, iptr, d);
1050 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1051 /* sx.val.l = constant */
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1055 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1056 M_XOR_IMM(s1, iptr->sx.val.l, d);
1058 LCONST(REG_ITMP2, iptr->sx.val.l);
1059 M_XOR(s1, REG_ITMP2, d);
1061 emit_store_dst(jd, iptr, d);
1065 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1068 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1069 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 M_XCMOVLT_IMM(-1, d);
1073 M_XCMOVGT_IMM(1, d);
1074 emit_store_dst(jd, iptr, d);
1078 /* floating operations ************************************************/
1080 case ICMD_FNEG: /* ..., value ==> ..., - value */
1082 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1083 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_DNEG: /* ..., value ==> ..., - value */
1090 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1091 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1093 emit_store_dst(jd, iptr, d);
1096 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1098 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1099 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1100 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1107 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1108 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1109 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1111 emit_store_dst(jd, iptr, d);
1114 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1116 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1117 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1118 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1120 emit_store_dst(jd, iptr, d);
1123 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1125 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1126 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1127 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1129 emit_store_dst(jd, iptr, d);
1132 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1134 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1135 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1136 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1138 emit_store_dst(jd, iptr, d);
1141 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1143 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1144 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1145 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1147 emit_store_dst(jd, iptr, d);
1150 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1152 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1153 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1154 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1161 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1162 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1163 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1165 emit_store_dst(jd, iptr, d);
1169 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1170 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1171 disp = dseg_add_unique_float(cd, 0.0);
1172 M_IST (s1, REG_PV_CALLEE, disp);
1173 M_FLD (d, REG_PV_CALLEE, disp);
1174 M_CVTIF (d, d); /* rd gets translated to double target register */
1175 emit_store_dst(jd, iptr, d);
1179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1180 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1181 disp = dseg_add_unique_float(cd, 0.0);
1182 M_IST(s1, REG_PV_CALLEE, disp);
1183 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1184 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1185 emit_store_dst(jd, iptr, d);
1189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1190 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1191 disp = dseg_add_unique_double(cd, 0.0);
1192 M_STX(s1, REG_PV_CALLEE, disp);
1193 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1194 M_CVTLF(REG_FTMP3, d);
1195 emit_store_dst(jd, iptr, d);
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1201 disp = dseg_add_unique_double(cd, 0.0);
1202 M_STX(s1, REG_PV_CALLEE, disp);
1203 M_DLD(d, REG_PV_CALLEE, disp);
1205 emit_store_dst(jd, iptr, d);
1208 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1209 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1210 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1211 disp = dseg_add_unique_float(cd, 0.0);
1213 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1216 M_MOV(REG_ZERO, d); /* delay slot */
1218 M_CVTFI(s1, REG_FTMP2);
1219 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1220 M_ILD(d, REG_PV, disp);
1221 emit_store_dst(jd, iptr, d);
1225 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1226 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1227 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1228 disp = dseg_add_unique_float(cd, 0.0);
1230 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1233 M_MOV(REG_ZERO, d); /* delay slot */
1235 M_CVTDI(s1, REG_FTMP2);
1236 M_FST(REG_FTMP2, REG_PV, disp);
1237 M_ILD(d, REG_PV, disp);
1238 emit_store_dst(jd, iptr, d);
1241 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1242 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1243 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1244 disp = dseg_add_unique_double(cd, 0.0);
1246 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1249 M_MOV(REG_ZERO, d); /* delay slot */
1251 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1252 M_DST(REG_FTMP2, REG_PV, disp);
1253 M_LDX(d, REG_PV, disp);
1254 emit_store_dst(jd, iptr, d);
1257 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1258 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1260 disp = dseg_add_unique_double(cd, 0.0);
1262 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1265 M_MOV(REG_ZERO, d); /* delay slot */
1267 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1268 M_DST(REG_FTMP2, REG_PV, disp);
1269 M_LDX(d, REG_PV, disp);
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1275 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1276 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1278 emit_store_dst(jd, iptr, d);
1281 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1283 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1284 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1286 emit_store_dst(jd, iptr, d);
1289 /* XXX merge F/D versions? only compare instr. is different */
1290 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1292 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1296 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1297 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1298 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1299 emit_store_dst(jd, iptr, d);
1302 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1304 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1305 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1306 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1308 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1309 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1310 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1311 emit_store_dst(jd, iptr, d);
1314 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1316 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1317 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1318 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1320 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1321 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1322 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1328 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1329 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1330 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1332 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1333 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1334 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1335 emit_store_dst(jd, iptr, d);
1339 /* memory operations **************************************************/
1341 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1345 emit_nullpointer_check(cd, iptr, s1);
1346 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1353 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1355 /* implicit null-pointer check */
1356 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1357 M_AADD(s2, s1, REG_ITMP3);
1358 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1367 /* implicit null-pointer check */
1368 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369 M_AADD(s2, s1, REG_ITMP3);
1370 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1371 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1372 emit_store_dst(jd, iptr, d);
1375 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1377 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1378 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1379 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1380 /* implicit null-pointer check */
1381 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1382 M_AADD(s2, s1, REG_ITMP3);
1383 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1384 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1385 emit_store_dst(jd, iptr, d);
1388 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1391 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1392 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1393 /* implicit null-pointer check */
1394 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1395 M_ASLL_IMM(s2, 2, REG_ITMP3);
1396 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1397 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1398 emit_store_dst(jd, iptr, d);
1401 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1403 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1404 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1406 /* implicit null-pointer check */
1407 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1408 M_ASLL_IMM(s2, 3, REG_ITMP3);
1409 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1410 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1411 emit_store_dst(jd, iptr, d);
1414 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1417 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1418 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1419 /* implicit null-pointer check */
1420 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1421 M_ASLL_IMM(s2, 2, REG_ITMP3);
1422 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1423 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1424 emit_store_dst(jd, iptr, d);
1427 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1430 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1432 /* implicit null-pointer check */
1433 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1434 M_ASLL_IMM(s2, 3, REG_ITMP3);
1435 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1436 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1437 emit_store_dst(jd, iptr, d);
1440 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1442 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1443 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1445 /* implicit null-pointer check */
1446 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1447 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1448 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1449 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1450 emit_store_dst(jd, iptr, d);
1454 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1456 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1458 /* implicit null-pointer check */
1459 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1460 M_AADD(s2, s1, REG_ITMP1);
1461 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1462 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1465 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1466 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1468 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1469 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1470 /* implicit null-pointer check */
1471 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1472 M_AADD(s2, s1, REG_ITMP1);
1473 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1474 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1475 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1478 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1480 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1481 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1482 /* implicit null-pointer check */
1483 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1484 M_ASLL_IMM(s2, 2, REG_ITMP2);
1485 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1486 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1487 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1490 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1492 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1493 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1494 /* implicit null-pointer check */
1495 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1496 M_ASLL_IMM(s2, 3, REG_ITMP2);
1497 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1498 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1499 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1502 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1505 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1506 /* implicit null-pointer check */
1507 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1508 M_ASLL_IMM(s2, 2, REG_ITMP2);
1509 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1510 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1511 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1514 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1517 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1518 /* implicit null-pointer check */
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 M_ASLL_IMM(s2, 3, REG_ITMP2);
1521 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1522 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1523 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1527 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531 /* implicit null-pointer check */
1532 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1533 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1535 M_MOV(s1, REG_OUT0);
1536 M_MOV(s3, REG_OUT1);
1537 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1538 M_ALD(REG_ITMP3, REG_PV, disp);
1539 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1541 emit_exception_check(cd, iptr);
1543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1545 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1546 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1547 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1548 /* implicit null-pointer check */
1549 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1553 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1556 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1557 /* implicit null-pointer check */
1558 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1559 M_AADD(s2, s1, REG_ITMP1);
1560 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1563 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1564 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1568 /* implicit null-pointer check */
1569 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1570 M_AADD(s2, s1, REG_ITMP1);
1571 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1572 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1575 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1578 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1579 /* implicit null-pointer check */
1580 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1581 M_ASLL_IMM(s2, 2, REG_ITMP2);
1582 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1583 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1586 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1589 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1590 /* implicit null-pointer check */
1591 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1592 M_ASLL_IMM(s2, 3, REG_ITMP2);
1593 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1594 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1597 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1601 /* implicit null-pointer check */
1602 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1603 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1604 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1605 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1609 case ICMD_GETSTATIC: /* ... ==> ..., value */
1611 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1612 uf = iptr->sx.s23.s3.uf;
1613 fieldtype = uf->fieldref->parseddesc.fd->type;
1614 disp = dseg_add_unique_address(cd, uf);
1616 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1619 fi = iptr->sx.s23.s3.fmiref->p.field;
1620 fieldtype = fi->type;
1621 disp = dseg_add_address(cd, &(fi->value));
1623 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1624 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1627 M_ALD(REG_ITMP1, REG_PV, disp);
1629 switch (fieldtype) {
1631 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1632 M_ILD_INTERN(d, REG_ITMP1, 0);
1635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1636 M_LDX_INTERN(d, REG_ITMP1, 0);
1639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1640 M_ALD_INTERN(d, REG_ITMP1, 0);
1643 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1644 M_FLD_INTERN(d, REG_ITMP1, 0);
1647 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1648 M_DLD_INTERN(d, REG_ITMP1, 0);
1651 emit_store_dst(jd, iptr, d);
1654 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1656 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1657 uf = iptr->sx.s23.s3.uf;
1658 fieldtype = uf->fieldref->parseddesc.fd->type;
1659 disp = dseg_add_unique_address(cd, uf);
1661 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1664 fi = iptr->sx.s23.s3.fmiref->p.field;
1665 fieldtype = fi->type;
1666 disp = dseg_add_address(cd, &(fi->value));
1668 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1669 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1672 M_ALD(REG_ITMP1, REG_PV, disp);
1674 switch (fieldtype) {
1676 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1677 M_IST_INTERN(s1, REG_ITMP1, 0);
1680 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1681 M_STX_INTERN(s1, REG_ITMP1, 0);
1684 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1685 M_AST_INTERN(s1, REG_ITMP1, 0);
1688 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1689 M_FST_INTERN(s1, REG_ITMP1, 0);
1692 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1693 M_DST_INTERN(s1, REG_ITMP1, 0);
1698 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1699 /* val = value (in current instruction) */
1700 /* following NOP) */
1702 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1703 uf = iptr->sx.s23.s3.uf;
1704 fieldtype = uf->fieldref->parseddesc.fd->type;
1705 disp = dseg_add_unique_address(cd, uf);
1707 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1710 fi = iptr->sx.s23.s3.fmiref->p.field;
1711 fieldtype = fi->type;
1712 disp = dseg_add_address(cd, &(fi->value));
1714 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1715 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1718 M_ALD(REG_ITMP1, REG_PV, disp);
1720 switch (fieldtype) {
1722 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1725 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1728 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1731 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1734 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1740 case ICMD_GETFIELD: /* ... ==> ..., value */
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 emit_nullpointer_check(cd, iptr, s1);
1745 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1746 uf = iptr->sx.s23.s3.uf;
1748 fieldtype = uf->fieldref->parseddesc.fd->type;
1751 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1754 fi = iptr->sx.s23.s3.fmiref->p.field;
1755 fieldtype = fi->type;
1759 switch (fieldtype) {
1761 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1773 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1777 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1784 emit_store_dst(jd, iptr, d);
1787 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1790 emit_nullpointer_check(cd, iptr, s1);
1792 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1793 uf = iptr->sx.s23.s3.uf;
1794 fieldtype = uf->fieldref->parseddesc.fd->type;
1799 fi = iptr->sx.s23.s3.fmiref->p.field;
1800 fieldtype = fi->type;
1804 if (IS_INT_LNG_TYPE(fieldtype))
1805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1807 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1809 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1810 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1812 switch (fieldtype) {
1814 M_IST(s2, s1, disp);
1817 M_STX(s2, s1, disp);
1820 M_AST(s2, s1, disp);
1823 M_FST(s2, s1, disp);
1826 M_DST(s2, s1, disp);
1834 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1835 /* val = value (in current instruction) */
1836 /* following NOP) */
1838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1839 emit_nullpointer_check(cd, iptr, s1);
1841 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1842 unresolved_field *uf = iptr->sx.s23.s3.uf;
1844 fieldtype = uf->fieldref->parseddesc.fd->type;
1846 codegen_addpatchref(cd, PATCHER_get_putfield,
1849 if (opt_showdisassemble) {
1857 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1859 fieldtype = fi->type;
1865 switch (fieldtype) {
1867 M_IST(REG_ZERO, s1, disp);
1870 M_STX(REG_ZERO, s1, disp);
1873 M_AST(REG_ZERO, s1, disp);
1876 M_FST(REG_ZERO, s1, disp);
1879 M_DST(REG_ZERO, s1, disp);
1885 /* branch operations **************************************************/
1887 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1890 M_INTMOVE(s1, REG_ITMP2_XPTR);
1892 #ifdef ENABLE_VERIFIER
1893 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1894 unresolved_class *uc = iptr->sx.s23.s2.uc;
1896 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1898 #endif /* ENABLE_VERIFIER */
1900 disp = dseg_add_functionptr(cd, asm_handle_exception);
1901 M_ALD(REG_ITMP1, REG_PV, disp);
1902 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1904 M_NOP; /* nop ensures that XPC is less than the end */
1905 /* of basic block */
1909 case ICMD_GOTO: /* ... ==> ... */
1910 case ICMD_RET: /* ... ==> ... */
1912 emit_br(cd, iptr->dst.block);
1916 case ICMD_JSR: /* ... ==> ... */
1918 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1922 case ICMD_IFNULL: /* ..., value ==> ... */
1923 case ICMD_IFNONNULL:
1925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1926 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1929 /* Note: int compares must not branch on the register directly. */
1930 /* Reason is, that register content is not 32-bit clean. */
1932 case ICMD_IFEQ: /* ..., value ==> ... */
1934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1936 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1937 M_CMP_IMM(s1, iptr->sx.val.i);
1940 ICONST(REG_ITMP2, iptr->sx.val.i);
1941 M_CMP(s1, REG_ITMP2);
1943 emit_beq(cd, iptr->dst.block);
1946 case ICMD_IFLT: /* ..., value ==> ... */
1948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1950 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1951 M_CMP_IMM(s1, iptr->sx.val.i);
1954 ICONST(REG_ITMP2, iptr->sx.val.i);
1955 M_CMP(s1, REG_ITMP2);
1957 emit_blt(cd, iptr->dst.block);
1960 case ICMD_IFLE: /* ..., value ==> ... */
1962 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1964 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1965 M_CMP_IMM(s1, iptr->sx.val.i);
1968 ICONST(REG_ITMP2, iptr->sx.val.i);
1969 M_CMP(s1, REG_ITMP2);
1971 emit_ble(cd, iptr->dst.block);
1974 case ICMD_IFNE: /* ..., value ==> ... */
1976 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1978 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1979 M_CMP_IMM(s1, iptr->sx.val.i);
1982 ICONST(REG_ITMP2, iptr->sx.val.i);
1983 M_CMP(s1, REG_ITMP2);
1985 emit_bne(cd, iptr->dst.block);
1988 case ICMD_IFGT: /* ..., value ==> ... */
1990 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1992 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1993 M_CMP_IMM(s1, iptr->sx.val.i);
1996 ICONST(REG_ITMP2, iptr->sx.val.i);
1997 M_CMP(s1, REG_ITMP2);
1999 emit_bgt(cd, iptr->dst.block);
2002 case ICMD_IFGE: /* ..., value ==> ... */
2004 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2006 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2007 M_CMP_IMM(s1, iptr->sx.val.i);
2010 ICONST(REG_ITMP2, iptr->sx.val.i);
2011 M_CMP(s1, REG_ITMP2);
2013 emit_bge(cd, iptr->dst.block);
2016 case ICMD_IF_LEQ: /* ..., value ==> ... */
2018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019 if (iptr->sx.val.l == 0)
2020 emit_beqz(cd, iptr->dst.block, s1);
2022 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2023 M_CMP_IMM(s1, iptr->sx.val.l);
2026 LCONST(REG_ITMP2, iptr->sx.val.l);
2027 M_CMP(s1, REG_ITMP2);
2029 emit_beq_xcc(cd, iptr->dst.block);
2033 case ICMD_IF_LLT: /* ..., value ==> ... */
2035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2036 if (iptr->sx.val.l == 0)
2037 emit_bltz(cd, iptr->dst.block, s1);
2039 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2040 M_CMP_IMM(s1, iptr->sx.val.l);
2043 LCONST(REG_ITMP2, iptr->sx.val.l);
2044 M_CMP(s1, REG_ITMP2);
2046 emit_blt_xcc(cd, iptr->dst.block);
2050 case ICMD_IF_LLE: /* ..., value ==> ... */
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053 if (iptr->sx.val.l == 0)
2054 emit_blez(cd, iptr->dst.block, s1);
2056 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2057 M_CMP_IMM(s1, iptr->sx.val.l);
2060 LCONST(REG_ITMP2, iptr->sx.val.l);
2061 M_CMP(s1, REG_ITMP2);
2063 emit_ble_xcc(cd, iptr->dst.block);
2067 case ICMD_IF_LNE: /* ..., value ==> ... */
2069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070 if (iptr->sx.val.l == 0)
2071 emit_bnez(cd, iptr->dst.block, s1);
2073 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2074 M_CMP_IMM(s1, iptr->sx.val.l);
2077 LCONST(REG_ITMP2, iptr->sx.val.l);
2078 M_CMP(s1, REG_ITMP2);
2080 emit_bne_xcc(cd, iptr->dst.block);
2084 case ICMD_IF_LGT: /* ..., value ==> ... */
2086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2087 if (iptr->sx.val.l == 0)
2088 emit_bgtz(cd, iptr->dst.block, s1);
2090 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2091 M_CMP_IMM(s1, iptr->sx.val.l);
2094 LCONST(REG_ITMP2, iptr->sx.val.l);
2095 M_CMP(s1, REG_ITMP2);
2097 emit_bgt_xcc(cd, iptr->dst.block);
2101 case ICMD_IF_LGE: /* ..., value ==> ... */
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 if (iptr->sx.val.l == 0)
2105 emit_bgez(cd, iptr->dst.block, s1);
2107 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2108 M_CMP_IMM(s1, iptr->sx.val.l);
2111 LCONST(REG_ITMP2, iptr->sx.val.l);
2112 M_CMP(s1, REG_ITMP2);
2114 emit_bge_xcc(cd, iptr->dst.block);
2119 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2120 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2122 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2123 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2125 emit_beq_xcc(cd, iptr->dst.block);
2128 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2133 emit_beq(cd, iptr->dst.block);
2136 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2137 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2140 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142 emit_bne_xcc(cd, iptr->dst.block);
2145 case ICMD_IF_ICMPNE: /* 32-bit compare */
2147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2148 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2150 emit_bne(cd, iptr->dst.block);
2153 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2156 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2158 emit_blt_xcc(cd, iptr->dst.block);
2161 case ICMD_IF_ICMPLT: /* 32-bit compare */
2163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2164 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2166 emit_blt(cd, iptr->dst.block);
2169 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2171 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2172 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2174 emit_bgt_xcc(cd, iptr->dst.block);
2177 case ICMD_IF_ICMPGT: /* 32-bit compare */
2179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2180 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2182 emit_bgt(cd, iptr->dst.block);
2185 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2187 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2188 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2190 emit_ble_xcc(cd, iptr->dst.block);
2193 case ICMD_IF_ICMPLE: /* 32-bit compare */
2195 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2196 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2198 emit_ble(cd, iptr->dst.block);
2202 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2204 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2205 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2207 emit_bge_xcc(cd, iptr->dst.block);
2210 case ICMD_IF_ICMPGE: /* 32-bit compare */
2212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2213 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2215 emit_bge(cd, iptr->dst.block);
2219 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2222 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2223 M_INTMOVE(s1, REG_RESULT_CALLEE);
2224 goto nowperformreturn;
2226 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2228 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2229 M_INTMOVE(s1, REG_RESULT_CALLEE);
2231 #ifdef ENABLE_VERIFIER
2232 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2233 unresolved_class *uc = iptr->sx.s23.s2.uc;
2235 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2237 #endif /* ENABLE_VERIFIER */
2238 goto nowperformreturn;
2240 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2243 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2244 M_DBLMOVE(s1, REG_FRESULT);
2245 goto nowperformreturn;
2247 case ICMD_RETURN: /* ... ==> ... */
2253 p = cd->stackframesize;
2255 #if !defined(NDEBUG)
2256 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2257 emit_verbosecall_exit(jd);
2260 #if defined(ENABLE_THREADS)
2261 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2262 /* XXX jit-c-call */
2263 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2264 M_ALD(REG_ITMP3, REG_PV, disp);
2266 /* we need to save fp return value (int saved by window) */
2268 switch (iptr->opc) {
2271 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2272 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2273 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2275 /* restore the fp return value */
2277 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2283 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2284 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2295 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2301 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2304 branch_target_t *table;
2306 table = iptr->dst.table;
2308 l = iptr->sx.s23.s2.tablelow;
2309 i = iptr->sx.s23.s3.tablehigh;
2311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2313 M_INTMOVE(s1, REG_ITMP1);
2315 else if (l <= 4095) {
2316 M_ADD_IMM(s1, -l, REG_ITMP1);
2319 ICONST(REG_ITMP2, l);
2320 /* XXX: do I need to truncate s1 to 32-bit ? */
2321 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2329 M_CMP_IMM(REG_ITMP1, i - 1);
2332 ICONST(REG_ITMP2, i - 1);
2333 M_CMP(REG_ITMP1, REG_ITMP2);
2335 emit_bugt(cd, table[0].block); /* default target */
2337 /* build jump table top down and use address of lowest entry */
2342 dseg_add_target(cd, table->block);
2347 /* length of dataseg after last dseg_addtarget is used by load */
2349 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2350 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2351 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2352 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2357 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2360 lookup_target_t *lookup;
2362 lookup = iptr->dst.lookup;
2364 i = iptr->sx.s23.s2.lookupcount;
2366 MCODECHECK((i<<2)+8);
2367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2370 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2371 M_CMP_IMM(s1, lookup->value);
2373 ICONST(REG_ITMP2, lookup->value);
2374 M_CMP(s1, REG_ITMP2);
2376 emit_beq(cd, lookup->target.block);
2380 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2386 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2388 bte = iptr->sx.s23.s3.bte;
2391 /* XXX: builtin calling with stack arguments not implemented */
2392 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2394 s3 = md->paramcount;
2396 MCODECHECK((s3 << 1) + 64);
2398 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2400 /* copy float arguments according to ABI convention */
2402 int num_fltregargs = 0;
2403 int fltregarg_inswap[16];
2405 for (s3 = s3 - 1; s3 >= 0; s3--) {
2406 var = VAR(iptr->sx.s23.s2.args[s3]);
2408 if (IS_FLT_DBL_TYPE(var->type)) {
2409 if (!md->params[s3].inmemory) {
2410 s1 = s3; /*native flt args use argument index directly*/
2411 d = emit_load(jd, iptr, var, REG_FTMP1);
2414 fltregarg_inswap[num_fltregargs] = s1;
2416 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2425 /* move swapped float args to target regs */
2426 for (i = 0; i < num_fltregargs; i++) {
2427 s1 = fltregarg_inswap[i];
2428 M_DMOV(s1 + 16, s1);
2429 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2433 assert(md->argfltreguse == 0);
2438 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2440 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2441 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2442 case ICMD_INVOKEINTERFACE:
2444 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2446 um = iptr->sx.s23.s3.um;
2447 md = um->methodref->parseddesc.md;
2450 lm = iptr->sx.s23.s3.fmiref->p.method;
2452 md = lm->parseddesc;
2456 s3 = md->paramcount;
2458 MCODECHECK((s3 << 1) + 64);
2460 /* copy arguments to registers or stack location */
2462 for (s3 = s3 - 1; s3 >= 0; s3--) {
2463 var = VAR(iptr->sx.s23.s2.args[s3]);
2464 d = md->params[s3].regoff;
2466 if (var->flags & PREALLOC)
2469 if (IS_INT_LNG_TYPE(var->type)) {
2470 if (!md->params[s3].inmemory) {
2471 s1 = emit_load(jd, iptr, var, d);
2475 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2476 M_STX(s1, REG_SP, JITSTACK + d);
2480 #ifdef BUILTIN_FLOAT_ARGS
2481 if (iptr->opc == ICMD_BUILTIN)
2485 if (!md->params[s3].inmemory) {
2486 s1 = emit_load(jd, iptr, var, d);
2487 if (IS_2_WORD_TYPE(var->type))
2493 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2494 M_DST(s1, REG_SP, JITSTACK + d);
2499 switch (iptr->opc) {
2501 disp = dseg_add_functionptr(cd, bte->fp);
2503 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2505 /* XXX jit-c-call */
2506 /* generate the actual call */
2508 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2510 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2511 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2512 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2514 emit_exception_check(cd, iptr);
2515 if (md->returntype.type == TYPE_FLT) {
2516 /* special handling for float return value in %f0 */
2521 case ICMD_INVOKESPECIAL:
2522 emit_nullpointer_check(cd, iptr, REG_OUT0);
2525 case ICMD_INVOKESTATIC:
2527 disp = dseg_add_unique_address(cd, NULL);
2529 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2533 disp = dseg_add_address(cd, lm->stubroutine);
2535 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2537 /* generate the actual call */
2539 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2541 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2542 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2543 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2546 case ICMD_INVOKEVIRTUAL:
2547 emit_nullpointer_check(cd, iptr, REG_OUT0);
2550 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2555 s1 = OFFSET(vftbl_t, table[0]) +
2556 sizeof(methodptr) * lm->vftblindex;
2558 /* implicit null-pointer check */
2559 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2560 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2562 /* generate the actual call */
2564 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2566 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2567 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2568 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2571 case ICMD_INVOKEINTERFACE:
2572 emit_nullpointer_check(cd, iptr, REG_OUT0);
2575 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2581 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2582 sizeof(methodptr*) * lm->class->index;
2584 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2587 /* implicit null-pointer check */
2588 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2589 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2590 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2592 /* generate the actual call */
2594 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2596 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2597 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2598 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2602 /* store return value */
2604 d = md->returntype.type;
2606 if (d != TYPE_VOID) {
2607 if (IS_INT_LNG_TYPE(d)) {
2608 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2609 M_INTMOVE(REG_RESULT_CALLER, s1);
2612 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2613 if (IS_2_WORD_TYPE(d)) {
2614 M_DBLMOVE(REG_FRESULT, s1);
2616 M_FLTMOVE(REG_FRESULT, s1);
2619 emit_store_dst(jd, iptr, s1);
2624 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2625 /* val.a: (classinfo*) superclass */
2627 /* superclass is an interface:
2629 * OK if ((sub == NULL) ||
2630 * (sub->vftbl->interfacetablelength > super->index) &&
2631 * (sub->vftbl->interfacetable[-super->index] != NULL));
2633 * superclass is a class:
2635 * OK if ((sub == NULL) || (0
2636 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2637 * super->vftbl->diffvall));
2640 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2644 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2649 super = iptr->sx.s23.s3.c.cls;
2650 superindex = super->index;
2653 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2654 CODEGEN_CRITICAL_SECTION_NEW;
2656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2658 /* if class is not resolved, check which code to call */
2660 if (super == NULL) {
2661 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2663 cr = iptr->sx.s23.s3.c.ref;
2664 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2666 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2669 M_ILD(REG_ITMP2, REG_PV, disp);
2670 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2671 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2674 /* interface checkcast code */
2676 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2677 if (super == NULL) {
2678 cr = iptr->sx.s23.s3.c.ref;
2680 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2684 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2687 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2688 M_ILD(REG_ITMP3, REG_ITMP2,
2689 OFFSET(vftbl_t, interfacetablelength));
2690 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2691 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2693 M_ALD(REG_ITMP3, REG_ITMP2,
2694 OFFSET(vftbl_t, interfacetable[0]) -
2695 superindex * sizeof(methodptr*));
2696 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2699 emit_label_br(cd, BRANCH_LABEL_4);
2701 emit_label(cd, BRANCH_LABEL_3);
2704 /* class checkcast code */
2706 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2707 if (super == NULL) {
2708 emit_label(cd, BRANCH_LABEL_2);
2710 cr = iptr->sx.s23.s3.c.ref;
2711 disp = dseg_add_unique_address(cd, NULL);
2713 codegen_add_patch_ref(cd,
2714 PATCHER_checkcast_instanceof_class,
2718 disp = dseg_add_address(cd, super->vftbl);
2720 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2723 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2724 M_ALD(REG_ITMP3, REG_PV, disp);
2726 CODEGEN_CRITICAL_SECTION_START;
2728 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2729 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2730 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2731 M_ALD(REG_ITMP3, REG_PV, disp);
2732 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2734 CODEGEN_CRITICAL_SECTION_END;
2737 M_CMP(REG_ITMP3, REG_ITMP2);
2738 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2741 emit_label(cd, BRANCH_LABEL_5);
2744 if (super == NULL) {
2745 emit_label(cd, BRANCH_LABEL_1);
2746 emit_label(cd, BRANCH_LABEL_4);
2749 d = codegen_reg_of_dst(jd, iptr, s1);
2752 /* array type cast-check */
2754 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2755 M_INTMOVE(s1, REG_OUT0);
2757 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2759 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2760 cr = iptr->sx.s23.s3.c.ref;
2761 disp = dseg_add_unique_address(cd, NULL);
2763 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2767 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2769 M_ALD(REG_OUT1, REG_PV, disp);
2770 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2771 M_ALD(REG_ITMP3, REG_PV, disp);
2772 /* XXX jit-c-call */
2773 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2776 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2777 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2779 d = codegen_reg_of_dst(jd, iptr, s1);
2783 emit_store_dst(jd, iptr, d);
2786 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2787 /* val.a: (classinfo*) superclass */
2789 /* superclass is an interface:
2791 * return (sub != NULL) &&
2792 * (sub->vftbl->interfacetablelength > super->index) &&
2793 * (sub->vftbl->interfacetable[-super->index] != NULL);
2795 * superclass is a class:
2797 * return ((sub != NULL) && (0
2798 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2799 * super->vftbl->diffvall));
2804 vftbl_t *supervftbl;
2807 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2813 super = iptr->sx.s23.s3.c.cls;
2814 superindex = super->index;
2815 supervftbl = super->vftbl;
2818 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2819 CODEGEN_CRITICAL_SECTION_NEW;
2821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2824 M_MOV(s1, REG_ITMP1);
2830 /* if class is not resolved, check which code to call */
2832 if (super == NULL) {
2833 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2835 cr = iptr->sx.s23.s3.c.ref;
2836 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2838 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2841 M_ILD(REG_ITMP3, REG_PV, disp);
2842 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2843 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2846 /* interface instanceof code */
2848 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2849 if (super == NULL) {
2850 cr = iptr->sx.s23.s3.c.ref;
2852 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2856 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2859 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2860 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2861 M_CMP_IMM(REG_ITMP3, superindex);
2864 M_ALD(REG_ITMP1, REG_ITMP1,
2865 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2866 superindex * sizeof(methodptr*)));
2867 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2870 emit_label_br(cd, BRANCH_LABEL_4);
2872 emit_label(cd, BRANCH_LABEL_3);
2875 /* class instanceof code */
2877 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2878 if (super == NULL) {
2879 emit_label(cd, BRANCH_LABEL_2);
2881 cr = iptr->sx.s23.s3.c.ref;
2882 disp = dseg_add_unique_address(cd, NULL);
2884 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2888 disp = dseg_add_address(cd, supervftbl);
2890 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2893 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2894 M_ALD(REG_ITMP2, REG_PV, disp);
2896 CODEGEN_CRITICAL_SECTION_START;
2898 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2899 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2900 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2902 CODEGEN_CRITICAL_SECTION_END;
2904 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2905 M_CMP(REG_ITMP1, REG_ITMP2);
2906 M_XCMOVULE_IMM(1, d);
2909 emit_label(cd, BRANCH_LABEL_5);
2912 if (super == NULL) {
2913 emit_label(cd, BRANCH_LABEL_1);
2914 emit_label(cd, BRANCH_LABEL_4);
2917 emit_store_dst(jd, iptr, d);
2921 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2923 /* check for negative sizes and copy sizes to stack if necessary */
2925 MCODECHECK((iptr->s1.argcount << 1) + 64);
2927 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2929 var = VAR(iptr->sx.s23.s2.args[s1]);
2931 /* copy SAVEDVAR sizes to stack */
2933 /* Already Preallocated? */
2935 if (!(var->flags & PREALLOC)) {
2936 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2937 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2941 /* arg 0 = dimension count */
2943 ICONST(REG_OUT0, iptr->s1.argcount);
2945 /* is patcher function set? */
2947 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2948 disp = dseg_add_unique_address(cd, 0);
2950 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2951 iptr->sx.s23.s3.c.ref,
2955 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2957 /* arg 1 = arraydescriptor */
2959 M_ALD(REG_OUT1, REG_PV, disp);
2961 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2963 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2965 /* XXX c abi call */
2966 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2967 M_ALD(REG_ITMP3, REG_PV, disp);
2968 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2971 /* check for exception before result assignment */
2973 emit_exception_check(cd, iptr);
2975 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2976 M_INTMOVE(REG_RESULT_CALLER, d);
2977 emit_store_dst(jd, iptr, d);
2981 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2987 } /* for instruction */
2991 /* At the end of a basic block we may have to append some nops,
2992 because the patcher stub calling code might be longer than the
2993 actual instruction. So codepatching does not change the
2994 following block unintentionally. */
2996 if (cd->mcodeptr < cd->lastmcodeptr) {
2997 while (cd->mcodeptr < cd->lastmcodeptr) {
3002 } /* if (bptr -> flags >= BBREACHED) */
3003 } /* for basic block */
3005 dseg_createlinenumbertable(cd);
3007 /* generate stubs */
3009 emit_patcher_stubs(jd);
3010 REPLACEMENT_EMIT_STUBS(jd);
3012 /* everything's ok */
3018 /* codegen_emit_stub_compiler **************************************************
3020 Emits a stub routine which calls the compiler.
3022 *******************************************************************************/
3024 void codegen_emit_stub_compiler(jitdata *jd)
3029 /* get required compiler data */
3034 /* code for the stub */
3036 /* no window save yet, user caller's PV */
3037 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3038 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3039 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3044 /* codegen_emit_stub_native ****************************************************
3046 Emits a stub routine which calls a native method.
3048 *******************************************************************************/
3050 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3057 s4 i, j; /* count variables */
3060 s4 funcdisp; /* displacement of the function */
3061 s4 fltregarg_offset[FLT_ARG_CNT];
3063 /* get required compiler data */
3069 /* initialize variables */
3072 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3074 /* calculate stack frame size */
3076 cd->stackframesize =
3077 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3078 sizeof(localref_table) / SIZEOF_VOID_P +
3079 md->paramcount + /* for saving arguments over calls */
3080 nmd->memuse + /* nmd knows about the native stackframe layout */
3084 /* keep stack 16-byte aligned (ABI requirement) */
3086 if (cd->stackframesize & 1)
3087 cd->stackframesize++;
3089 /* create method header */
3091 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3092 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3093 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3094 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3095 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3096 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3097 (void) dseg_addlinenumbertablesize(cd);
3098 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3100 /* generate stub code */
3102 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3104 #if !defined(NDEBUG)
3105 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3106 emit_verbosecall_enter(jd);
3109 /* get function address (this must happen before the stackframeinfo) */
3111 funcdisp = dseg_add_functionptr(cd, f);
3113 #if !defined(WITH_STATIC_CLASSPATH)
3115 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3119 /* save float argument registers (into abi parameter slots) */
3121 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3123 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3124 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3125 s1 = WINSAVE_CNT + nmd->memuse + j;
3126 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3127 fltregarg_offset[i] = s1; /* remember stack offset */
3132 /* prepare data structures for native function call */
3134 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3135 M_MOV(REG_PV_CALLEE, REG_OUT1);
3136 M_MOV(REG_FP, REG_OUT2); /* java sp */
3137 M_MOV(REG_RA_CALLEE, REG_OUT3);
3138 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3139 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3140 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3141 M_NOP; /* XXX fill me! */
3143 /* keep float arguments on stack */
3145 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3146 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3147 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3153 /* copy or spill arguments to new locations */
3155 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3156 t = md->paramtypes[i].type;
3158 if (IS_INT_LNG_TYPE(t)) {
3160 /* integral types */
3162 if (!md->params[i].inmemory) {
3163 s1 = md->params[i].regoff;
3164 /* s1 refers to the old window, transpose */
3165 s1 = REG_WINDOW_TRANSPOSE(s1);
3167 if (!nmd->params[j].inmemory) {
3168 s2 = nat_argintregs[nmd->params[j].regoff];
3171 s2 = nmd->params[j].regoff - 6 * 8;
3172 M_AST(s1, REG_SP, CSTACK + s2);
3176 if (!nmd->params[j].inmemory) {
3177 /* JIT stack arg -> NAT reg arg */
3179 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3180 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3182 assert(false); /* path never taken */
3185 s1 = md->params[i].regoff + cd->stackframesize * 8;
3186 s2 = nmd->params[j].regoff - 6 * 8;
3187 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3188 M_AST(REG_ITMP1, REG_SP, CSTACK + s2);
3193 /* floating point types */
3195 if (!md->params[i].inmemory) {
3196 s1 = md->params[i].regoff;
3198 if (!nmd->params[j].inmemory) {
3200 /* no mapping to regs needed, native flt args use regoff */
3201 s2 = nmd->params[j].regoff;
3203 /* JIT float regs are still on the stack */
3204 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3207 /* not supposed to happen with 16 NAT flt args */
3210 s2 = nmd->params[j].regoff;
3211 if (IS_2_WORD_TYPE(t))
3212 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3214 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3220 s1 = md->params[i].regoff + cd->stackframesize * 8;
3222 if (!nmd->params[j].inmemory) {
3224 /* JIT stack -> NAT reg */
3226 s2 = nmd->params[j].regoff;
3227 M_DLD(s2, REG_SP, CSTACK + s1);
3231 /* JIT stack -> NAT stack */
3233 s2 = nmd->params[j].regoff - 6 * 8;
3235 /* The FTMP register may already be loaded with args */
3236 /* we know $f0 is unused because of the env pointer */
3237 M_DLD(REG_F0, REG_SP, CSTACK + s1);
3238 M_DST(REG_F0, REG_SP, CSTACK + s2);
3245 /* put class into second argument register */
3247 if (m->flags & ACC_STATIC) {
3248 disp = dseg_add_address(cd, m->class);
3249 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3252 /* put env into first argument register */
3254 disp = dseg_add_address(cd, _Jv_env);
3255 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3257 /* do the native function call */
3259 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3260 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3261 M_NOP; /* delay slot */
3263 /* save return value */
3265 if (md->returntype.type != TYPE_VOID) {
3266 if (IS_INT_LNG_TYPE(md->returntype.type))
3267 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3269 M_DST(REG_FRESULT, REG_SP, CSTACK);
3272 /* Note: native functions return float values in %f0 (see ABI) */
3273 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3275 #if !defined(NDEBUG)
3276 /* But for the trace function we need to put a flt result into %f1 */
3277 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3278 if (!IS_2_WORD_TYPE(md->returntype.type))
3279 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3280 emit_verbosecall_exit(jd);
3284 /* remove native stackframe info */
3286 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3287 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3288 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3289 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3290 M_NOP; /* XXX fill me! */
3291 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3293 /* restore float return value, int return value already in our return reg */
3295 if (md->returntype.type != TYPE_VOID) {
3296 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3297 if (IS_2_WORD_TYPE(md->returntype.type))
3298 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3300 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3304 /* check for exception */
3305 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3308 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3311 /* handle exception */
3313 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3314 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3315 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3316 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3317 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3319 /* generate patcher stubs */
3321 emit_patcher_stubs(jd);
3325 * These are local overrides for various environment variables in Emacs.
3326 * Please do not remove this and leave it at the end of the file, where
3327 * Emacs will automagically detect them.
3328 * ---------------------------------------------------------------------
3331 * indent-tabs-mode: t
3335 * vim:noexpandtab:sw=4:ts=4: