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 $
40 /* #include "vm/jit/sparc64/arch.h" */
41 #include "vm/jit/sparc64/codegen.h"
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/localref.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/sparc64/emit.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/parse.h"
60 #include "vm/jit/patcher.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vmcore/loader.h"
65 #include "vmcore/options.h"
67 #include "vm/jit/sparc64/solaris/macro_rename.h"
69 #define BUILTIN_FLOAT_ARGS 1
71 /* XXX use something like this for window control ?
72 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
74 #define REG_PV REG_PV_CALLEE
79 if ((disp < -4096) || (disp > 4095))
80 printf("disp %d\n", disp);
83 return (disp >= -4096) && (disp <= 4095);
86 s4 get_lopart_disp(disp)
91 lodisp = setlo_part(disp);
93 if (setlo_part(disp) == 0)
96 lodisp = setlo_part(disp) | 0x1c00;
103 bool check_13bit_imm(s8 imm)
105 s4 sign = (imm >> 12) & 0x1;
108 if ((imm & ~0xfff) == 0) return true; /* pos imm. */
111 if ((imm & ~0xfff) + 0xfff == -1) return true; /* neg imm. */
113 printf("immediate out-of-bounds: %ld\n", imm);
119 /* codegen_emit ****************************************************************
121 Generates machine code.
123 *******************************************************************************/
125 bool codegen_emit(jitdata *jd)
131 s4 len, s1, s2, s3, d, disp, slots;
137 constant_classref *cr;
138 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
139 unresolved_method *um;
140 builtintable_entry *bte;
143 unresolved_field *uf;
147 /* get required compiler data */
154 /* prevent compiler warnings */
166 #if 0 /* no leaf optimization yet */
167 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
169 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
172 /* space to save used callee saved registers */
174 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
175 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
177 cd->stackframesize = rd->memuse + savedregs_num;
179 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
180 if (checksync && (m->flags & ACC_SYNCHRONIZED))
181 cd->stackframesize++;
184 /* keep stack 16-byte aligned (ABI requirement) */
186 if (cd->stackframesize & 1)
187 cd->stackframesize++;
189 /* create method header */
191 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
192 framesize_disp = dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
194 #if defined(ENABLE_THREADS)
195 /* IsSync contains the offset relative to the stack pointer for the
196 argument of monitor_exit used in the exception handler. Since the
197 offset could be zero and give a wrong meaning of the flag it is
201 if (checksync && (m->flags & ACC_SYNCHRONIZED))
202 (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
205 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
207 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
208 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
209 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
210 dseg_addlinenumbertablesize(cd);
211 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
213 /* create exception table */
215 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
216 dseg_add_target(cd, ex->start);
217 dseg_add_target(cd, ex->end);
218 dseg_add_target(cd, ex->handler);
219 (void) dseg_add_unique_address(cd, ex->catchtype.any);
222 /* save register window and create stack frame (if necessary) */
224 if (cd->stackframesize) {
225 if (cd->stackframesize <= 4095)
226 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
228 M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
229 M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
230 M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
234 /* save callee saved float registers (none right now) */
236 p = cd->stackframesize;
237 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
238 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
243 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
244 emit_verbosecall_enter(jd);
248 /* call monitorenter function */
249 #if defined(ENABLE_THREADS)
250 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
251 /* stack offset for monitor argument */
255 /* save float argument registers */
259 ALIGN_STACK_SLOTS(slots);
261 M_LDA(REG_SP, REG_SP, -(slots * 8));
262 for (i = 0; i < FLT_ARG_CNT; i++)
263 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
267 /* get correct lock object */
269 if (m->flags & ACC_STATIC) {
270 disp = dseg_add_address(cd, &m->class->object.header);
271 M_ALD(REG_OUT0, REG_PV, disp);
272 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
273 M_ALD(REG_ITMP3, REG_PV, disp);
276 /* copy class pointer: $i0 -> $o0 */
277 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
279 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
280 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
281 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
284 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
285 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
287 /* restore float argument registers */
289 for (i = 0; i < FLT_ARG_CNT; i++)
290 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
292 M_LDA(REG_SP, REG_SP, slots * 8);
297 /* take arguments out of register or stack frame */
301 for (p = 0, l = 0; p < md->paramcount; p++) {
302 t = md->paramtypes[p].type;
304 varindex = jd->local_map[l * 5 + t];
307 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
310 if (varindex == UNUSED)
314 s1 = md->params[p].regoff;
316 if (IS_INT_LNG_TYPE(t)) { /* integer args */
320 if (!md->params[p].inmemory) { /* register arguments */
321 s1 = REG_WINDOW_TRANSPOSE(s1);
323 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
325 /* the register allocator does not know about the window. */
326 /* avoid copying the locals from save to save regs by */
327 /* swapping variables. */
330 int old_dest = var->vv.regoff;
331 int new_dest = p + 24;
333 /* run through all variables */
335 for (i = 0; i < jd->varcount; i++) {
336 varinfo* uvar = VAR(i);
338 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
341 s2 = uvar->vv.regoff;
343 /* free the in reg by moving all other references */
345 if (s2 == new_dest) {
346 uvar->vv.regoff = old_dest;
347 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
350 /* move all variables to the in reg */
352 if (s2 == old_dest) {
353 uvar->vv.regoff = new_dest;
354 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
362 else { /* reg arg -> spilled */
363 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
366 } else { /* stack arguments */
367 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
368 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
370 } else { /* stack arg -> spilled */
371 /* add the callers window save registers */
372 var->vv.regoff = cd->stackframesize * 8 + s1;
376 } else { /* floating args */
377 if (!md->params[p].inmemory) { /* register arguments */
378 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
379 M_FLTMOVE(s1, var->vv.regoff);
381 } else { /* reg arg -> spilled */
382 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
385 } else { /* stack arguments */
386 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
387 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
389 } else { /* stack-arg -> spilled */
390 var->vv.regoff = cd->stackframesize * 8 + s1;
399 /* end of header generation */
401 /* create replacement points */
403 REPLACEMENT_POINTS_INIT(cd, jd);
405 /* walk through all basic blocks */
407 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
409 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
411 if (bptr->flags >= BBREACHED) {
413 /* branch resolving */
415 codegen_resolve_branchrefs(cd, bptr);
417 /* handle replacement points */
420 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
421 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
427 /* copy interface registers to their destination */
432 #if defined(ENABLE_LSRA)
433 #error XXX LSRA not tested yet
437 src = bptr->invars[len];
438 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
439 /* d = reg_of_var(m, src, REG_ITMP1); */
440 if (!(src->flags & INMEMORY))
444 M_INTMOVE(REG_ITMP1, d);
445 emit_store(jd, NULL, src, d);
452 var = VAR(bptr->invars[len]);
453 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
454 d = codegen_reg_of_var(0, var, REG_ITMP1);
455 M_INTMOVE(REG_ITMP2_XPTR, d);
456 emit_store(jd, NULL, var, d);
459 assert((var->flags & INOUT));
462 #if defined(ENABLE_LSRA)
465 /* walk through all instructions */
469 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
470 if (iptr->line != currentline) {
471 dseg_addlinenumber(cd, iptr->line);
472 currentline = iptr->line;
475 MCODECHECK(64); /* an instruction usually needs < 64 words */
479 case ICMD_INLINE_START:
480 case ICMD_INLINE_END:
483 case ICMD_NOP: /* ... ==> ... */
486 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
489 emit_nullpointer_check(cd, iptr, s1);
492 /* constant operations ************************************************/
494 case ICMD_ICONST: /* ... ==> ..., constant */
496 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
497 ICONST(d, iptr->sx.val.i);
498 emit_store_dst(jd, iptr, d);
501 case ICMD_LCONST: /* ... ==> ..., constant */
503 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
504 LCONST(d, iptr->sx.val.l);
505 emit_store_dst(jd, iptr, d);
508 case ICMD_FCONST: /* ... ==> ..., constant */
510 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
511 disp = dseg_add_float(cd, iptr->sx.val.f);
512 M_FLD(d, REG_PV, disp);
513 emit_store_dst(jd, iptr, d);
516 case ICMD_DCONST: /* ... ==> ..., constant */
518 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
519 disp = dseg_add_double(cd, iptr->sx.val.d);
520 M_DLD(d, REG_PV, disp);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_ACONST: /* ... ==> ..., constant */
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
529 cr = iptr->sx.val.c.ref;
530 disp = dseg_add_unique_address(cd, cr);
532 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
534 M_ALD(d, REG_PV, disp);
538 if (iptr->sx.val.anyptr == NULL) {
539 M_INTMOVE(REG_ZERO, d);
542 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
543 M_ALD(d, REG_PV, disp);
546 emit_store_dst(jd, iptr, d);
550 /* load/store/copy/move operations ************************************/
552 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
557 case ICMD_ISTORE: /* ..., value ==> ... */
568 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
573 /* pop/dup/swap operations ********************************************/
575 /* attention: double and longs are only one entry in CACAO ICMDs */
577 case ICMD_POP: /* ..., value ==> ... */
578 case ICMD_POP2: /* ..., value, value ==> ... */
582 /* integer operations *************************************************/
584 case ICMD_INEG: /* ..., value ==> ..., - value */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589 M_SUB(REG_ZERO, s1, d);
590 emit_store_dst(jd, iptr, d);
593 case ICMD_I2L: /* ..., value ==> ..., value */
595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_L2I: /* ..., value ==> ..., value */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
606 emit_store_dst(jd, iptr, d);
609 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
613 M_SLLX_IMM(s1, 56, d);
614 M_SRAX_IMM( d, 56, d);
615 emit_store_dst(jd, iptr, d);
618 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
622 M_SLLX_IMM(s1, 48, d);
623 M_SRLX_IMM( d, 48, d);
624 emit_store_dst(jd, iptr, d);
627 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 M_SLLX_IMM(s1, 48, d);
632 M_SRAX_IMM( d, 48, d);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
643 emit_store_dst(jd, iptr, d);
647 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
648 /* sx.val.i = constant */
650 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
652 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
653 M_ADD_IMM(s1, iptr->sx.val.i, d);
655 ICONST(REG_ITMP2, iptr->sx.val.i);
656 M_ADD(s1, REG_ITMP2, d);
658 emit_store_dst(jd, iptr, d);
661 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
662 /* sx.val.l = constant */
664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
666 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
667 M_ADD_IMM(s1, iptr->sx.val.l, d);
669 LCONST(REG_ITMP2, iptr->sx.val.l);
670 M_ADD(s1, REG_ITMP2, d);
672 emit_store_dst(jd, iptr, d);
675 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
682 emit_store_dst(jd, iptr, d);
685 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
686 /* sx.val.i = constant */
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
690 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
691 M_SUB_IMM(s1, iptr->sx.val.i, d);
693 ICONST(REG_ITMP2, iptr->sx.val.i);
694 M_SUB(s1, REG_ITMP2, d);
696 emit_store_dst(jd, iptr, d);
699 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
700 /* sx.val.l = constant */
702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
703 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
704 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
705 M_SUB_IMM(s1, iptr->sx.val.l, d);
707 LCONST(REG_ITMP2, iptr->sx.val.l);
708 M_SUB(s1, REG_ITMP2, d);
710 emit_store_dst(jd, iptr, d);
713 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
720 emit_store_dst(jd, iptr, d);
723 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
724 /* sx.val.i = constant */
726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
728 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
729 M_MULX_IMM(s1, iptr->sx.val.i, d);
731 ICONST(REG_ITMP2, iptr->sx.val.i);
732 M_MULX(s1, REG_ITMP2, d);
734 emit_store_dst(jd, iptr, d);
737 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
738 /* sx.val.l = constant */
740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
741 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
742 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
743 M_MULX_IMM(s1, iptr->sx.val.l, d);
745 LCONST(REG_ITMP2, iptr->sx.val.l);
746 M_MULX(s1, REG_ITMP2, d);
748 emit_store_dst(jd, iptr, d);
751 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
752 /* XXX could also clear Y and use 32bit div */
753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
756 emit_arithmetic_check(cd, iptr, s2);
758 /* XXX trim s2 like s1 ? */
760 emit_store_dst(jd, iptr, d);
763 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768 emit_arithmetic_check(cd, iptr, s2);
770 emit_store_dst(jd, iptr, d);
773 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
776 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
777 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
778 emit_arithmetic_check(cd, iptr, s2);
780 /* XXX trim s2 like s1 ? */
781 M_DIVX(s1, s2, REG_ITMP3);
782 M_MULX(s2, REG_ITMP3, REG_ITMP3);
783 M_SUB(s1, REG_ITMP3, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
791 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
792 emit_arithmetic_check(cd, iptr, s2);
793 M_DIVX(s1, s2, REG_ITMP3);
794 M_MULX(s2, REG_ITMP3, REG_ITMP3);
795 M_SUB(s1, REG_ITMP3, d);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
800 case ICMD_LDIVPOW2: /* val.i = constant */
802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
804 M_SRAX_IMM(s1, 63, REG_ITMP2);
805 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
806 M_ADD(s1, REG_ITMP2, REG_ITMP2);
807 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
808 emit_store_dst(jd, iptr, d);
811 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
813 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
814 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
823 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
826 emit_store_dst(jd, iptr, d);
829 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
830 /* val.i = constant */
832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
834 M_SLL_IMM(s1, iptr->sx.val.i, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
839 /* val.i = constant */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 M_SLLX_IMM(s1, iptr->sx.val.i, d);
844 emit_store_dst(jd, iptr, d);
847 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 emit_store_dst(jd, iptr, d);
856 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
857 /* sx.val.i = constant */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
861 M_SRA_IMM(s1, iptr->sx.val.i, d);
862 emit_store_dst(jd, iptr, d);
865 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
867 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
875 /* sx.val.i = constant */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 M_SRL_IMM(s1, iptr->sx.val.i, d);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889 emit_store_dst(jd, iptr, d);
892 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
893 /* sx.val.i = constant */
895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
897 M_SRAX_IMM(s1, iptr->sx.val.i, d);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
911 /* sx.val.i = constant */
913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
914 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 M_SRLX_IMM(s1, iptr->sx.val.i, d);
916 emit_store_dst(jd, iptr, d);
919 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
924 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
930 /* sx.val.i = constant */
932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
934 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
935 M_AND_IMM(s1, iptr->sx.val.i, d);
937 ICONST(REG_ITMP2, iptr->sx.val.i);
938 M_AND(s1, REG_ITMP2, d);
940 emit_store_dst(jd, iptr, d);
943 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
944 /* sx.val.i = constant */
945 /* constant is actually constant - 1 */
947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
948 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
950 M_MOV(s1, REG_ITMP1);
953 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
954 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
955 M_AND_IMM(s1, iptr->sx.val.i, d);
958 M_SUB(REG_ZERO, s1, d);
959 M_AND_IMM(d, iptr->sx.val.i, d);
961 ICONST(REG_ITMP2, iptr->sx.val.i);
962 M_AND(s1, REG_ITMP2, d);
965 M_SUB(REG_ZERO, s1, d);
966 M_AND(d, REG_ITMP2, d);
968 M_SUB(REG_ZERO, d, d);
969 emit_store_dst(jd, iptr, d);
972 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
973 /* sx.val.l = constant */
975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
976 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
977 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
978 M_AND_IMM(s1, iptr->sx.val.l, d);
980 LCONST(REG_ITMP2, iptr->sx.val.l);
981 M_AND(s1, REG_ITMP2, d);
983 emit_store_dst(jd, iptr, d);
986 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
987 /* sx.val.l = constant */
989 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
990 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
992 M_MOV(s1, REG_ITMP1);
995 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
996 M_AND_IMM(s1, iptr->sx.val.l, d);
999 M_SUB(REG_ZERO, s1, d);
1000 M_AND_IMM(d, iptr->sx.val.l, d);
1002 LCONST(REG_ITMP2, iptr->sx.val.l);
1003 M_AND(s1, REG_ITMP2, d);
1006 M_SUB(REG_ZERO, s1, d);
1007 M_AND(d, REG_ITMP2, d);
1009 M_SUB(REG_ZERO, d, d);
1010 emit_store_dst(jd, iptr, d);
1013 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1016 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1017 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1018 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1020 emit_store_dst(jd, iptr, d);
1023 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1024 /* sx.val.i = constant */
1026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1027 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1028 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1029 M_OR_IMM(s1, iptr->sx.val.i, d);
1031 ICONST(REG_ITMP2, iptr->sx.val.i);
1032 M_OR(s1, REG_ITMP2, d);
1034 emit_store_dst(jd, iptr, d);
1037 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1038 /* sx.val.l = constant */
1040 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1041 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1043 M_OR_IMM(s1, iptr->sx.val.l, d);
1045 LCONST(REG_ITMP2, iptr->sx.val.l);
1046 M_OR(s1, REG_ITMP2, d);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1056 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1058 emit_store_dst(jd, iptr, d);
1061 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1062 /* sx.val.i = constant */
1064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1065 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1067 M_XOR_IMM(s1, iptr->sx.val.i, d);
1069 ICONST(REG_ITMP2, iptr->sx.val.i);
1070 M_XOR(s1, REG_ITMP2, d);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1076 /* sx.val.l = constant */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1080 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1081 M_XOR_IMM(s1, iptr->sx.val.l, d);
1083 LCONST(REG_ITMP2, iptr->sx.val.l);
1084 M_XOR(s1, REG_ITMP2, d);
1086 emit_store_dst(jd, iptr, d);
1090 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1093 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1094 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1097 M_XCMOVLT_IMM(-1, d);
1098 M_XCMOVGT_IMM(1, d);
1099 emit_store_dst(jd, iptr, d);
1103 /* floating operations ************************************************/
1105 case ICMD_FNEG: /* ..., value ==> ..., - value */
1107 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1108 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_DNEG: /* ..., value ==> ..., - value */
1115 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1116 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1118 emit_store_dst(jd, iptr, d);
1121 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1123 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1124 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1125 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1127 emit_store_dst(jd, iptr, d);
1130 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1132 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1133 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1134 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1141 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1142 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1143 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1145 emit_store_dst(jd, iptr, d);
1148 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1150 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1151 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1152 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1159 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1160 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1161 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1163 emit_store_dst(jd, iptr, d);
1166 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1168 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1169 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1170 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1177 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1178 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1179 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1181 emit_store_dst(jd, iptr, d);
1184 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1186 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1188 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1190 emit_store_dst(jd, iptr, d);
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1195 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1196 disp = dseg_add_unique_float(cd, 0.0);
1197 M_IST (s1, REG_PV_CALLEE, disp);
1198 M_FLD (d, REG_PV_CALLEE, disp);
1199 M_CVTIF (d, d); /* rd gets translated to double target register */
1200 emit_store_dst(jd, iptr, d);
1204 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1205 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1206 disp = dseg_add_unique_float(cd, 0.0);
1207 M_IST(s1, REG_PV_CALLEE, disp);
1208 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1209 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1210 emit_store_dst(jd, iptr, d);
1214 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1215 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1216 disp = dseg_add_unique_double(cd, 0.0);
1217 M_STX(s1, REG_PV_CALLEE, disp);
1218 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1219 M_CVTLF(REG_FTMP3, d);
1220 emit_store_dst(jd, iptr, d);
1224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1225 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1226 disp = dseg_add_unique_double(cd, 0.0);
1227 M_STX(s1, REG_PV_CALLEE, disp);
1228 M_DLD(d, REG_PV_CALLEE, disp);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1234 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1236 disp = dseg_add_unique_float(cd, 0.0);
1238 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1241 M_MOV(REG_ZERO, d); /* delay slot */
1243 M_CVTFI(s1, REG_FTMP2);
1244 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1245 M_ILD(d, REG_PV, disp);
1246 emit_store_dst(jd, iptr, d);
1250 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1251 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1252 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1253 disp = dseg_add_unique_float(cd, 0.0);
1255 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1258 M_MOV(REG_ZERO, d); /* delay slot */
1260 M_CVTDI(s1, REG_FTMP2);
1261 M_FST(REG_FTMP2, REG_PV, disp);
1262 M_ILD(d, REG_PV, disp);
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1267 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1268 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1269 disp = dseg_add_unique_double(cd, 0.0);
1271 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1274 M_MOV(REG_ZERO, d); /* delay slot */
1276 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1277 M_DST(REG_FTMP2, REG_PV, disp);
1278 M_LDX(d, REG_PV, disp);
1279 emit_store_dst(jd, iptr, d);
1282 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1283 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1284 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1285 disp = dseg_add_unique_double(cd, 0.0);
1287 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1290 M_MOV(REG_ZERO, d); /* delay slot */
1292 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1293 M_DST(REG_FTMP2, REG_PV, disp);
1294 M_LDX(d, REG_PV, disp);
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1300 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1301 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1303 emit_store_dst(jd, iptr, d);
1306 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1308 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1309 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1311 emit_store_dst(jd, iptr, d);
1314 /* XXX merge F/D versions? only compare instr. is different */
1315 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1317 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1318 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1319 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1321 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1322 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1323 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1329 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1330 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1331 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1333 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1334 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1335 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1336 emit_store_dst(jd, iptr, d);
1339 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1341 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1342 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1343 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1345 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1346 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1347 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1353 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1354 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1357 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1358 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1359 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1360 emit_store_dst(jd, iptr, d);
1364 /* memory operations **************************************************/
1366 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1370 emit_nullpointer_check(cd, iptr, s1);
1371 M_ILD(d, s1, OFFSET(java_array_t, size));
1372 emit_store_dst(jd, iptr, d);
1375 case ICMD_BALOAD: /* ..., 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_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1384 emit_store_dst(jd, iptr, d);
1387 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1389 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1390 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1391 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1392 /* implicit null-pointer check */
1393 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1394 M_AADD(s2, s1, REG_ITMP3);
1395 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1396 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1397 emit_store_dst(jd, iptr, d);
1400 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1405 /* implicit null-pointer check */
1406 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1407 M_AADD(s2, s1, REG_ITMP3);
1408 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1409 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1410 emit_store_dst(jd, iptr, d);
1413 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1415 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1416 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1417 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1418 /* implicit null-pointer check */
1419 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1420 M_ASLL_IMM(s2, 2, REG_ITMP3);
1421 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1422 M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1423 emit_store_dst(jd, iptr, d);
1426 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1431 /* implicit null-pointer check */
1432 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1433 M_ASLL_IMM(s2, 3, REG_ITMP3);
1434 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1435 M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1436 emit_store_dst(jd, iptr, d);
1439 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1442 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1444 /* implicit null-pointer check */
1445 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1446 M_ASLL_IMM(s2, 2, REG_ITMP3);
1447 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1448 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1449 emit_store_dst(jd, iptr, d);
1452 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1454 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1455 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1456 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1457 /* implicit null-pointer check */
1458 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1459 M_ASLL_IMM(s2, 3, REG_ITMP3);
1460 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1461 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1470 /* implicit null-pointer check */
1471 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1472 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1473 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1474 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1475 emit_store_dst(jd, iptr, d);
1479 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1481 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1482 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1483 /* implicit null-pointer check */
1484 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1485 M_AADD(s2, s1, REG_ITMP1);
1486 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1487 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1490 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1491 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1494 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1495 /* implicit null-pointer check */
1496 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1497 M_AADD(s2, s1, REG_ITMP1);
1498 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1499 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1500 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1503 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1507 /* implicit null-pointer check */
1508 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1509 M_ASLL_IMM(s2, 2, REG_ITMP2);
1510 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1511 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1512 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1515 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 /* implicit null-pointer check */
1520 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1521 M_ASLL_IMM(s2, 3, REG_ITMP2);
1522 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1523 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1524 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1527 case ICMD_FASTORE: /* ..., 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 M_ASLL_IMM(s2, 2, REG_ITMP2);
1534 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1535 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1536 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1539 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 /* implicit null-pointer check */
1544 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1545 M_ASLL_IMM(s2, 3, REG_ITMP2);
1546 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1547 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1548 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1552 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556 /* implicit null-pointer check */
1557 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1558 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1560 M_MOV(s1, REG_OUT0);
1561 M_MOV(s3, REG_OUT1);
1562 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1563 M_ALD(REG_ITMP3, REG_PV, disp);
1564 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1566 emit_exception_check(cd, iptr);
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1570 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1571 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1572 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1573 /* implicit null-pointer check */
1574 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1578 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1581 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1582 /* implicit null-pointer check */
1583 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1584 M_AADD(s2, s1, REG_ITMP1);
1585 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1588 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1589 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1592 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1593 /* implicit null-pointer check */
1594 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1595 M_AADD(s2, s1, REG_ITMP1);
1596 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1597 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1600 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1603 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1604 /* implicit null-pointer check */
1605 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1606 M_ASLL_IMM(s2, 2, REG_ITMP2);
1607 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1608 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1611 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1614 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1615 /* implicit null-pointer check */
1616 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1617 M_ASLL_IMM(s2, 3, REG_ITMP2);
1618 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1619 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1622 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1626 /* implicit null-pointer check */
1627 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1628 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1629 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1630 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1634 case ICMD_GETSTATIC: /* ... ==> ..., value */
1636 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1637 uf = iptr->sx.s23.s3.uf;
1638 fieldtype = uf->fieldref->parseddesc.fd->type;
1639 disp = dseg_add_unique_address(cd, uf);
1641 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1644 fi = iptr->sx.s23.s3.fmiref->p.field;
1645 fieldtype = fi->type;
1646 disp = dseg_add_address(cd, fi->value);
1648 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1649 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1652 M_ALD(REG_ITMP1, REG_PV, disp);
1654 switch (fieldtype) {
1656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1657 M_ILD_INTERN(d, REG_ITMP1, 0);
1660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1661 M_LDX_INTERN(d, REG_ITMP1, 0);
1664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1665 M_ALD_INTERN(d, REG_ITMP1, 0);
1668 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1669 M_FLD_INTERN(d, REG_ITMP1, 0);
1672 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1673 M_DLD_INTERN(d, REG_ITMP1, 0);
1676 emit_store_dst(jd, iptr, d);
1679 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1681 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1682 uf = iptr->sx.s23.s3.uf;
1683 fieldtype = uf->fieldref->parseddesc.fd->type;
1684 disp = dseg_add_unique_address(cd, uf);
1686 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1689 fi = iptr->sx.s23.s3.fmiref->p.field;
1690 fieldtype = fi->type;
1691 disp = dseg_add_address(cd, fi->value);
1693 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1694 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1697 M_ALD(REG_ITMP1, REG_PV, disp);
1699 switch (fieldtype) {
1701 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1702 M_IST_INTERN(s1, REG_ITMP1, 0);
1705 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1706 M_STX_INTERN(s1, REG_ITMP1, 0);
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1710 M_AST_INTERN(s1, REG_ITMP1, 0);
1713 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1714 M_FST_INTERN(s1, REG_ITMP1, 0);
1717 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1718 M_DST_INTERN(s1, REG_ITMP1, 0);
1723 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1724 /* val = value (in current instruction) */
1725 /* following NOP) */
1727 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1728 uf = iptr->sx.s23.s3.uf;
1729 fieldtype = uf->fieldref->parseddesc.fd->type;
1730 disp = dseg_add_unique_address(cd, uf);
1732 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1735 fi = iptr->sx.s23.s3.fmiref->p.field;
1736 fieldtype = fi->type;
1737 disp = dseg_add_address(cd, fi->value);
1739 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1740 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1743 M_ALD(REG_ITMP1, REG_PV, disp);
1745 switch (fieldtype) {
1747 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1750 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1753 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1756 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1759 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1765 case ICMD_GETFIELD: /* ... ==> ..., value */
1767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1768 emit_nullpointer_check(cd, iptr, s1);
1770 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1771 uf = iptr->sx.s23.s3.uf;
1773 fieldtype = uf->fieldref->parseddesc.fd->type;
1776 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1779 fi = iptr->sx.s23.s3.fmiref->p.field;
1780 fieldtype = fi->type;
1784 switch (fieldtype) {
1786 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1798 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1802 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1809 emit_store_dst(jd, iptr, d);
1812 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1815 emit_nullpointer_check(cd, iptr, s1);
1817 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1818 uf = iptr->sx.s23.s3.uf;
1819 fieldtype = uf->fieldref->parseddesc.fd->type;
1824 fi = iptr->sx.s23.s3.fmiref->p.field;
1825 fieldtype = fi->type;
1829 if (IS_INT_LNG_TYPE(fieldtype))
1830 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1832 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1834 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1835 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1837 switch (fieldtype) {
1839 M_IST(s2, s1, disp);
1842 M_STX(s2, s1, disp);
1845 M_AST(s2, s1, disp);
1848 M_FST(s2, s1, disp);
1851 M_DST(s2, s1, disp);
1859 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1860 /* val = value (in current instruction) */
1861 /* following NOP) */
1863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1864 emit_nullpointer_check(cd, iptr, s1);
1866 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1867 unresolved_field *uf = iptr->sx.s23.s3.uf;
1869 fieldtype = uf->fieldref->parseddesc.fd->type;
1871 codegen_addpatchref(cd, PATCHER_get_putfield,
1874 if (opt_showdisassemble) {
1882 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1884 fieldtype = fi->type;
1890 switch (fieldtype) {
1892 M_IST(REG_ZERO, s1, disp);
1895 M_STX(REG_ZERO, s1, disp);
1898 M_AST(REG_ZERO, s1, disp);
1901 M_FST(REG_ZERO, s1, disp);
1904 M_DST(REG_ZERO, s1, disp);
1910 /* branch operations **************************************************/
1912 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1915 M_INTMOVE(s1, REG_ITMP2_XPTR);
1917 #ifdef ENABLE_VERIFIER
1918 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1919 unresolved_class *uc = iptr->sx.s23.s2.uc;
1921 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1923 #endif /* ENABLE_VERIFIER */
1925 disp = dseg_add_functionptr(cd, asm_handle_exception);
1926 M_ALD(REG_ITMP1, REG_PV, disp);
1927 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1929 M_NOP; /* nop ensures that XPC is less than the end */
1930 /* of basic block */
1934 case ICMD_GOTO: /* ... ==> ... */
1935 case ICMD_RET: /* ... ==> ... */
1937 emit_br(cd, iptr->dst.block);
1941 case ICMD_JSR: /* ... ==> ... */
1943 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1947 case ICMD_IFNULL: /* ..., value ==> ... */
1948 case ICMD_IFNONNULL:
1950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1951 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1954 /* Note: int compares must not branch on the register directly. */
1955 /* Reason is, that register content is not 32-bit clean. */
1957 case ICMD_IFEQ: /* ..., value ==> ... */
1959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1961 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1962 M_CMP_IMM(s1, iptr->sx.val.i);
1965 ICONST(REG_ITMP2, iptr->sx.val.i);
1966 M_CMP(s1, REG_ITMP2);
1968 emit_beq(cd, iptr->dst.block);
1971 case ICMD_IFLT: /* ..., value ==> ... */
1973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1976 M_CMP_IMM(s1, iptr->sx.val.i);
1979 ICONST(REG_ITMP2, iptr->sx.val.i);
1980 M_CMP(s1, REG_ITMP2);
1982 emit_blt(cd, iptr->dst.block);
1985 case ICMD_IFLE: /* ..., value ==> ... */
1987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1989 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1990 M_CMP_IMM(s1, iptr->sx.val.i);
1993 ICONST(REG_ITMP2, iptr->sx.val.i);
1994 M_CMP(s1, REG_ITMP2);
1996 emit_ble(cd, iptr->dst.block);
1999 case ICMD_IFNE: /* ..., value ==> ... */
2001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2003 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2004 M_CMP_IMM(s1, iptr->sx.val.i);
2007 ICONST(REG_ITMP2, iptr->sx.val.i);
2008 M_CMP(s1, REG_ITMP2);
2010 emit_bne(cd, iptr->dst.block);
2013 case ICMD_IFGT: /* ..., value ==> ... */
2015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2017 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2018 M_CMP_IMM(s1, iptr->sx.val.i);
2021 ICONST(REG_ITMP2, iptr->sx.val.i);
2022 M_CMP(s1, REG_ITMP2);
2024 emit_bgt(cd, iptr->dst.block);
2027 case ICMD_IFGE: /* ..., value ==> ... */
2029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2031 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2032 M_CMP_IMM(s1, iptr->sx.val.i);
2035 ICONST(REG_ITMP2, iptr->sx.val.i);
2036 M_CMP(s1, REG_ITMP2);
2038 emit_bge(cd, iptr->dst.block);
2041 case ICMD_IF_LEQ: /* ..., value ==> ... */
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2044 if (iptr->sx.val.l == 0)
2045 emit_beqz(cd, iptr->dst.block, s1);
2047 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2048 M_CMP_IMM(s1, iptr->sx.val.l);
2051 LCONST(REG_ITMP2, iptr->sx.val.l);
2052 M_CMP(s1, REG_ITMP2);
2054 emit_beq_xcc(cd, iptr->dst.block);
2058 case ICMD_IF_LLT: /* ..., value ==> ... */
2060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2061 if (iptr->sx.val.l == 0)
2062 emit_bltz(cd, iptr->dst.block, s1);
2064 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2065 M_CMP_IMM(s1, iptr->sx.val.l);
2068 LCONST(REG_ITMP2, iptr->sx.val.l);
2069 M_CMP(s1, REG_ITMP2);
2071 emit_blt_xcc(cd, iptr->dst.block);
2075 case ICMD_IF_LLE: /* ..., value ==> ... */
2077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2078 if (iptr->sx.val.l == 0)
2079 emit_blez(cd, iptr->dst.block, s1);
2081 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2082 M_CMP_IMM(s1, iptr->sx.val.l);
2085 LCONST(REG_ITMP2, iptr->sx.val.l);
2086 M_CMP(s1, REG_ITMP2);
2088 emit_ble_xcc(cd, iptr->dst.block);
2092 case ICMD_IF_LNE: /* ..., value ==> ... */
2094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2095 if (iptr->sx.val.l == 0)
2096 emit_bnez(cd, iptr->dst.block, s1);
2098 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2099 M_CMP_IMM(s1, iptr->sx.val.l);
2102 LCONST(REG_ITMP2, iptr->sx.val.l);
2103 M_CMP(s1, REG_ITMP2);
2105 emit_bne_xcc(cd, iptr->dst.block);
2109 case ICMD_IF_LGT: /* ..., value ==> ... */
2111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2112 if (iptr->sx.val.l == 0)
2113 emit_bgtz(cd, iptr->dst.block, s1);
2115 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2116 M_CMP_IMM(s1, iptr->sx.val.l);
2119 LCONST(REG_ITMP2, iptr->sx.val.l);
2120 M_CMP(s1, REG_ITMP2);
2122 emit_bgt_xcc(cd, iptr->dst.block);
2126 case ICMD_IF_LGE: /* ..., value ==> ... */
2128 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2129 if (iptr->sx.val.l == 0)
2130 emit_bgez(cd, iptr->dst.block, s1);
2132 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2133 M_CMP_IMM(s1, iptr->sx.val.l);
2136 LCONST(REG_ITMP2, iptr->sx.val.l);
2137 M_CMP(s1, REG_ITMP2);
2139 emit_bge_xcc(cd, iptr->dst.block);
2144 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2145 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2148 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2150 emit_beq_xcc(cd, iptr->dst.block);
2153 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2156 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2158 emit_beq(cd, iptr->dst.block);
2161 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2162 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2167 emit_bne_xcc(cd, iptr->dst.block);
2170 case ICMD_IF_ICMPNE: /* 32-bit compare */
2172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2173 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2175 emit_bne(cd, iptr->dst.block);
2178 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2181 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2183 emit_blt_xcc(cd, iptr->dst.block);
2186 case ICMD_IF_ICMPLT: /* 32-bit compare */
2188 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2189 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2191 emit_blt(cd, iptr->dst.block);
2194 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2196 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2197 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2199 emit_bgt_xcc(cd, iptr->dst.block);
2202 case ICMD_IF_ICMPGT: /* 32-bit compare */
2204 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2205 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2207 emit_bgt(cd, iptr->dst.block);
2210 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2213 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2215 emit_ble_xcc(cd, iptr->dst.block);
2218 case ICMD_IF_ICMPLE: /* 32-bit compare */
2220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2221 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2223 emit_ble(cd, iptr->dst.block);
2227 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2230 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2232 emit_bge_xcc(cd, iptr->dst.block);
2235 case ICMD_IF_ICMPGE: /* 32-bit compare */
2237 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2238 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2240 emit_bge(cd, iptr->dst.block);
2244 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2247 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2248 M_INTMOVE(s1, REG_RESULT_CALLEE);
2249 goto nowperformreturn;
2251 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2253 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2254 M_INTMOVE(s1, REG_RESULT_CALLEE);
2256 #ifdef ENABLE_VERIFIER
2257 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2258 unresolved_class *uc = iptr->sx.s23.s2.uc;
2260 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2262 #endif /* ENABLE_VERIFIER */
2263 goto nowperformreturn;
2265 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2268 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2269 M_DBLMOVE(s1, REG_FRESULT);
2270 goto nowperformreturn;
2272 case ICMD_RETURN: /* ... ==> ... */
2278 p = cd->stackframesize;
2280 #if !defined(NDEBUG)
2281 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2282 emit_verbosecall_exit(jd);
2285 #if defined(ENABLE_THREADS)
2286 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2287 /* XXX jit-c-call */
2288 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2289 M_ALD(REG_ITMP3, REG_PV, disp);
2291 /* we need to save fp return value (int saved by window) */
2293 switch (iptr->opc) {
2296 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2297 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2298 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2300 /* restore the fp return value */
2302 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2308 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2309 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2320 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2326 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2329 branch_target_t *table;
2331 table = iptr->dst.table;
2333 l = iptr->sx.s23.s2.tablelow;
2334 i = iptr->sx.s23.s3.tablehigh;
2336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2338 M_INTMOVE(s1, REG_ITMP1);
2340 else if (-l >= 4096 && -l <= 4095) {
2341 M_ADD_IMM(s1, -l, REG_ITMP1);
2344 ICONST(REG_ITMP2, l);
2345 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2348 i = i - l + 1; /* number of targets (>0) */
2354 M_CMP_IMM(REG_ITMP1, i - 1);
2357 ICONST(REG_ITMP2, i - 1);
2358 M_CMP(REG_ITMP1, REG_ITMP2);
2360 emit_bugt(cd, table[0].block); /* default target */
2362 /* build jump table top down and use address of lowest entry */
2367 dseg_add_target(cd, table->block);
2372 /* length of dataseg after last dseg_addtarget is used by load */
2374 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2375 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2376 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2377 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2382 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2385 lookup_target_t *lookup;
2387 lookup = iptr->dst.lookup;
2389 i = iptr->sx.s23.s2.lookupcount;
2391 MCODECHECK((i<<2)+8);
2392 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2395 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2396 M_CMP_IMM(s1, lookup->value);
2398 ICONST(REG_ITMP2, lookup->value);
2399 M_CMP(s1, REG_ITMP2);
2401 emit_beq(cd, lookup->target.block);
2405 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2411 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2413 bte = iptr->sx.s23.s3.bte;
2416 /* XXX: builtin calling with stack arguments not implemented */
2417 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2419 s3 = md->paramcount;
2421 MCODECHECK((s3 << 1) + 64);
2423 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2425 /* copy float arguments according to ABI convention */
2427 int num_fltregargs = 0;
2428 int fltregarg_inswap[16];
2430 for (s3 = s3 - 1; s3 >= 0; s3--) {
2431 var = VAR(iptr->sx.s23.s2.args[s3]);
2433 if (IS_FLT_DBL_TYPE(var->type)) {
2434 if (!md->params[s3].inmemory) {
2435 s1 = s3; /*native flt args use argument index directly*/
2436 d = emit_load(jd, iptr, var, REG_FTMP1);
2439 fltregarg_inswap[num_fltregargs] = s1;
2441 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2450 /* move swapped float args to target regs */
2451 for (i = 0; i < num_fltregargs; i++) {
2452 s1 = fltregarg_inswap[i];
2453 M_DMOV(s1 + 16, s1);
2454 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2458 assert(md->argfltreguse == 0);
2463 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2465 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2466 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2467 case ICMD_INVOKEINTERFACE:
2469 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2471 um = iptr->sx.s23.s3.um;
2472 md = um->methodref->parseddesc.md;
2475 lm = iptr->sx.s23.s3.fmiref->p.method;
2477 md = lm->parseddesc;
2481 s3 = md->paramcount;
2483 MCODECHECK((s3 << 1) + 64);
2485 /* copy arguments to registers or stack location */
2487 for (s3 = s3 - 1; s3 >= 0; s3--) {
2488 var = VAR(iptr->sx.s23.s2.args[s3]);
2489 d = md->params[s3].regoff;
2491 if (var->flags & PREALLOC)
2494 if (IS_INT_LNG_TYPE(var->type)) {
2495 if (!md->params[s3].inmemory) {
2496 s1 = emit_load(jd, iptr, var, d);
2500 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2501 M_STX(s1, REG_SP, JITSTACK + d);
2505 #ifdef BUILTIN_FLOAT_ARGS
2506 if (iptr->opc == ICMD_BUILTIN)
2510 if (!md->params[s3].inmemory) {
2511 s1 = emit_load(jd, iptr, var, d);
2512 if (IS_2_WORD_TYPE(var->type))
2518 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2519 M_DST(s1, REG_SP, JITSTACK + d);
2524 switch (iptr->opc) {
2526 disp = dseg_add_functionptr(cd, bte->fp);
2528 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2530 /* XXX jit-c-call */
2531 /* generate the actual call */
2533 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2535 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2536 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2537 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2539 emit_exception_check(cd, iptr);
2540 if (md->returntype.type == TYPE_FLT) {
2541 /* special handling for float return value in %f0 */
2546 case ICMD_INVOKESPECIAL:
2547 emit_nullpointer_check(cd, iptr, REG_OUT0);
2550 case ICMD_INVOKESTATIC:
2552 disp = dseg_add_unique_address(cd, NULL);
2554 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2558 disp = dseg_add_address(cd, lm->stubroutine);
2560 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
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_INVOKEVIRTUAL:
2572 emit_nullpointer_check(cd, iptr, REG_OUT0);
2575 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2580 s1 = OFFSET(vftbl_t, table[0]) +
2581 sizeof(methodptr) * lm->vftblindex;
2583 /* implicit null-pointer check */
2584 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2585 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2587 /* generate the actual call */
2589 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2591 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2592 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2593 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2596 case ICMD_INVOKEINTERFACE:
2597 emit_nullpointer_check(cd, iptr, REG_OUT0);
2600 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2606 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2607 sizeof(methodptr*) * lm->class->index;
2609 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2612 /* implicit null-pointer check */
2613 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2614 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2615 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2617 /* generate the actual call */
2619 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2621 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2622 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2623 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2627 /* store return value */
2629 d = md->returntype.type;
2631 if (d != TYPE_VOID) {
2632 if (IS_INT_LNG_TYPE(d)) {
2633 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2634 M_INTMOVE(REG_RESULT_CALLER, s1);
2637 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2638 if (IS_2_WORD_TYPE(d)) {
2639 M_DBLMOVE(REG_FRESULT, s1);
2641 M_FLTMOVE(REG_FRESULT, s1);
2644 emit_store_dst(jd, iptr, s1);
2649 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2650 /* val.a: (classinfo*) superclass */
2652 /* superclass is an interface:
2654 * OK if ((sub == NULL) ||
2655 * (sub->vftbl->interfacetablelength > super->index) &&
2656 * (sub->vftbl->interfacetable[-super->index] != NULL));
2658 * superclass is a class:
2660 * OK if ((sub == NULL) || (0
2661 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2662 * super->vftbl->diffvall));
2665 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2669 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2674 super = iptr->sx.s23.s3.c.cls;
2675 superindex = super->index;
2678 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2679 CODEGEN_CRITICAL_SECTION_NEW;
2681 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2683 /* if class is not resolved, check which code to call */
2685 if (super == NULL) {
2686 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2688 cr = iptr->sx.s23.s3.c.ref;
2689 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2691 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2694 M_ILD(REG_ITMP2, REG_PV, disp);
2695 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2696 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2699 /* interface checkcast code */
2701 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2702 if (super == NULL) {
2703 cr = iptr->sx.s23.s3.c.ref;
2705 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2709 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2712 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2713 M_ILD(REG_ITMP3, REG_ITMP2,
2714 OFFSET(vftbl_t, interfacetablelength));
2715 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2716 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2718 M_ALD(REG_ITMP3, REG_ITMP2,
2719 OFFSET(vftbl_t, interfacetable[0]) -
2720 superindex * sizeof(methodptr*));
2721 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2724 emit_label_br(cd, BRANCH_LABEL_4);
2726 emit_label(cd, BRANCH_LABEL_3);
2729 /* class checkcast code */
2731 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2732 if (super == NULL) {
2733 emit_label(cd, BRANCH_LABEL_2);
2735 cr = iptr->sx.s23.s3.c.ref;
2736 disp = dseg_add_unique_address(cd, NULL);
2738 codegen_add_patch_ref(cd,
2739 PATCHER_checkcast_instanceof_class,
2743 disp = dseg_add_address(cd, super->vftbl);
2745 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2748 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2749 M_ALD(REG_ITMP3, REG_PV, disp);
2751 CODEGEN_CRITICAL_SECTION_START;
2753 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2754 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2755 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2756 M_ALD(REG_ITMP3, REG_PV, disp);
2757 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2759 CODEGEN_CRITICAL_SECTION_END;
2762 M_CMP(REG_ITMP3, REG_ITMP2);
2763 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2766 emit_label(cd, BRANCH_LABEL_5);
2769 if (super == NULL) {
2770 emit_label(cd, BRANCH_LABEL_1);
2771 emit_label(cd, BRANCH_LABEL_4);
2774 d = codegen_reg_of_dst(jd, iptr, s1);
2777 /* array type cast-check */
2779 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2780 M_INTMOVE(s1, REG_OUT0);
2782 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2784 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2785 cr = iptr->sx.s23.s3.c.ref;
2786 disp = dseg_add_unique_address(cd, NULL);
2788 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2792 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2794 M_ALD(REG_OUT1, REG_PV, disp);
2795 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2796 M_ALD(REG_ITMP3, REG_PV, disp);
2797 /* XXX jit-c-call */
2798 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2802 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2804 d = codegen_reg_of_dst(jd, iptr, s1);
2808 emit_store_dst(jd, iptr, d);
2811 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2812 /* val.a: (classinfo*) superclass */
2814 /* superclass is an interface:
2816 * return (sub != NULL) &&
2817 * (sub->vftbl->interfacetablelength > super->index) &&
2818 * (sub->vftbl->interfacetable[-super->index] != NULL);
2820 * superclass is a class:
2822 * return ((sub != NULL) && (0
2823 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2824 * super->vftbl->diffvall));
2829 vftbl_t *supervftbl;
2832 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2838 super = iptr->sx.s23.s3.c.cls;
2839 superindex = super->index;
2840 supervftbl = super->vftbl;
2843 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2844 CODEGEN_CRITICAL_SECTION_NEW;
2846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2849 M_MOV(s1, REG_ITMP1);
2855 /* if class is not resolved, check which code to call */
2857 if (super == NULL) {
2858 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2860 cr = iptr->sx.s23.s3.c.ref;
2861 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2863 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2866 M_ILD(REG_ITMP3, REG_PV, disp);
2867 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2868 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2871 /* interface instanceof code */
2873 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2874 if (super == NULL) {
2875 cr = iptr->sx.s23.s3.c.ref;
2877 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2881 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2884 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2885 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2886 M_CMP_IMM(REG_ITMP3, superindex);
2889 M_ALD(REG_ITMP1, REG_ITMP1,
2890 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2891 superindex * sizeof(methodptr*)));
2892 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2895 emit_label_br(cd, BRANCH_LABEL_4);
2897 emit_label(cd, BRANCH_LABEL_3);
2900 /* class instanceof code */
2902 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2903 if (super == NULL) {
2904 emit_label(cd, BRANCH_LABEL_2);
2906 cr = iptr->sx.s23.s3.c.ref;
2907 disp = dseg_add_unique_address(cd, NULL);
2909 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2913 disp = dseg_add_address(cd, supervftbl);
2915 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2918 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2919 M_ALD(REG_ITMP2, REG_PV, disp);
2921 CODEGEN_CRITICAL_SECTION_START;
2923 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2924 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2925 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2927 CODEGEN_CRITICAL_SECTION_END;
2929 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2930 M_CMP(REG_ITMP1, REG_ITMP2);
2931 M_XCMOVULE_IMM(1, d);
2934 emit_label(cd, BRANCH_LABEL_5);
2937 if (super == NULL) {
2938 emit_label(cd, BRANCH_LABEL_1);
2939 emit_label(cd, BRANCH_LABEL_4);
2942 emit_store_dst(jd, iptr, d);
2946 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2948 /* check for negative sizes and copy sizes to stack if necessary */
2950 MCODECHECK((iptr->s1.argcount << 1) + 64);
2952 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2954 var = VAR(iptr->sx.s23.s2.args[s1]);
2956 /* copy SAVEDVAR sizes to stack */
2958 /* Already Preallocated? */
2960 if (!(var->flags & PREALLOC)) {
2961 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2962 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2966 /* arg 0 = dimension count */
2968 ICONST(REG_OUT0, iptr->s1.argcount);
2970 /* is patcher function set? */
2972 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2973 disp = dseg_add_unique_address(cd, 0);
2975 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2976 iptr->sx.s23.s3.c.ref,
2980 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2982 /* arg 1 = arraydescriptor */
2984 M_ALD(REG_OUT1, REG_PV, disp);
2986 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2988 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2990 /* XXX c abi call */
2991 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2992 M_ALD(REG_ITMP3, REG_PV, disp);
2993 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2996 /* check for exception before result assignment */
2998 emit_exception_check(cd, iptr);
3000 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
3001 M_INTMOVE(REG_RESULT_CALLER, d);
3002 emit_store_dst(jd, iptr, d);
3006 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3012 } /* for instruction */
3016 /* At the end of a basic block we may have to append some nops,
3017 because the patcher stub calling code might be longer than the
3018 actual instruction. So codepatching does not change the
3019 following block unintentionally. */
3021 if (cd->mcodeptr < cd->lastmcodeptr) {
3022 while (cd->mcodeptr < cd->lastmcodeptr) {
3027 } /* if (bptr -> flags >= BBREACHED) */
3028 } /* for basic block */
3030 dseg_createlinenumbertable(cd);
3032 /* generate stubs */
3034 emit_patcher_stubs(jd);
3036 /* everything's ok */
3042 /* codegen_emit_stub_compiler **************************************************
3044 Emits a stub routine which calls the compiler.
3046 *******************************************************************************/
3048 void codegen_emit_stub_compiler(jitdata *jd)
3053 /* get required compiler data */
3058 /* code for the stub */
3060 /* no window save yet, user caller's PV */
3061 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3062 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3063 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3068 /* codegen_emit_stub_native ****************************************************
3070 Emits a stub routine which calls a native method.
3072 *******************************************************************************/
3074 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3081 s4 i, j; /* count variables */
3084 s4 funcdisp; /* displacement of the function */
3085 s4 fltregarg_offset[FLT_ARG_CNT];
3087 /* get required compiler data */
3093 /* initialize variables */
3096 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3098 /* calculate stack frame size */
3100 cd->stackframesize =
3101 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3102 sizeof(localref_table) / SIZEOF_VOID_P +
3103 md->paramcount + /* for saving arguments over calls */
3104 nmd->memuse + /* nmd->memuse includes the (6) abi params */
3108 /* keep stack 16-byte aligned (ABI requirement) */
3110 if (cd->stackframesize & 1)
3111 cd->stackframesize++;
3113 /* create method header */
3115 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3116 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3117 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3118 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3119 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3120 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3121 (void) dseg_addlinenumbertablesize(cd);
3122 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3124 /* generate stub code */
3126 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3128 #if !defined(NDEBUG)
3129 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3130 emit_verbosecall_enter(jd);
3133 /* get function address (this must happen before the stackframeinfo) */
3135 funcdisp = dseg_add_functionptr(cd, f);
3137 #if !defined(WITH_STATIC_CLASSPATH)
3139 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3143 /* save float argument registers */
3145 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3147 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3148 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3149 s1 = WINSAVE_CNT + nmd->memuse + j;
3150 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3151 fltregarg_offset[i] = s1; /* remember stack offset */
3156 /* prepare data structures for native function call */
3158 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3159 M_MOV(REG_PV_CALLEE, REG_OUT1);
3160 M_MOV(REG_FP, REG_OUT2); /* java sp */
3161 M_MOV(REG_RA_CALLEE, REG_OUT3);
3162 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3163 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3164 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3165 M_NOP; /* XXX fill me! */
3167 /* keep float arguments on stack */
3169 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3170 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3171 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3177 /* copy or spill arguments to new locations */
3179 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3180 t = md->paramtypes[i].type;
3182 if (IS_INT_LNG_TYPE(t)) {
3184 /* integral types */
3186 if (!md->params[i].inmemory) {
3187 s1 = md->params[i].regoff;
3188 /* s1 refers to the old window, transpose */
3189 s1 = REG_WINDOW_TRANSPOSE(s1);
3191 if (!nmd->params[j].inmemory) {
3192 s2 = nmd->params[j].regoff;
3195 /* nmd's regoff is relative to the start of the param array */
3196 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3197 M_AST(s1, REG_SP, s2);
3201 if (!nmd->params[j].inmemory) {
3202 /* JIT stack arg -> NAT reg arg */
3204 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3205 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3207 assert(false); /* path never taken */
3210 s1 = md->params[i].regoff + cd->stackframesize * 8;
3211 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3212 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3213 M_AST(REG_ITMP1, REG_SP, s2);
3218 /* floating point types */
3220 if (!md->params[i].inmemory) {
3221 s1 = md->params[i].regoff;
3223 if (!nmd->params[j].inmemory) {
3225 /* no mapping to regs needed, native flt args use regoff */
3226 s2 = nmd->params[j].regoff;
3228 /* JIT float regs are still on the stack */
3229 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3232 /* not supposed to happen with 16 NAT flt args */
3235 s2 = nmd->params[j].regoff;
3236 if (IS_2_WORD_TYPE(t))
3237 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3239 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3245 s1 = md->params[i].regoff;
3247 if (!nmd->params[j].inmemory) {
3249 /* JIT stack -> NAT reg */
3251 s2 = nmd->params[j].regoff;
3252 M_DLD(s2, REG_FP, JITSTACK + s1);
3256 /* JIT stack -> NAT stack */
3258 s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3260 /* The FTMP register may already be loaded with args */
3261 /* we know $f0 is unused because of the env pointer */
3262 M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3263 M_DST(REG_F0, REG_SP, BIAS + s2);
3270 /* put class into second argument register */
3272 if (m->flags & ACC_STATIC) {
3273 disp = dseg_add_address(cd, m->class);
3274 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3277 /* put env into first argument register */
3279 disp = dseg_add_address(cd, _Jv_env);
3280 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3282 /* do the native function call */
3284 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3285 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3286 M_NOP; /* delay slot */
3288 /* save return value */
3290 if (md->returntype.type != TYPE_VOID) {
3291 if (IS_INT_LNG_TYPE(md->returntype.type))
3292 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3294 M_DST(REG_FRESULT, REG_SP, CSTACK);
3297 /* Note: native functions return float values in %f0 (see ABI) */
3298 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3300 #if !defined(NDEBUG)
3301 /* But for the trace function we need to put a flt result into %f1 */
3302 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3303 if (!IS_2_WORD_TYPE(md->returntype.type))
3304 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3305 emit_verbosecall_exit(jd);
3309 /* remove native stackframe info */
3311 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3312 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3313 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3314 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3315 M_NOP; /* XXX fill me! */
3316 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3318 /* restore float return value, int return value already in our return reg */
3320 if (md->returntype.type != TYPE_VOID) {
3321 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3322 if (IS_2_WORD_TYPE(md->returntype.type))
3323 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3325 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3329 /* check for exception */
3330 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3333 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3336 /* handle exception */
3338 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3339 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3340 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3341 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3342 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3344 /* generate patcher stubs */
3346 emit_patcher_stubs(jd);
3350 * These are local overrides for various environment variables in Emacs.
3351 * Please do not remove this and leave it at the end of the file, where
3352 * Emacs will automagically detect them.
3353 * ---------------------------------------------------------------------
3356 * indent-tabs-mode: t
3360 * vim:noexpandtab:sw=4:ts=4: