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 check = imm & ~0x1fff;
106 if (check == 0) return true; /* pos imm. */
107 if (check + 0x1fff == -1) return true; /* neg imm. */
109 printf("immediate out-of-bounds: %d\n", imm);
115 /* codegen_emit ****************************************************************
117 Generates machine code.
119 *******************************************************************************/
121 bool codegen_emit(jitdata *jd)
127 s4 len, s1, s2, s3, d, disp, slots;
133 constant_classref *cr;
134 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
135 unresolved_method *um;
136 builtintable_entry *bte;
139 unresolved_field *uf;
143 /* get required compiler data */
150 /* prevent compiler warnings */
162 #if 0 /* no leaf optimization yet */
163 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
165 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
168 /* space to save used callee saved registers */
170 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
171 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
173 cd->stackframesize = rd->memuse + savedregs_num;
175 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
176 if (checksync && (m->flags & ACC_SYNCHRONIZED))
177 cd->stackframesize++;
180 /* keep stack 16-byte aligned (ABI requirement) */
182 if (cd->stackframesize & 1)
183 cd->stackframesize++;
185 /* create method header */
187 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
188 framesize_disp = dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
190 #if defined(ENABLE_THREADS)
191 /* IsSync contains the offset relative to the stack pointer for the
192 argument of monitor_exit used in the exception handler. Since the
193 offset could be zero and give a wrong meaning of the flag it is
197 if (checksync && (m->flags & ACC_SYNCHRONIZED))
198 (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
201 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
203 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
204 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
205 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
206 dseg_addlinenumbertablesize(cd);
207 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
209 /* create exception table */
211 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
212 dseg_add_target(cd, ex->start);
213 dseg_add_target(cd, ex->end);
214 dseg_add_target(cd, ex->handler);
215 (void) dseg_add_unique_address(cd, ex->catchtype.any);
218 /* save register window and create stack frame (if necessary) */
220 if (cd->stackframesize) {
221 if (cd->stackframesize <= 4095)
222 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
224 M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
225 M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
226 M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
230 /* save callee saved float registers (none right now) */
232 p = cd->stackframesize;
233 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
234 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
239 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
240 emit_verbosecall_enter(jd);
244 /* call monitorenter function */
245 #if defined(ENABLE_THREADS)
246 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
247 /* stack offset for monitor argument */
251 /* save float argument registers */
255 ALIGN_STACK_SLOTS(slots);
257 M_LDA(REG_SP, REG_SP, -(slots * 8));
258 for (i = 0; i < FLT_ARG_CNT; i++)
259 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
263 /* get correct lock object */
265 if (m->flags & ACC_STATIC) {
266 disp = dseg_add_address(cd, &m->class->object.header);
267 M_ALD(REG_OUT0, REG_PV, disp);
268 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
269 M_ALD(REG_ITMP3, REG_PV, disp);
272 /* copy class pointer: $i0 -> $o0 */
273 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
275 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
276 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
277 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
280 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
281 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
283 /* restore float argument registers */
285 for (i = 0; i < FLT_ARG_CNT; i++)
286 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
288 M_LDA(REG_SP, REG_SP, slots * 8);
293 /* take arguments out of register or stack frame */
297 for (p = 0, l = 0; p < md->paramcount; p++) {
298 t = md->paramtypes[p].type;
300 varindex = jd->local_map[l * 5 + t];
303 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
306 if (varindex == UNUSED)
310 s1 = md->params[p].regoff;
312 if (IS_INT_LNG_TYPE(t)) { /* integer args */
316 if (!md->params[p].inmemory) { /* register arguments */
317 s1 = REG_WINDOW_TRANSPOSE(s1);
319 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
321 /* the register allocator does not know about the window. */
322 /* avoid copying the locals from save to save regs by */
323 /* swapping variables. */
326 int old_dest = var->vv.regoff;
327 int new_dest = p + 24;
329 /* run through all variables */
331 for (i = 0; i < jd->varcount; i++) {
332 varinfo* uvar = VAR(i);
334 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
337 s2 = uvar->vv.regoff;
339 /* free the in reg by moving all other references */
341 if (s2 == new_dest) {
342 uvar->vv.regoff = old_dest;
343 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
346 /* move all variables to the in reg */
348 if (s2 == old_dest) {
349 uvar->vv.regoff = new_dest;
350 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
358 else { /* reg arg -> spilled */
359 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
362 } else { /* stack arguments */
363 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
364 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
366 } else { /* stack arg -> spilled */
367 /* add the callers window save registers */
368 var->vv.regoff = cd->stackframesize * 8 + s1;
372 } else { /* floating args */
373 if (!md->params[p].inmemory) { /* register arguments */
374 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
375 M_FLTMOVE(s1, var->vv.regoff);
377 } else { /* reg arg -> spilled */
378 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
381 } else { /* stack arguments */
382 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
383 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
385 } else { /* stack-arg -> spilled */
386 var->vv.regoff = cd->stackframesize * 8 + s1;
395 /* end of header generation */
397 /* create replacement points */
399 REPLACEMENT_POINTS_INIT(cd, jd);
401 /* walk through all basic blocks */
403 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
405 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
407 if (bptr->flags >= BBREACHED) {
409 /* branch resolving */
411 codegen_resolve_branchrefs(cd, bptr);
413 /* handle replacement points */
416 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
417 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
423 /* copy interface registers to their destination */
428 #if defined(ENABLE_LSRA)
429 #error XXX LSRA not tested yet
433 src = bptr->invars[len];
434 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
435 /* d = reg_of_var(m, src, REG_ITMP1); */
436 if (!(src->flags & INMEMORY))
440 M_INTMOVE(REG_ITMP1, d);
441 emit_store(jd, NULL, src, d);
448 var = VAR(bptr->invars[len]);
449 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
450 d = codegen_reg_of_var(0, var, REG_ITMP1);
451 M_INTMOVE(REG_ITMP2_XPTR, d);
452 emit_store(jd, NULL, var, d);
455 assert((var->flags & INOUT));
458 #if defined(ENABLE_LSRA)
461 /* walk through all instructions */
465 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
466 if (iptr->line != currentline) {
467 dseg_addlinenumber(cd, iptr->line);
468 currentline = iptr->line;
471 MCODECHECK(64); /* an instruction usually needs < 64 words */
475 case ICMD_INLINE_START:
476 case ICMD_INLINE_END:
479 case ICMD_NOP: /* ... ==> ... */
482 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
485 emit_nullpointer_check(cd, iptr, s1);
488 /* constant operations ************************************************/
490 case ICMD_ICONST: /* ... ==> ..., constant */
492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
493 ICONST(d, iptr->sx.val.i);
494 emit_store_dst(jd, iptr, d);
497 case ICMD_LCONST: /* ... ==> ..., constant */
499 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
500 LCONST(d, iptr->sx.val.l);
501 emit_store_dst(jd, iptr, d);
504 case ICMD_FCONST: /* ... ==> ..., constant */
506 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
507 disp = dseg_add_float(cd, iptr->sx.val.f);
508 M_FLD(d, REG_PV, disp);
509 emit_store_dst(jd, iptr, d);
512 case ICMD_DCONST: /* ... ==> ..., constant */
514 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
515 disp = dseg_add_double(cd, iptr->sx.val.d);
516 M_DLD(d, REG_PV, disp);
517 emit_store_dst(jd, iptr, d);
520 case ICMD_ACONST: /* ... ==> ..., constant */
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
524 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
525 cr = iptr->sx.val.c.ref;
526 disp = dseg_add_unique_address(cd, cr);
528 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
530 M_ALD(d, REG_PV, disp);
534 if (iptr->sx.val.anyptr == NULL) {
535 M_INTMOVE(REG_ZERO, d);
538 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
539 M_ALD(d, REG_PV, disp);
542 emit_store_dst(jd, iptr, d);
546 /* load/store/copy/move operations ************************************/
548 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
553 case ICMD_ISTORE: /* ..., value ==> ... */
564 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
569 /* pop/dup/swap operations ********************************************/
571 /* attention: double and longs are only one entry in CACAO ICMDs */
573 case ICMD_POP: /* ..., value ==> ... */
574 case ICMD_POP2: /* ..., value, value ==> ... */
578 /* integer operations *************************************************/
580 case ICMD_INEG: /* ..., value ==> ..., - value */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
585 M_SUB(REG_ZERO, s1, d);
586 emit_store_dst(jd, iptr, d);
589 case ICMD_I2L: /* ..., value ==> ..., value */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
594 emit_store_dst(jd, iptr, d);
597 case ICMD_L2I: /* ..., value ==> ..., value */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
601 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
602 emit_store_dst(jd, iptr, d);
605 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
609 M_SLLX_IMM(s1, 56, d);
610 M_SRAX_IMM( d, 56, d);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618 M_SLLX_IMM(s1, 48, d);
619 M_SRLX_IMM( d, 48, d);
620 emit_store_dst(jd, iptr, d);
623 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 M_SLLX_IMM(s1, 48, d);
628 M_SRAX_IMM( d, 48, d);
629 emit_store_dst(jd, iptr, d);
632 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
635 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
636 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
639 emit_store_dst(jd, iptr, d);
643 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
644 /* sx.val.i = constant */
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
648 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
649 M_ADD_IMM(s1, iptr->sx.val.i, d);
651 ICONST(REG_ITMP2, iptr->sx.val.i);
652 M_ADD(s1, REG_ITMP2, d);
654 emit_store_dst(jd, iptr, d);
657 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
658 /* sx.val.l = constant */
660 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
661 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
662 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
663 M_ADD_IMM(s1, iptr->sx.val.l, d);
665 LCONST(REG_ITMP2, iptr->sx.val.l);
666 M_ADD(s1, REG_ITMP2, d);
668 emit_store_dst(jd, iptr, d);
671 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
678 emit_store_dst(jd, iptr, d);
681 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
682 /* sx.val.i = constant */
684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
686 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
687 M_SUB_IMM(s1, iptr->sx.val.i, d);
689 ICONST(REG_ITMP2, iptr->sx.val.i);
690 M_SUB(s1, REG_ITMP2, d);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
696 /* sx.val.l = constant */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
701 M_SUB_IMM(s1, iptr->sx.val.l, d);
703 LCONST(REG_ITMP2, iptr->sx.val.l);
704 M_SUB(s1, REG_ITMP2, d);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
716 emit_store_dst(jd, iptr, d);
719 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
720 /* sx.val.i = constant */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
724 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
725 M_MULX_IMM(s1, iptr->sx.val.i, d);
727 ICONST(REG_ITMP2, iptr->sx.val.i);
728 M_MULX(s1, REG_ITMP2, d);
730 emit_store_dst(jd, iptr, d);
733 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
734 /* sx.val.l = constant */
736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
737 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
738 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
739 M_MULX_IMM(s1, iptr->sx.val.l, d);
741 LCONST(REG_ITMP2, iptr->sx.val.l);
742 M_MULX(s1, REG_ITMP2, d);
744 emit_store_dst(jd, iptr, d);
747 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
748 /* XXX could also clear Y and use 32bit div */
749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
750 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752 emit_arithmetic_check(cd, iptr, s2);
754 /* XXX trim s2 like s1 ? */
756 emit_store_dst(jd, iptr, d);
759 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
762 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
763 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764 emit_arithmetic_check(cd, iptr, s2);
766 emit_store_dst(jd, iptr, d);
769 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
772 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
774 emit_arithmetic_check(cd, iptr, s2);
776 /* XXX trim s2 like s1 ? */
777 M_DIVX(s1, s2, REG_ITMP3);
778 M_MULX(s2, REG_ITMP3, REG_ITMP3);
779 M_SUB(s1, REG_ITMP3, d);
780 emit_store_dst(jd, iptr, d);
783 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
786 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
787 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
788 emit_arithmetic_check(cd, iptr, s2);
789 M_DIVX(s1, s2, REG_ITMP3);
790 M_MULX(s2, REG_ITMP3, REG_ITMP3);
791 M_SUB(s1, REG_ITMP3, d);
792 emit_store_dst(jd, iptr, d);
795 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
796 case ICMD_LDIVPOW2: /* val.i = constant */
798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
800 M_SRAX_IMM(s1, 63, REG_ITMP2);
801 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
802 M_ADD(s1, REG_ITMP2, REG_ITMP2);
803 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
822 emit_store_dst(jd, iptr, d);
825 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
826 /* val.i = constant */
828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
830 M_SLL_IMM(s1, iptr->sx.val.i, d);
831 emit_store_dst(jd, iptr, d);
834 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
835 /* val.i = constant */
837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
839 M_SLLX_IMM(s1, iptr->sx.val.i, d);
840 emit_store_dst(jd, iptr, d);
843 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
849 emit_store_dst(jd, iptr, d);
852 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
853 /* sx.val.i = constant */
855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
856 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
857 M_SRA_IMM(s1, iptr->sx.val.i, d);
858 emit_store_dst(jd, iptr, d);
861 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
864 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
867 emit_store_dst(jd, iptr, d);
870 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
871 /* sx.val.i = constant */
873 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
874 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
875 M_SRL_IMM(s1, iptr->sx.val.i, d);
876 emit_store_dst(jd, iptr, d);
879 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
883 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
885 emit_store_dst(jd, iptr, d);
888 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
889 /* sx.val.i = constant */
891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
893 M_SRAX_IMM(s1, iptr->sx.val.i, d);
894 emit_store_dst(jd, iptr, d);
897 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
901 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
903 emit_store_dst(jd, iptr, d);
906 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
907 /* sx.val.i = constant */
909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
910 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
911 M_SRLX_IMM(s1, iptr->sx.val.i, d);
912 emit_store_dst(jd, iptr, d);
915 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
919 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
920 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
926 /* sx.val.i = constant */
928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
929 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
930 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
931 M_AND_IMM(s1, iptr->sx.val.i, d);
933 ICONST(REG_ITMP2, iptr->sx.val.i);
934 M_AND(s1, REG_ITMP2, d);
936 emit_store_dst(jd, iptr, d);
939 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
940 /* sx.val.i = constant */
941 /* constant is actually constant - 1 */
943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
946 M_MOV(s1, REG_ITMP1);
949 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
950 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
951 M_AND_IMM(s1, iptr->sx.val.i, d);
954 M_SUB(REG_ZERO, s1, d);
955 M_AND_IMM(d, iptr->sx.val.i, d);
957 ICONST(REG_ITMP2, iptr->sx.val.i);
958 M_AND(s1, REG_ITMP2, d);
961 M_SUB(REG_ZERO, s1, d);
962 M_AND(d, REG_ITMP2, d);
964 M_SUB(REG_ZERO, d, d);
965 emit_store_dst(jd, iptr, d);
968 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
969 /* sx.val.l = constant */
971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
972 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
974 M_AND_IMM(s1, iptr->sx.val.l, d);
976 LCONST(REG_ITMP2, iptr->sx.val.l);
977 M_AND(s1, REG_ITMP2, d);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
983 /* sx.val.l = constant */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
988 M_MOV(s1, REG_ITMP1);
991 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
992 M_AND_IMM(s1, iptr->sx.val.l, d);
995 M_SUB(REG_ZERO, s1, d);
996 M_AND_IMM(d, iptr->sx.val.l, d);
998 LCONST(REG_ITMP2, iptr->sx.val.l);
999 M_AND(s1, REG_ITMP2, d);
1002 M_SUB(REG_ZERO, s1, d);
1003 M_AND(d, REG_ITMP2, d);
1005 M_SUB(REG_ZERO, d, d);
1006 emit_store_dst(jd, iptr, d);
1009 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1012 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1013 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1014 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 emit_store_dst(jd, iptr, d);
1019 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1020 /* sx.val.i = constant */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1024 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1025 M_OR_IMM(s1, iptr->sx.val.i, d);
1027 ICONST(REG_ITMP2, iptr->sx.val.i);
1028 M_OR(s1, REG_ITMP2, d);
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1034 /* sx.val.l = constant */
1036 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1038 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1039 M_OR_IMM(s1, iptr->sx.val.l, d);
1041 LCONST(REG_ITMP2, iptr->sx.val.l);
1042 M_OR(s1, REG_ITMP2, d);
1044 emit_store_dst(jd, iptr, d);
1047 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1052 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 emit_store_dst(jd, iptr, d);
1057 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1058 /* sx.val.i = constant */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1062 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1063 M_XOR_IMM(s1, iptr->sx.val.i, d);
1065 ICONST(REG_ITMP2, iptr->sx.val.i);
1066 M_XOR(s1, REG_ITMP2, d);
1068 emit_store_dst(jd, iptr, d);
1071 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1072 /* sx.val.l = constant */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1076 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1077 M_XOR_IMM(s1, iptr->sx.val.l, d);
1079 LCONST(REG_ITMP2, iptr->sx.val.l);
1080 M_XOR(s1, REG_ITMP2, d);
1082 emit_store_dst(jd, iptr, d);
1086 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1093 M_XCMOVLT_IMM(-1, d);
1094 M_XCMOVGT_IMM(1, d);
1095 emit_store_dst(jd, iptr, d);
1099 /* floating operations ************************************************/
1101 case ICMD_FNEG: /* ..., value ==> ..., - value */
1103 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1104 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1106 emit_store_dst(jd, iptr, d);
1109 case ICMD_DNEG: /* ..., value ==> ..., - value */
1111 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1112 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1114 emit_store_dst(jd, iptr, d);
1117 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1119 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1120 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1121 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1123 emit_store_dst(jd, iptr, d);
1126 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1128 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1129 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1130 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1132 emit_store_dst(jd, iptr, d);
1135 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1137 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1138 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1139 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1141 emit_store_dst(jd, iptr, d);
1144 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1146 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1147 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1148 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1150 emit_store_dst(jd, iptr, d);
1153 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1155 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1156 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1157 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1159 emit_store_dst(jd, iptr, d);
1162 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1164 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1165 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1166 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1173 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1174 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1175 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1177 emit_store_dst(jd, iptr, d);
1180 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1182 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1183 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1184 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1186 emit_store_dst(jd, iptr, d);
1190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1191 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1192 disp = dseg_add_unique_float(cd, 0.0);
1193 M_IST (s1, REG_PV_CALLEE, disp);
1194 M_FLD (d, REG_PV_CALLEE, disp);
1195 M_CVTIF (d, d); /* rd gets translated to double target register */
1196 emit_store_dst(jd, iptr, d);
1200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1202 disp = dseg_add_unique_float(cd, 0.0);
1203 M_IST(s1, REG_PV_CALLEE, disp);
1204 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1205 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1206 emit_store_dst(jd, iptr, d);
1210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1211 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1212 disp = dseg_add_unique_double(cd, 0.0);
1213 M_STX(s1, REG_PV_CALLEE, disp);
1214 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1215 M_CVTLF(REG_FTMP3, d);
1216 emit_store_dst(jd, iptr, d);
1220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1221 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1222 disp = dseg_add_unique_double(cd, 0.0);
1223 M_STX(s1, REG_PV_CALLEE, disp);
1224 M_DLD(d, REG_PV_CALLEE, disp);
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1230 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1231 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1232 disp = dseg_add_unique_float(cd, 0.0);
1234 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1237 M_MOV(REG_ZERO, d); /* delay slot */
1239 M_CVTFI(s1, REG_FTMP2);
1240 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1241 M_ILD(d, REG_PV, disp);
1242 emit_store_dst(jd, iptr, d);
1246 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1247 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1249 disp = dseg_add_unique_float(cd, 0.0);
1251 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1254 M_MOV(REG_ZERO, d); /* delay slot */
1256 M_CVTDI(s1, REG_FTMP2);
1257 M_FST(REG_FTMP2, REG_PV, disp);
1258 M_ILD(d, REG_PV, disp);
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1263 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1265 disp = dseg_add_unique_double(cd, 0.0);
1267 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1270 M_MOV(REG_ZERO, d); /* delay slot */
1272 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1273 M_DST(REG_FTMP2, REG_PV, disp);
1274 M_LDX(d, REG_PV, disp);
1275 emit_store_dst(jd, iptr, d);
1278 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1279 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1280 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1281 disp = dseg_add_unique_double(cd, 0.0);
1283 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1286 M_MOV(REG_ZERO, d); /* delay slot */
1288 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1289 M_DST(REG_FTMP2, REG_PV, disp);
1290 M_LDX(d, REG_PV, disp);
1291 emit_store_dst(jd, iptr, d);
1294 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1296 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1297 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1299 emit_store_dst(jd, iptr, d);
1302 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1304 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1305 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1307 emit_store_dst(jd, iptr, d);
1310 /* XXX merge F/D versions? only compare instr. is different */
1311 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1313 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1314 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1315 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1317 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1318 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1319 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1325 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1326 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1329 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1330 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1331 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1332 emit_store_dst(jd, iptr, d);
1335 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1337 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1338 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1339 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1341 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1342 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1343 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1349 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1350 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1351 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1353 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1354 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1355 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1356 emit_store_dst(jd, iptr, d);
1360 /* memory operations **************************************************/
1362 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1366 emit_nullpointer_check(cd, iptr, s1);
1367 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1368 emit_store_dst(jd, iptr, d);
1371 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1373 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1374 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1376 /* implicit null-pointer check */
1377 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1378 M_AADD(s2, s1, REG_ITMP3);
1379 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1380 emit_store_dst(jd, iptr, d);
1383 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1385 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1386 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1388 /* implicit null-pointer check */
1389 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1390 M_AADD(s2, s1, REG_ITMP3);
1391 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1392 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1393 emit_store_dst(jd, iptr, d);
1396 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1399 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1401 /* implicit null-pointer check */
1402 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1403 M_AADD(s2, s1, REG_ITMP3);
1404 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1405 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1413 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1414 /* implicit null-pointer check */
1415 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1416 M_ASLL_IMM(s2, 2, REG_ITMP3);
1417 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1418 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1419 emit_store_dst(jd, iptr, d);
1422 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1425 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1427 /* implicit null-pointer check */
1428 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1429 M_ASLL_IMM(s2, 3, REG_ITMP3);
1430 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1431 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1432 emit_store_dst(jd, iptr, d);
1435 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1438 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1439 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1440 /* implicit null-pointer check */
1441 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1442 M_ASLL_IMM(s2, 2, REG_ITMP3);
1443 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1444 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1445 emit_store_dst(jd, iptr, d);
1448 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1452 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1453 /* implicit null-pointer check */
1454 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1455 M_ASLL_IMM(s2, 3, REG_ITMP3);
1456 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1457 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1458 emit_store_dst(jd, iptr, d);
1461 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1464 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1465 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1466 /* implicit null-pointer check */
1467 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1468 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1469 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1470 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1471 emit_store_dst(jd, iptr, d);
1475 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1478 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1479 /* implicit null-pointer check */
1480 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1481 M_AADD(s2, s1, REG_ITMP1);
1482 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1483 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1486 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1487 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1491 /* implicit null-pointer check */
1492 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1493 M_AADD(s2, s1, REG_ITMP1);
1494 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1495 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1496 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1499 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1502 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1503 /* implicit null-pointer check */
1504 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1505 M_ASLL_IMM(s2, 2, REG_ITMP2);
1506 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1507 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1508 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1511 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1515 /* implicit null-pointer check */
1516 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1517 M_ASLL_IMM(s2, 3, REG_ITMP2);
1518 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1519 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1520 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1523 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527 /* implicit null-pointer check */
1528 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1529 M_ASLL_IMM(s2, 2, REG_ITMP2);
1530 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1531 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1532 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1535 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1538 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1539 /* implicit null-pointer check */
1540 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1541 M_ASLL_IMM(s2, 3, REG_ITMP2);
1542 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1543 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1544 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1548 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1552 /* implicit null-pointer check */
1553 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1554 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1556 M_MOV(s1, REG_OUT0);
1557 M_MOV(s3, REG_OUT1);
1558 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1559 M_ALD(REG_ITMP3, REG_PV, disp);
1560 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1562 emit_exception_check(cd, iptr);
1564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1565 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1566 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1567 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1568 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1569 /* implicit null-pointer check */
1570 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1574 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1578 /* implicit null-pointer check */
1579 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1580 M_AADD(s2, s1, REG_ITMP1);
1581 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1584 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1585 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1588 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1589 /* implicit null-pointer check */
1590 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1591 M_AADD(s2, s1, REG_ITMP1);
1592 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1593 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1596 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1600 /* implicit null-pointer check */
1601 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1602 M_ASLL_IMM(s2, 2, REG_ITMP2);
1603 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1604 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1607 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1611 /* implicit null-pointer check */
1612 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1613 M_ASLL_IMM(s2, 3, REG_ITMP2);
1614 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1615 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1618 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1622 /* implicit null-pointer check */
1623 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1624 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1625 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1626 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1630 case ICMD_GETSTATIC: /* ... ==> ..., value */
1632 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1633 uf = iptr->sx.s23.s3.uf;
1634 fieldtype = uf->fieldref->parseddesc.fd->type;
1635 disp = dseg_add_unique_address(cd, uf);
1637 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1640 fi = iptr->sx.s23.s3.fmiref->p.field;
1641 fieldtype = fi->type;
1642 disp = dseg_add_address(cd, fi->value);
1644 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1645 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1648 M_ALD(REG_ITMP1, REG_PV, disp);
1650 switch (fieldtype) {
1652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1653 M_ILD_INTERN(d, REG_ITMP1, 0);
1656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1657 M_LDX_INTERN(d, REG_ITMP1, 0);
1660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1661 M_ALD_INTERN(d, REG_ITMP1, 0);
1664 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1665 M_FLD_INTERN(d, REG_ITMP1, 0);
1668 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1669 M_DLD_INTERN(d, REG_ITMP1, 0);
1672 emit_store_dst(jd, iptr, d);
1675 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1677 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1678 uf = iptr->sx.s23.s3.uf;
1679 fieldtype = uf->fieldref->parseddesc.fd->type;
1680 disp = dseg_add_unique_address(cd, uf);
1682 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1685 fi = iptr->sx.s23.s3.fmiref->p.field;
1686 fieldtype = fi->type;
1687 disp = dseg_add_address(cd, fi->value);
1689 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1690 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1693 M_ALD(REG_ITMP1, REG_PV, disp);
1695 switch (fieldtype) {
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1698 M_IST_INTERN(s1, REG_ITMP1, 0);
1701 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1702 M_STX_INTERN(s1, REG_ITMP1, 0);
1705 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1706 M_AST_INTERN(s1, REG_ITMP1, 0);
1709 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1710 M_FST_INTERN(s1, REG_ITMP1, 0);
1713 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1714 M_DST_INTERN(s1, REG_ITMP1, 0);
1719 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1720 /* val = value (in current instruction) */
1721 /* following NOP) */
1723 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1724 uf = iptr->sx.s23.s3.uf;
1725 fieldtype = uf->fieldref->parseddesc.fd->type;
1726 disp = dseg_add_unique_address(cd, uf);
1728 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1731 fi = iptr->sx.s23.s3.fmiref->p.field;
1732 fieldtype = fi->type;
1733 disp = dseg_add_address(cd, fi->value);
1735 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1736 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1739 M_ALD(REG_ITMP1, REG_PV, disp);
1741 switch (fieldtype) {
1743 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1746 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1749 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1752 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1755 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1761 case ICMD_GETFIELD: /* ... ==> ..., value */
1763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1764 emit_nullpointer_check(cd, iptr, s1);
1766 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1767 uf = iptr->sx.s23.s3.uf;
1769 fieldtype = uf->fieldref->parseddesc.fd->type;
1772 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1775 fi = iptr->sx.s23.s3.fmiref->p.field;
1776 fieldtype = fi->type;
1780 switch (fieldtype) {
1782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
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_FTMP1);
1798 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1805 emit_store_dst(jd, iptr, d);
1808 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1811 emit_nullpointer_check(cd, iptr, s1);
1813 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1814 uf = iptr->sx.s23.s3.uf;
1815 fieldtype = uf->fieldref->parseddesc.fd->type;
1820 fi = iptr->sx.s23.s3.fmiref->p.field;
1821 fieldtype = fi->type;
1825 if (IS_INT_LNG_TYPE(fieldtype))
1826 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1828 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1830 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1831 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1833 switch (fieldtype) {
1835 M_IST(s2, s1, disp);
1838 M_STX(s2, s1, disp);
1841 M_AST(s2, s1, disp);
1844 M_FST(s2, s1, disp);
1847 M_DST(s2, s1, disp);
1855 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1856 /* val = value (in current instruction) */
1857 /* following NOP) */
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 emit_nullpointer_check(cd, iptr, s1);
1862 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1863 unresolved_field *uf = iptr->sx.s23.s3.uf;
1865 fieldtype = uf->fieldref->parseddesc.fd->type;
1867 codegen_addpatchref(cd, PATCHER_get_putfield,
1870 if (opt_showdisassemble) {
1878 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1880 fieldtype = fi->type;
1886 switch (fieldtype) {
1888 M_IST(REG_ZERO, s1, disp);
1891 M_STX(REG_ZERO, s1, disp);
1894 M_AST(REG_ZERO, s1, disp);
1897 M_FST(REG_ZERO, s1, disp);
1900 M_DST(REG_ZERO, s1, disp);
1906 /* branch operations **************************************************/
1908 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911 M_INTMOVE(s1, REG_ITMP2_XPTR);
1913 #ifdef ENABLE_VERIFIER
1914 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1915 unresolved_class *uc = iptr->sx.s23.s2.uc;
1917 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1919 #endif /* ENABLE_VERIFIER */
1921 disp = dseg_add_functionptr(cd, asm_handle_exception);
1922 M_ALD(REG_ITMP1, REG_PV, disp);
1923 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1925 M_NOP; /* nop ensures that XPC is less than the end */
1926 /* of basic block */
1930 case ICMD_GOTO: /* ... ==> ... */
1931 case ICMD_RET: /* ... ==> ... */
1933 emit_br(cd, iptr->dst.block);
1937 case ICMD_JSR: /* ... ==> ... */
1939 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1943 case ICMD_IFNULL: /* ..., value ==> ... */
1944 case ICMD_IFNONNULL:
1946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1947 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1950 /* Note: int compares must not branch on the register directly. */
1951 /* Reason is, that register content is not 32-bit clean. */
1953 case ICMD_IFEQ: /* ..., value ==> ... */
1955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1957 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1958 M_CMP_IMM(s1, iptr->sx.val.i);
1961 ICONST(REG_ITMP2, iptr->sx.val.i);
1962 M_CMP(s1, REG_ITMP2);
1964 emit_beq(cd, iptr->dst.block);
1967 case ICMD_IFLT: /* ..., value ==> ... */
1969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1971 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1972 M_CMP_IMM(s1, iptr->sx.val.i);
1975 ICONST(REG_ITMP2, iptr->sx.val.i);
1976 M_CMP(s1, REG_ITMP2);
1978 emit_blt(cd, iptr->dst.block);
1981 case ICMD_IFLE: /* ..., value ==> ... */
1983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1985 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1986 M_CMP_IMM(s1, iptr->sx.val.i);
1989 ICONST(REG_ITMP2, iptr->sx.val.i);
1990 M_CMP(s1, REG_ITMP2);
1992 emit_ble(cd, iptr->dst.block);
1995 case ICMD_IFNE: /* ..., value ==> ... */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1999 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2000 M_CMP_IMM(s1, iptr->sx.val.i);
2003 ICONST(REG_ITMP2, iptr->sx.val.i);
2004 M_CMP(s1, REG_ITMP2);
2006 emit_bne(cd, iptr->dst.block);
2009 case ICMD_IFGT: /* ..., value ==> ... */
2011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2013 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2014 M_CMP_IMM(s1, iptr->sx.val.i);
2017 ICONST(REG_ITMP2, iptr->sx.val.i);
2018 M_CMP(s1, REG_ITMP2);
2020 emit_bgt(cd, iptr->dst.block);
2023 case ICMD_IFGE: /* ..., value ==> ... */
2025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2028 M_CMP_IMM(s1, iptr->sx.val.i);
2031 ICONST(REG_ITMP2, iptr->sx.val.i);
2032 M_CMP(s1, REG_ITMP2);
2034 emit_bge(cd, iptr->dst.block);
2037 case ICMD_IF_LEQ: /* ..., value ==> ... */
2039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2040 if (iptr->sx.val.l == 0)
2041 emit_beqz(cd, iptr->dst.block, s1);
2043 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2044 M_CMP_IMM(s1, iptr->sx.val.l);
2047 LCONST(REG_ITMP2, iptr->sx.val.l);
2048 M_CMP(s1, REG_ITMP2);
2050 emit_beq_xcc(cd, iptr->dst.block);
2054 case ICMD_IF_LLT: /* ..., value ==> ... */
2056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2057 if (iptr->sx.val.l == 0)
2058 emit_bltz(cd, iptr->dst.block, s1);
2060 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2061 M_CMP_IMM(s1, iptr->sx.val.l);
2064 LCONST(REG_ITMP2, iptr->sx.val.l);
2065 M_CMP(s1, REG_ITMP2);
2067 emit_blt_xcc(cd, iptr->dst.block);
2071 case ICMD_IF_LLE: /* ..., value ==> ... */
2073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2074 if (iptr->sx.val.l == 0)
2075 emit_blez(cd, iptr->dst.block, s1);
2077 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2078 M_CMP_IMM(s1, iptr->sx.val.l);
2081 LCONST(REG_ITMP2, iptr->sx.val.l);
2082 M_CMP(s1, REG_ITMP2);
2084 emit_ble_xcc(cd, iptr->dst.block);
2088 case ICMD_IF_LNE: /* ..., value ==> ... */
2090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2091 if (iptr->sx.val.l == 0)
2092 emit_bnez(cd, iptr->dst.block, s1);
2094 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2095 M_CMP_IMM(s1, iptr->sx.val.l);
2098 LCONST(REG_ITMP2, iptr->sx.val.l);
2099 M_CMP(s1, REG_ITMP2);
2101 emit_bne_xcc(cd, iptr->dst.block);
2105 case ICMD_IF_LGT: /* ..., value ==> ... */
2107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2108 if (iptr->sx.val.l == 0)
2109 emit_bgtz(cd, iptr->dst.block, s1);
2111 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2112 M_CMP_IMM(s1, iptr->sx.val.l);
2115 LCONST(REG_ITMP2, iptr->sx.val.l);
2116 M_CMP(s1, REG_ITMP2);
2118 emit_bgt_xcc(cd, iptr->dst.block);
2122 case ICMD_IF_LGE: /* ..., value ==> ... */
2124 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2125 if (iptr->sx.val.l == 0)
2126 emit_bgez(cd, iptr->dst.block, s1);
2128 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2129 M_CMP_IMM(s1, iptr->sx.val.l);
2132 LCONST(REG_ITMP2, iptr->sx.val.l);
2133 M_CMP(s1, REG_ITMP2);
2135 emit_bge_xcc(cd, iptr->dst.block);
2140 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2141 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2146 emit_beq_xcc(cd, iptr->dst.block);
2149 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2151 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2152 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2154 emit_beq(cd, iptr->dst.block);
2157 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2158 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2160 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2163 emit_bne_xcc(cd, iptr->dst.block);
2166 case ICMD_IF_ICMPNE: /* 32-bit compare */
2168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2169 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2171 emit_bne(cd, iptr->dst.block);
2174 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2176 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2177 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2179 emit_blt_xcc(cd, iptr->dst.block);
2182 case ICMD_IF_ICMPLT: /* 32-bit compare */
2184 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2185 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2187 emit_blt(cd, iptr->dst.block);
2190 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2193 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2195 emit_bgt_xcc(cd, iptr->dst.block);
2198 case ICMD_IF_ICMPGT: /* 32-bit compare */
2200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2201 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2203 emit_bgt(cd, iptr->dst.block);
2206 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2208 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2209 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2211 emit_ble_xcc(cd, iptr->dst.block);
2214 case ICMD_IF_ICMPLE: /* 32-bit compare */
2216 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2217 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2219 emit_ble(cd, iptr->dst.block);
2223 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2225 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2226 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2228 emit_bge_xcc(cd, iptr->dst.block);
2231 case ICMD_IF_ICMPGE: /* 32-bit compare */
2233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2234 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2236 emit_bge(cd, iptr->dst.block);
2240 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2243 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2244 M_INTMOVE(s1, REG_RESULT_CALLEE);
2245 goto nowperformreturn;
2247 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2249 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2250 M_INTMOVE(s1, REG_RESULT_CALLEE);
2252 #ifdef ENABLE_VERIFIER
2253 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2254 unresolved_class *uc = iptr->sx.s23.s2.uc;
2256 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2258 #endif /* ENABLE_VERIFIER */
2259 goto nowperformreturn;
2261 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2264 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2265 M_DBLMOVE(s1, REG_FRESULT);
2266 goto nowperformreturn;
2268 case ICMD_RETURN: /* ... ==> ... */
2274 p = cd->stackframesize;
2276 #if !defined(NDEBUG)
2277 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2278 emit_verbosecall_exit(jd);
2281 #if defined(ENABLE_THREADS)
2282 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2283 /* XXX jit-c-call */
2284 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2285 M_ALD(REG_ITMP3, REG_PV, disp);
2287 /* we need to save fp return value (int saved by window) */
2289 switch (iptr->opc) {
2292 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2293 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2294 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2296 /* restore the fp return value */
2298 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2304 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2305 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2316 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2322 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2325 branch_target_t *table;
2327 table = iptr->dst.table;
2329 l = iptr->sx.s23.s2.tablelow;
2330 i = iptr->sx.s23.s3.tablehigh;
2332 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2334 M_INTMOVE(s1, REG_ITMP1);
2336 else if (l <= 4095) {
2337 M_ADD_IMM(s1, -l, REG_ITMP1);
2340 ICONST(REG_ITMP2, l);
2341 /* XXX: do I need to truncate s1 to 32-bit ? */
2342 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2350 M_CMP_IMM(REG_ITMP1, i - 1);
2353 ICONST(REG_ITMP2, i - 1);
2354 M_CMP(REG_ITMP1, REG_ITMP2);
2356 emit_bugt(cd, table[0].block); /* default target */
2358 /* build jump table top down and use address of lowest entry */
2363 dseg_add_target(cd, table->block);
2368 /* length of dataseg after last dseg_addtarget is used by load */
2370 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2371 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2372 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2373 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2378 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2381 lookup_target_t *lookup;
2383 lookup = iptr->dst.lookup;
2385 i = iptr->sx.s23.s2.lookupcount;
2387 MCODECHECK((i<<2)+8);
2388 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2391 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2392 M_CMP_IMM(s1, lookup->value);
2394 ICONST(REG_ITMP2, lookup->value);
2395 M_CMP(s1, REG_ITMP2);
2397 emit_beq(cd, lookup->target.block);
2401 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2407 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2409 bte = iptr->sx.s23.s3.bte;
2412 /* XXX: builtin calling with stack arguments not implemented */
2413 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2415 s3 = md->paramcount;
2417 MCODECHECK((s3 << 1) + 64);
2419 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2421 /* copy float arguments according to ABI convention */
2423 int num_fltregargs = 0;
2424 int fltregarg_inswap[16];
2426 for (s3 = s3 - 1; s3 >= 0; s3--) {
2427 var = VAR(iptr->sx.s23.s2.args[s3]);
2429 if (IS_FLT_DBL_TYPE(var->type)) {
2430 if (!md->params[s3].inmemory) {
2431 s1 = s3; /*native flt args use argument index directly*/
2432 d = emit_load(jd, iptr, var, REG_FTMP1);
2435 fltregarg_inswap[num_fltregargs] = s1;
2437 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2446 /* move swapped float args to target regs */
2447 for (i = 0; i < num_fltregargs; i++) {
2448 s1 = fltregarg_inswap[i];
2449 M_DMOV(s1 + 16, s1);
2450 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2454 assert(md->argfltreguse == 0);
2459 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2461 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2462 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2463 case ICMD_INVOKEINTERFACE:
2465 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2467 um = iptr->sx.s23.s3.um;
2468 md = um->methodref->parseddesc.md;
2471 lm = iptr->sx.s23.s3.fmiref->p.method;
2473 md = lm->parseddesc;
2477 s3 = md->paramcount;
2479 MCODECHECK((s3 << 1) + 64);
2481 /* copy arguments to registers or stack location */
2483 for (s3 = s3 - 1; s3 >= 0; s3--) {
2484 var = VAR(iptr->sx.s23.s2.args[s3]);
2485 d = md->params[s3].regoff;
2487 if (var->flags & PREALLOC)
2490 if (IS_INT_LNG_TYPE(var->type)) {
2491 if (!md->params[s3].inmemory) {
2492 s1 = emit_load(jd, iptr, var, d);
2496 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2497 M_STX(s1, REG_SP, JITSTACK + d);
2501 #ifdef BUILTIN_FLOAT_ARGS
2502 if (iptr->opc == ICMD_BUILTIN)
2506 if (!md->params[s3].inmemory) {
2507 s1 = emit_load(jd, iptr, var, d);
2508 if (IS_2_WORD_TYPE(var->type))
2514 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2515 M_DST(s1, REG_SP, JITSTACK + d);
2520 switch (iptr->opc) {
2522 disp = dseg_add_functionptr(cd, bte->fp);
2524 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2526 /* XXX jit-c-call */
2527 /* generate the actual call */
2529 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2531 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2532 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2533 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2535 emit_exception_check(cd, iptr);
2536 if (md->returntype.type == TYPE_FLT) {
2537 /* special handling for float return value in %f0 */
2542 case ICMD_INVOKESPECIAL:
2543 emit_nullpointer_check(cd, iptr, REG_OUT0);
2546 case ICMD_INVOKESTATIC:
2548 disp = dseg_add_unique_address(cd, NULL);
2550 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2554 disp = dseg_add_address(cd, lm->stubroutine);
2556 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2558 /* generate the actual call */
2560 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2562 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2563 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2564 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2567 case ICMD_INVOKEVIRTUAL:
2568 emit_nullpointer_check(cd, iptr, REG_OUT0);
2571 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2576 s1 = OFFSET(vftbl_t, table[0]) +
2577 sizeof(methodptr) * lm->vftblindex;
2579 /* implicit null-pointer check */
2580 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2581 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2583 /* generate the actual call */
2585 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2587 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2588 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2589 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2592 case ICMD_INVOKEINTERFACE:
2593 emit_nullpointer_check(cd, iptr, REG_OUT0);
2596 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2602 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2603 sizeof(methodptr*) * lm->class->index;
2605 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2608 /* implicit null-pointer check */
2609 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2610 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2611 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2613 /* generate the actual call */
2615 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2617 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2618 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2619 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2623 /* store return value */
2625 d = md->returntype.type;
2627 if (d != TYPE_VOID) {
2628 if (IS_INT_LNG_TYPE(d)) {
2629 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2630 M_INTMOVE(REG_RESULT_CALLER, s1);
2633 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2634 if (IS_2_WORD_TYPE(d)) {
2635 M_DBLMOVE(REG_FRESULT, s1);
2637 M_FLTMOVE(REG_FRESULT, s1);
2640 emit_store_dst(jd, iptr, s1);
2645 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2646 /* val.a: (classinfo*) superclass */
2648 /* superclass is an interface:
2650 * OK if ((sub == NULL) ||
2651 * (sub->vftbl->interfacetablelength > super->index) &&
2652 * (sub->vftbl->interfacetable[-super->index] != NULL));
2654 * superclass is a class:
2656 * OK if ((sub == NULL) || (0
2657 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2658 * super->vftbl->diffvall));
2661 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2665 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2670 super = iptr->sx.s23.s3.c.cls;
2671 superindex = super->index;
2674 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2675 CODEGEN_CRITICAL_SECTION_NEW;
2677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2679 /* if class is not resolved, check which code to call */
2681 if (super == NULL) {
2682 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2684 cr = iptr->sx.s23.s3.c.ref;
2685 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2687 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2690 M_ILD(REG_ITMP2, REG_PV, disp);
2691 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2692 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2695 /* interface checkcast code */
2697 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2698 if (super == NULL) {
2699 cr = iptr->sx.s23.s3.c.ref;
2701 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2705 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2708 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2709 M_ILD(REG_ITMP3, REG_ITMP2,
2710 OFFSET(vftbl_t, interfacetablelength));
2711 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2712 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2714 M_ALD(REG_ITMP3, REG_ITMP2,
2715 OFFSET(vftbl_t, interfacetable[0]) -
2716 superindex * sizeof(methodptr*));
2717 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2720 emit_label_br(cd, BRANCH_LABEL_4);
2722 emit_label(cd, BRANCH_LABEL_3);
2725 /* class checkcast code */
2727 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2728 if (super == NULL) {
2729 emit_label(cd, BRANCH_LABEL_2);
2731 cr = iptr->sx.s23.s3.c.ref;
2732 disp = dseg_add_unique_address(cd, NULL);
2734 codegen_add_patch_ref(cd,
2735 PATCHER_checkcast_instanceof_class,
2739 disp = dseg_add_address(cd, super->vftbl);
2741 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2744 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2745 M_ALD(REG_ITMP3, REG_PV, disp);
2747 CODEGEN_CRITICAL_SECTION_START;
2749 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2750 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2751 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2752 M_ALD(REG_ITMP3, REG_PV, disp);
2753 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2755 CODEGEN_CRITICAL_SECTION_END;
2758 M_CMP(REG_ITMP3, REG_ITMP2);
2759 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2762 emit_label(cd, BRANCH_LABEL_5);
2765 if (super == NULL) {
2766 emit_label(cd, BRANCH_LABEL_1);
2767 emit_label(cd, BRANCH_LABEL_4);
2770 d = codegen_reg_of_dst(jd, iptr, s1);
2773 /* array type cast-check */
2775 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2776 M_INTMOVE(s1, REG_OUT0);
2778 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2780 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2781 cr = iptr->sx.s23.s3.c.ref;
2782 disp = dseg_add_unique_address(cd, NULL);
2784 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2788 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2790 M_ALD(REG_OUT1, REG_PV, disp);
2791 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2792 M_ALD(REG_ITMP3, REG_PV, disp);
2793 /* XXX jit-c-call */
2794 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2798 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2800 d = codegen_reg_of_dst(jd, iptr, s1);
2804 emit_store_dst(jd, iptr, d);
2807 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2808 /* val.a: (classinfo*) superclass */
2810 /* superclass is an interface:
2812 * return (sub != NULL) &&
2813 * (sub->vftbl->interfacetablelength > super->index) &&
2814 * (sub->vftbl->interfacetable[-super->index] != NULL);
2816 * superclass is a class:
2818 * return ((sub != NULL) && (0
2819 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2820 * super->vftbl->diffvall));
2825 vftbl_t *supervftbl;
2828 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2834 super = iptr->sx.s23.s3.c.cls;
2835 superindex = super->index;
2836 supervftbl = super->vftbl;
2839 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2840 CODEGEN_CRITICAL_SECTION_NEW;
2842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2845 M_MOV(s1, REG_ITMP1);
2851 /* if class is not resolved, check which code to call */
2853 if (super == NULL) {
2854 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2856 cr = iptr->sx.s23.s3.c.ref;
2857 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2859 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2862 M_ILD(REG_ITMP3, REG_PV, disp);
2863 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2864 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2867 /* interface instanceof code */
2869 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2870 if (super == NULL) {
2871 cr = iptr->sx.s23.s3.c.ref;
2873 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2877 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2880 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2881 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2882 M_CMP_IMM(REG_ITMP3, superindex);
2885 M_ALD(REG_ITMP1, REG_ITMP1,
2886 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2887 superindex * sizeof(methodptr*)));
2888 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2891 emit_label_br(cd, BRANCH_LABEL_4);
2893 emit_label(cd, BRANCH_LABEL_3);
2896 /* class instanceof code */
2898 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2899 if (super == NULL) {
2900 emit_label(cd, BRANCH_LABEL_2);
2902 cr = iptr->sx.s23.s3.c.ref;
2903 disp = dseg_add_unique_address(cd, NULL);
2905 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2909 disp = dseg_add_address(cd, supervftbl);
2911 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2914 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2915 M_ALD(REG_ITMP2, REG_PV, disp);
2917 CODEGEN_CRITICAL_SECTION_START;
2919 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2920 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2921 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2923 CODEGEN_CRITICAL_SECTION_END;
2925 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2926 M_CMP(REG_ITMP1, REG_ITMP2);
2927 M_XCMOVULE_IMM(1, d);
2930 emit_label(cd, BRANCH_LABEL_5);
2933 if (super == NULL) {
2934 emit_label(cd, BRANCH_LABEL_1);
2935 emit_label(cd, BRANCH_LABEL_4);
2938 emit_store_dst(jd, iptr, d);
2942 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2944 /* check for negative sizes and copy sizes to stack if necessary */
2946 MCODECHECK((iptr->s1.argcount << 1) + 64);
2948 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2950 var = VAR(iptr->sx.s23.s2.args[s1]);
2952 /* copy SAVEDVAR sizes to stack */
2954 /* Already Preallocated? */
2956 if (!(var->flags & PREALLOC)) {
2957 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2958 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2962 /* arg 0 = dimension count */
2964 ICONST(REG_OUT0, iptr->s1.argcount);
2966 /* is patcher function set? */
2968 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2969 disp = dseg_add_unique_address(cd, 0);
2971 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2972 iptr->sx.s23.s3.c.ref,
2976 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2978 /* arg 1 = arraydescriptor */
2980 M_ALD(REG_OUT1, REG_PV, disp);
2982 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2984 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2986 /* XXX c abi call */
2987 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2988 M_ALD(REG_ITMP3, REG_PV, disp);
2989 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2992 /* check for exception before result assignment */
2994 emit_exception_check(cd, iptr);
2996 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2997 M_INTMOVE(REG_RESULT_CALLER, d);
2998 emit_store_dst(jd, iptr, d);
3002 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3008 } /* for instruction */
3012 /* At the end of a basic block we may have to append some nops,
3013 because the patcher stub calling code might be longer than the
3014 actual instruction. So codepatching does not change the
3015 following block unintentionally. */
3017 if (cd->mcodeptr < cd->lastmcodeptr) {
3018 while (cd->mcodeptr < cd->lastmcodeptr) {
3023 } /* if (bptr -> flags >= BBREACHED) */
3024 } /* for basic block */
3026 dseg_createlinenumbertable(cd);
3028 /* generate stubs */
3030 emit_patcher_stubs(jd);
3032 /* everything's ok */
3038 /* codegen_emit_stub_compiler **************************************************
3040 Emits a stub routine which calls the compiler.
3042 *******************************************************************************/
3044 void codegen_emit_stub_compiler(jitdata *jd)
3049 /* get required compiler data */
3054 /* code for the stub */
3056 /* no window save yet, user caller's PV */
3057 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3058 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3059 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3064 /* codegen_emit_stub_native ****************************************************
3066 Emits a stub routine which calls a native method.
3068 *******************************************************************************/
3070 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3077 s4 i, j; /* count variables */
3080 s4 funcdisp; /* displacement of the function */
3081 s4 fltregarg_offset[FLT_ARG_CNT];
3083 /* get required compiler data */
3089 /* initialize variables */
3092 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3094 /* calculate stack frame size */
3096 cd->stackframesize =
3097 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3098 sizeof(localref_table) / SIZEOF_VOID_P +
3099 md->paramcount + /* for saving arguments over calls */
3100 nmd->memuse + /* nmd->memuse includes the (6) abi params */
3104 /* keep stack 16-byte aligned (ABI requirement) */
3106 if (cd->stackframesize & 1)
3107 cd->stackframesize++;
3109 /* create method header */
3111 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3112 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3113 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3114 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3115 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3116 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3117 (void) dseg_addlinenumbertablesize(cd);
3118 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3120 /* generate stub code */
3122 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3124 #if !defined(NDEBUG)
3125 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3126 emit_verbosecall_enter(jd);
3129 /* get function address (this must happen before the stackframeinfo) */
3131 funcdisp = dseg_add_functionptr(cd, f);
3133 #if !defined(WITH_STATIC_CLASSPATH)
3135 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3139 /* save float argument registers */
3141 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3143 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3144 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3145 s1 = WINSAVE_CNT + nmd->memuse + j;
3146 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3147 fltregarg_offset[i] = s1; /* remember stack offset */
3152 /* prepare data structures for native function call */
3154 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3155 M_MOV(REG_PV_CALLEE, REG_OUT1);
3156 M_MOV(REG_FP, REG_OUT2); /* java sp */
3157 M_MOV(REG_RA_CALLEE, REG_OUT3);
3158 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3159 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3160 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3161 M_NOP; /* XXX fill me! */
3163 /* keep float arguments on stack */
3165 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3166 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3167 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3173 /* copy or spill arguments to new locations */
3175 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3176 t = md->paramtypes[i].type;
3178 if (IS_INT_LNG_TYPE(t)) {
3180 /* integral types */
3182 if (!md->params[i].inmemory) {
3183 s1 = md->params[i].regoff;
3184 /* s1 refers to the old window, transpose */
3185 s1 = REG_WINDOW_TRANSPOSE(s1);
3187 if (!nmd->params[j].inmemory) {
3188 s2 = nmd->params[j].regoff;
3191 /* nmd's regoff is relative to the start of the param array */
3192 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3193 M_AST(s1, REG_SP, s2);
3197 if (!nmd->params[j].inmemory) {
3198 /* JIT stack arg -> NAT reg arg */
3200 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3201 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3203 assert(false); /* path never taken */
3206 s1 = md->params[i].regoff + cd->stackframesize * 8;
3207 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3208 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3209 M_AST(REG_ITMP1, REG_SP, s2);
3214 /* floating point types */
3216 if (!md->params[i].inmemory) {
3217 s1 = md->params[i].regoff;
3219 if (!nmd->params[j].inmemory) {
3221 /* no mapping to regs needed, native flt args use regoff */
3222 s2 = nmd->params[j].regoff;
3224 /* JIT float regs are still on the stack */
3225 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3228 /* not supposed to happen with 16 NAT flt args */
3231 s2 = nmd->params[j].regoff;
3232 if (IS_2_WORD_TYPE(t))
3233 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3235 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3241 s1 = md->params[i].regoff;
3243 if (!nmd->params[j].inmemory) {
3245 /* JIT stack -> NAT reg */
3247 s2 = nmd->params[j].regoff;
3248 M_DLD(s2, REG_FP, JITSTACK + s1);
3252 /* JIT stack -> NAT stack */
3254 s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3256 /* The FTMP register may already be loaded with args */
3257 /* we know $f0 is unused because of the env pointer */
3258 M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3259 M_DST(REG_F0, REG_SP, BIAS + s2);
3266 /* put class into second argument register */
3268 if (m->flags & ACC_STATIC) {
3269 disp = dseg_add_address(cd, m->class);
3270 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3273 /* put env into first argument register */
3275 disp = dseg_add_address(cd, _Jv_env);
3276 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3278 /* do the native function call */
3280 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3281 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3282 M_NOP; /* delay slot */
3284 /* save return value */
3286 if (md->returntype.type != TYPE_VOID) {
3287 if (IS_INT_LNG_TYPE(md->returntype.type))
3288 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3290 M_DST(REG_FRESULT, REG_SP, CSTACK);
3293 /* Note: native functions return float values in %f0 (see ABI) */
3294 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3296 #if !defined(NDEBUG)
3297 /* But for the trace function we need to put a flt result into %f1 */
3298 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3299 if (!IS_2_WORD_TYPE(md->returntype.type))
3300 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3301 emit_verbosecall_exit(jd);
3305 /* remove native stackframe info */
3307 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3308 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3309 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3310 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3311 M_NOP; /* XXX fill me! */
3312 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3314 /* restore float return value, int return value already in our return reg */
3316 if (md->returntype.type != TYPE_VOID) {
3317 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3318 if (IS_2_WORD_TYPE(md->returntype.type))
3319 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3321 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3325 /* check for exception */
3326 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3329 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3332 /* handle exception */
3334 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3335 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3336 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3337 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3338 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3340 /* generate patcher stubs */
3342 emit_patcher_stubs(jd);
3346 * These are local overrides for various environment variables in Emacs.
3347 * Please do not remove this and leave it at the end of the file, where
3348 * Emacs will automagically detect them.
3349 * ---------------------------------------------------------------------
3352 * indent-tabs-mode: t
3356 * vim:noexpandtab:sw=4:ts=4: