1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
39 /* #include "vm/jit/sparc64/arch.h" */
40 #include "vm/jit/sparc64/codegen.h"
42 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
50 #include "vm/jit/abi.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/codegen-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/sparc64/emit.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/patcher.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
66 #define BUILTIN_FLOAT_ARGS 1
68 /* XXX use something like this for window control ?
69 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
71 #define REG_PV REG_PV_CALLEE
76 if ((disp < -4096) || (disp > 4095))
77 printf("disp %d\n", disp);
80 return (disp >= -4096) && (disp <= 4095);
83 s4 get_lopart_disp(disp)
88 lodisp = setlo_part(disp);
90 if (setlo_part(disp) == 0)
93 lodisp = setlo_part(disp) | 0x1c00;
100 /* codegen_emit ****************************************************************
102 Generates machine code.
104 *******************************************************************************/
106 bool codegen_emit(jitdata *jd)
112 s4 len, s1, s2, s3, d, disp, slots;
118 constant_classref *cr;
119 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
120 unresolved_method *um;
121 builtintable_entry *bte;
124 unresolved_field *uf;
128 /* get required compiler data */
135 /* prevent compiler warnings */
146 #if 0 /* no leaf optimization yet */
147 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
149 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
152 /* space to save used callee saved registers */
154 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
155 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
157 cd->stackframesize = rd->memuse + savedregs_num;
159 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 cd->stackframesize++;
164 /* keep stack 16-byte aligned (ABI requirement) */
166 if (cd->stackframesize & 1)
167 cd->stackframesize++;
169 /* create method header */
171 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
172 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
174 #if defined(ENABLE_THREADS)
175 /* IsSync contains the offset relative to the stack pointer for the
176 argument of monitor_exit used in the exception handler. Since the
177 offset could be zero and give a wrong meaning of the flag it is
181 if (checksync && (m->flags & ACC_SYNCHRONIZED))
182 (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
185 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
187 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
188 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
189 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
190 dseg_addlinenumbertablesize(cd);
191 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
193 /* create exception table */
195 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
196 dseg_add_target(cd, ex->start);
197 dseg_add_target(cd, ex->end);
198 dseg_add_target(cd, ex->handler);
199 (void) dseg_add_unique_address(cd, ex->catchtype.any);
202 /* save register window and create stack frame (if necessary) */
204 if (cd->stackframesize)
205 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
208 /* save callee saved float registers (none right now) */
210 p = cd->stackframesize;
211 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
212 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
217 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
218 emit_verbosecall_enter(jd);
222 /* call monitorenter function */
223 #if defined(ENABLE_THREADS)
224 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
225 /* stack offset for monitor argument */
229 /* save float argument registers */
233 ALIGN_STACK_SLOTS(slots);
235 M_LDA(REG_SP, REG_SP, -(slots * 8));
236 for (i = 0; i < FLT_ARG_CNT; i++)
237 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
241 /* get correct lock object */
243 if (m->flags & ACC_STATIC) {
244 disp = dseg_add_address(cd, &m->class->object.header);
245 M_ALD(REG_OUT0, REG_PV, disp);
246 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
247 M_ALD(REG_ITMP3, REG_PV, disp);
250 /* copy class pointer: $i0 -> $o0 */
251 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
253 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
254 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
255 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
258 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
259 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
261 /* restore float argument registers */
263 for (i = 0; i < FLT_ARG_CNT; i++)
264 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
266 M_LDA(REG_SP, REG_SP, slots * 8);
271 /* take arguments out of register or stack frame */
275 for (p = 0, l = 0; p < md->paramcount; p++) {
276 t = md->paramtypes[p].type;
278 varindex = jd->local_map[l * 5 + t];
281 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
284 if (varindex == UNUSED)
288 s1 = md->params[p].regoff;
290 if (IS_INT_LNG_TYPE(t)) { /* integer args */
294 if (!md->params[p].inmemory) { /* register arguments */
295 s1 = REG_WINDOW_TRANSPOSE(s1);
297 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
299 /* the register allocator does not know about the window. */
300 /* avoid copying the locals from save to save regs by */
301 /* swapping variables. */
304 int old_dest = var->vv.regoff;
305 int new_dest = p + 24;
307 /* run through all variables */
309 for (i = 0; i < jd->varcount; i++) {
310 varinfo* uvar = VAR(i);
312 if (IS_FLT_DBL_TYPE(uvar->type))
315 s2 = uvar->vv.regoff;
317 /* free the in reg by moving all other references */
319 if (s2 == new_dest) {
320 uvar->vv.regoff = old_dest;
321 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
324 /* move all variables to the in reg */
326 if (s2 == old_dest) {
327 uvar->vv.regoff = new_dest;
328 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
336 else { /* reg arg -> spilled */
337 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
340 } else { /* stack arguments */
341 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
342 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
344 } else { /* stack arg -> spilled */
345 /* add the callers window save registers */
346 var->vv.regoff = cd->stackframesize * 8 + s1;
350 } else { /* floating args */
351 if (!md->params[p].inmemory) { /* register arguments */
352 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
353 M_FLTMOVE(s1, var->vv.regoff);
355 } else { /* reg arg -> spilled */
356 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
359 } else { /* stack arguments */
360 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
361 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
363 } else { /* stack-arg -> spilled */
364 var->vv.regoff = cd->stackframesize * 8 + s1;
373 /* end of header generation */
375 /* create replacement points */
377 REPLACEMENT_POINTS_INIT(cd, jd);
379 /* walk through all basic blocks */
381 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
383 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
385 if (bptr->flags >= BBREACHED) {
387 /* branch resolving */
389 codegen_resolve_branchrefs(cd, bptr);
391 /* handle replacement points */
394 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
395 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
401 /* copy interface registers to their destination */
406 #if defined(ENABLE_LSRA)
407 #error XXX LSRA not tested yet
411 src = bptr->invars[len];
412 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
413 /* d = reg_of_var(m, src, REG_ITMP1); */
414 if (!(src->flags & INMEMORY))
418 M_INTMOVE(REG_ITMP1, d);
419 emit_store(jd, NULL, src, d);
426 var = VAR(bptr->invars[len]);
427 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
428 d = codegen_reg_of_var(0, var, REG_ITMP1);
429 M_INTMOVE(REG_ITMP2_XPTR, d);
430 emit_store(jd, NULL, var, d);
433 assert((var->flags & INOUT));
436 #if defined(ENABLE_LSRA)
439 /* walk through all instructions */
443 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
444 if (iptr->line != currentline) {
445 dseg_addlinenumber(cd, iptr->line);
446 currentline = iptr->line;
449 MCODECHECK(64); /* an instruction usually needs < 64 words */
453 case ICMD_INLINE_START:
454 case ICMD_INLINE_END:
457 case ICMD_NOP: /* ... ==> ... */
460 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
463 emit_nullpointer_check(cd, iptr, s1);
466 /* constant operations ************************************************/
468 case ICMD_ICONST: /* ... ==> ..., constant */
470 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
471 ICONST(d, iptr->sx.val.i);
472 emit_store_dst(jd, iptr, d);
475 case ICMD_LCONST: /* ... ==> ..., constant */
477 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
478 LCONST(d, iptr->sx.val.l);
479 emit_store_dst(jd, iptr, d);
482 case ICMD_FCONST: /* ... ==> ..., constant */
484 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
485 disp = dseg_add_float(cd, iptr->sx.val.f);
486 M_FLD(d, REG_PV, disp);
487 emit_store_dst(jd, iptr, d);
490 case ICMD_DCONST: /* ... ==> ..., constant */
492 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
493 disp = dseg_add_double(cd, iptr->sx.val.d);
494 M_DLD(d, REG_PV, disp);
495 emit_store_dst(jd, iptr, d);
498 case ICMD_ACONST: /* ... ==> ..., constant */
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
502 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
503 cr = iptr->sx.val.c.ref;
504 disp = dseg_add_unique_address(cd, cr);
506 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
508 M_ALD(d, REG_PV, disp);
512 if (iptr->sx.val.anyptr == NULL) {
513 M_INTMOVE(REG_ZERO, d);
516 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
517 M_ALD(d, REG_PV, disp);
520 emit_store_dst(jd, iptr, d);
524 /* load/store/copy/move operations ************************************/
526 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
531 case ICMD_ISTORE: /* ..., value ==> ... */
542 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
547 /* pop/dup/swap operations ********************************************/
549 /* attention: double and longs are only one entry in CACAO ICMDs */
551 case ICMD_POP: /* ..., value ==> ... */
552 case ICMD_POP2: /* ..., value, value ==> ... */
556 /* integer operations *************************************************/
558 case ICMD_INEG: /* ..., value ==> ..., - value */
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
563 M_SUB(REG_ZERO, s1, d);
564 emit_store_dst(jd, iptr, d);
567 case ICMD_I2L: /* ..., value ==> ..., value */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
572 emit_store_dst(jd, iptr, d);
575 case ICMD_L2I: /* ..., value ==> ..., value */
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
579 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
580 emit_store_dst(jd, iptr, d);
583 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 M_SLLX_IMM(s1, 56, d);
588 M_SRAX_IMM( d, 56, d);
589 emit_store_dst(jd, iptr, d);
592 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596 M_SLLX_IMM(s1, 48, d);
597 M_SRLX_IMM( d, 48, d);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 M_SLLX_IMM(s1, 48, d);
606 M_SRAX_IMM( d, 48, d);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
617 emit_store_dst(jd, iptr, d);
621 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
622 /* sx.val.i = constant */
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
627 M_ADD_IMM(s1, iptr->sx.val.i, d);
629 ICONST(REG_ITMP2, iptr->sx.val.i);
630 M_ADD(s1, REG_ITMP2, d);
632 emit_store_dst(jd, iptr, d);
635 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
636 /* sx.val.l = constant */
638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
640 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
641 M_ADD_IMM(s1, iptr->sx.val.l, d);
643 LCONST(REG_ITMP2, iptr->sx.val.l);
644 M_ADD(s1, REG_ITMP2, d);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656 emit_store_dst(jd, iptr, d);
659 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
660 /* sx.val.i = constant */
662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
665 M_SUB_IMM(s1, iptr->sx.val.i, d);
667 ICONST(REG_ITMP2, iptr->sx.val.i);
668 M_SUB(s1, REG_ITMP2, d);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
674 /* sx.val.l = constant */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
678 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
679 M_SUB_IMM(s1, iptr->sx.val.l, d);
681 LCONST(REG_ITMP2, iptr->sx.val.l);
682 M_SUB(s1, REG_ITMP2, d);
684 emit_store_dst(jd, iptr, d);
687 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
698 /* sx.val.i = constant */
700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
702 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
703 M_MULX_IMM(s1, iptr->sx.val.i, d);
705 ICONST(REG_ITMP2, iptr->sx.val.i);
706 M_MULX(s1, REG_ITMP2, d);
708 emit_store_dst(jd, iptr, d);
711 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
712 /* sx.val.l = constant */
714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
715 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
716 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
717 M_MULX_IMM(s1, iptr->sx.val.l, d);
719 LCONST(REG_ITMP2, iptr->sx.val.l);
720 M_MULX(s1, REG_ITMP2, d);
722 emit_store_dst(jd, iptr, d);
725 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
726 /* XXX could also clear Y and use 32bit div */
727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
729 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
730 emit_arithmetic_check(cd, iptr, s2);
732 /* XXX trim s2 like s1 ? */
734 emit_store_dst(jd, iptr, d);
737 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
739 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
740 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
741 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
742 emit_arithmetic_check(cd, iptr, s2);
744 emit_store_dst(jd, iptr, d);
747 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
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_ITMP3);
752 emit_arithmetic_check(cd, iptr, s2);
754 /* XXX trim s2 like s1 ? */
755 M_DIVX(s1, s2, REG_ITMP3);
756 M_MULX(s2, REG_ITMP3, REG_ITMP3);
757 M_SUB(s1, REG_ITMP3, d);
758 emit_store_dst(jd, iptr, d);
761 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
764 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
766 emit_arithmetic_check(cd, iptr, s2);
767 M_DIVX(s1, s2, REG_ITMP3);
768 M_MULX(s2, REG_ITMP3, REG_ITMP3);
769 M_SUB(s1, REG_ITMP3, d);
770 emit_store_dst(jd, iptr, d);
773 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
774 case ICMD_LDIVPOW2: /* val.i = constant */
776 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
777 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
778 M_SRAX_IMM(s1, 63, REG_ITMP2);
779 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
780 M_ADD(s1, REG_ITMP2, REG_ITMP2);
781 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
800 emit_store_dst(jd, iptr, d);
803 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
804 /* val.i = constant */
806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
808 M_SLL_IMM(s1, iptr->sx.val.i, d);
809 emit_store_dst(jd, iptr, d);
812 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
813 /* val.i = constant */
815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 M_SLLX_IMM(s1, iptr->sx.val.i, d);
818 emit_store_dst(jd, iptr, d);
821 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827 emit_store_dst(jd, iptr, d);
830 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
831 /* sx.val.i = constant */
833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
834 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
835 M_SRA_IMM(s1, iptr->sx.val.i, d);
836 emit_store_dst(jd, iptr, d);
839 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845 emit_store_dst(jd, iptr, d);
848 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
849 /* sx.val.i = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 M_SRL_IMM(s1, iptr->sx.val.i, d);
854 emit_store_dst(jd, iptr, d);
857 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863 emit_store_dst(jd, iptr, d);
866 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
867 /* sx.val.i = constant */
869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 M_SRAX_IMM(s1, iptr->sx.val.i, d);
872 emit_store_dst(jd, iptr, d);
875 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
879 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
881 emit_store_dst(jd, iptr, d);
884 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
885 /* sx.val.i = constant */
887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889 M_SRLX_IMM(s1, iptr->sx.val.i, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
898 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900 emit_store_dst(jd, iptr, d);
903 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
904 /* sx.val.i = constant */
906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
907 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
908 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
909 M_AND_IMM(s1, iptr->sx.val.i, d);
911 ICONST(REG_ITMP2, iptr->sx.val.i);
912 M_AND(s1, REG_ITMP2, d);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
918 /* sx.val.i = constant */
919 /* constant is actually constant - 1 */
921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
924 M_MOV(s1, REG_ITMP1);
927 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
928 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
929 M_AND_IMM(s1, iptr->sx.val.i, d);
932 M_SUB(REG_ZERO, s1, d);
933 M_AND_IMM(d, iptr->sx.val.i, d);
935 ICONST(REG_ITMP2, iptr->sx.val.i);
936 M_AND(s1, REG_ITMP2, d);
939 M_SUB(REG_ZERO, s1, d);
940 M_AND(d, REG_ITMP2, d);
942 M_SUB(REG_ZERO, d, d);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
947 /* sx.val.l = constant */
949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
952 M_AND_IMM(s1, iptr->sx.val.l, d);
954 LCONST(REG_ITMP2, iptr->sx.val.l);
955 M_AND(s1, REG_ITMP2, d);
957 emit_store_dst(jd, iptr, d);
960 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
961 /* sx.val.l = constant */
963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
964 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
966 M_MOV(s1, REG_ITMP1);
969 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
970 M_AND_IMM(s1, iptr->sx.val.l, d);
973 M_SUB(REG_ZERO, s1, d);
974 M_AND_IMM(d, iptr->sx.val.l, d);
976 LCONST(REG_ITMP2, iptr->sx.val.l);
977 M_AND(s1, REG_ITMP2, d);
980 M_SUB(REG_ZERO, s1, d);
981 M_AND(d, REG_ITMP2, d);
983 M_SUB(REG_ZERO, d, d);
984 emit_store_dst(jd, iptr, d);
987 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
990 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
991 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
994 emit_store_dst(jd, iptr, d);
997 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
998 /* sx.val.i = constant */
1000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1001 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1002 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1003 M_OR_IMM(s1, iptr->sx.val.i, d);
1005 ICONST(REG_ITMP2, iptr->sx.val.i);
1006 M_OR(s1, REG_ITMP2, d);
1008 emit_store_dst(jd, iptr, d);
1011 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1012 /* sx.val.l = constant */
1014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1017 M_OR_IMM(s1, iptr->sx.val.l, d);
1019 LCONST(REG_ITMP2, iptr->sx.val.l);
1020 M_OR(s1, REG_ITMP2, d);
1022 emit_store_dst(jd, iptr, d);
1025 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1028 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1029 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1030 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1036 /* sx.val.i = constant */
1038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1039 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1040 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1041 M_XOR_IMM(s1, iptr->sx.val.i, d);
1043 ICONST(REG_ITMP2, iptr->sx.val.i);
1044 M_XOR(s1, REG_ITMP2, d);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1050 /* sx.val.l = constant */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1055 M_XOR_IMM(s1, iptr->sx.val.l, d);
1057 LCONST(REG_ITMP2, iptr->sx.val.l);
1058 M_XOR(s1, REG_ITMP2, d);
1060 emit_store_dst(jd, iptr, d);
1064 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1068 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 M_XCMOVLT_IMM(-1, d);
1072 M_XCMOVGT_IMM(1, d);
1073 emit_store_dst(jd, iptr, d);
1077 /* floating operations ************************************************/
1079 case ICMD_FNEG: /* ..., value ==> ..., - value */
1081 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1082 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_DNEG: /* ..., value ==> ..., - value */
1089 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1090 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1092 emit_store_dst(jd, iptr, d);
1095 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1097 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1098 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1099 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1101 emit_store_dst(jd, iptr, d);
1104 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1106 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1107 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1108 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1115 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1124 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1125 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1126 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1128 emit_store_dst(jd, iptr, d);
1131 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1133 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1134 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1135 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1137 emit_store_dst(jd, iptr, d);
1140 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1142 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1143 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1144 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1146 emit_store_dst(jd, iptr, d);
1149 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1151 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1152 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1153 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1155 emit_store_dst(jd, iptr, d);
1158 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1160 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1161 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1162 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1164 emit_store_dst(jd, iptr, d);
1168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1169 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1170 disp = dseg_add_unique_float(cd, 0.0);
1171 M_IST (s1, REG_PV_CALLEE, disp);
1172 M_FLD (d, REG_PV_CALLEE, disp);
1173 M_CVTIF (d, d); /* rd gets translated to double target register */
1174 emit_store_dst(jd, iptr, d);
1178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1179 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1180 disp = dseg_add_unique_float(cd, 0.0);
1181 M_IST(s1, REG_PV_CALLEE, disp);
1182 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1183 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1184 emit_store_dst(jd, iptr, d);
1188 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1189 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1190 disp = dseg_add_unique_double(cd, 0.0);
1191 M_STX(s1, REG_PV_CALLEE, disp);
1192 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1193 M_CVTLF(REG_FTMP3, d);
1194 emit_store_dst(jd, iptr, d);
1198 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1199 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1200 disp = dseg_add_unique_double(cd, 0.0);
1201 M_STX(s1, REG_PV_CALLEE, disp);
1202 M_DLD(d, REG_PV_CALLEE, disp);
1204 emit_store_dst(jd, iptr, d);
1207 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1208 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1209 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1210 disp = dseg_add_unique_float(cd, 0.0);
1212 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1215 M_MOV(REG_ZERO, d); /* delay slot */
1217 M_CVTFI(s1, REG_FTMP2);
1218 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1219 M_ILD(d, REG_PV, disp);
1220 emit_store_dst(jd, iptr, d);
1224 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1225 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1227 disp = dseg_add_unique_float(cd, 0.0);
1229 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1232 M_MOV(REG_ZERO, d); /* delay slot */
1234 M_CVTDI(s1, REG_FTMP2);
1235 M_FST(REG_FTMP2, REG_PV, disp);
1236 M_ILD(d, REG_PV, disp);
1237 emit_store_dst(jd, iptr, d);
1240 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1241 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1243 disp = dseg_add_unique_double(cd, 0.0);
1245 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1248 M_MOV(REG_ZERO, d); /* delay slot */
1250 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1251 M_DST(REG_FTMP2, REG_PV, disp);
1252 M_LDX(d, REG_PV, disp);
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1257 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1258 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1259 disp = dseg_add_unique_double(cd, 0.0);
1261 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1264 M_MOV(REG_ZERO, d); /* delay slot */
1266 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1267 M_DST(REG_FTMP2, REG_PV, disp);
1268 M_LDX(d, REG_PV, disp);
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1274 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1275 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1277 emit_store_dst(jd, iptr, d);
1280 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1282 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1283 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1285 emit_store_dst(jd, iptr, d);
1288 /* XXX merge F/D versions? only compare instr. is different */
1289 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1291 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1295 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1296 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1297 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1303 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1304 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1305 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1307 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1308 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1309 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1310 emit_store_dst(jd, iptr, d);
1313 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1315 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1316 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1317 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1319 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1320 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1321 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1327 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1328 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1329 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1331 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1332 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1333 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1334 emit_store_dst(jd, iptr, d);
1338 /* memory operations **************************************************/
1340 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1343 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1344 emit_nullpointer_check(cd, iptr, s1);
1345 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1354 /* implicit null-pointer check */
1355 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1356 M_AADD(s2, s1, REG_ITMP3);
1357 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1358 emit_store_dst(jd, iptr, d);
1361 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1366 /* implicit null-pointer check */
1367 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1368 M_AADD(s2, s1, REG_ITMP3);
1369 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1370 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1371 emit_store_dst(jd, iptr, d);
1374 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1377 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1379 /* implicit null-pointer check */
1380 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1381 M_AADD(s2, s1, REG_ITMP3);
1382 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1383 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1384 emit_store_dst(jd, iptr, d);
1387 case ICMD_IALOAD: /* ..., 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_ASLL_IMM(s2, 2, REG_ITMP3);
1395 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1396 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1397 emit_store_dst(jd, iptr, d);
1400 case ICMD_LALOAD: /* ..., 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_ASLL_IMM(s2, 3, REG_ITMP3);
1408 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1409 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1410 emit_store_dst(jd, iptr, d);
1413 case ICMD_FALOAD: /* ..., 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_FTMP1);
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_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1423 emit_store_dst(jd, iptr, d);
1426 case ICMD_DALOAD: /* ..., 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_FTMP1);
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_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1436 emit_store_dst(jd, iptr, d);
1439 case ICMD_AALOAD: /* ..., 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_ITMP2);
1444 /* implicit null-pointer check */
1445 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1446 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1447 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1448 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1449 emit_store_dst(jd, iptr, d);
1453 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1457 /* implicit null-pointer check */
1458 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1459 M_AADD(s2, s1, REG_ITMP1);
1460 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1461 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1464 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1465 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1469 /* implicit null-pointer check */
1470 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1471 M_AADD(s2, s1, REG_ITMP1);
1472 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1473 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1474 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1477 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1479 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1480 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1481 /* implicit null-pointer check */
1482 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1483 M_ASLL_IMM(s2, 2, REG_ITMP2);
1484 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1485 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1486 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1489 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1493 /* implicit null-pointer check */
1494 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1495 M_ASLL_IMM(s2, 3, REG_ITMP2);
1496 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1497 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1498 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1501 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1504 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1505 /* implicit null-pointer check */
1506 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1507 M_ASLL_IMM(s2, 2, REG_ITMP2);
1508 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1509 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1510 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1513 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1517 /* implicit null-pointer check */
1518 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1519 M_ASLL_IMM(s2, 3, REG_ITMP2);
1520 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1521 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1522 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1526 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1529 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1530 /* implicit null-pointer check */
1531 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1532 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1534 M_MOV(s1, REG_OUT0);
1535 M_MOV(s3, REG_OUT1);
1536 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1537 M_ALD(REG_ITMP3, REG_PV, disp);
1538 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1540 emit_exception_check(cd, iptr);
1542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1543 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1544 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1545 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1546 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1547 /* implicit null-pointer check */
1548 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1552 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
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 M_AADD(s2, s1, REG_ITMP1);
1559 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1562 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1563 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1566 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1567 /* implicit null-pointer check */
1568 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1569 M_AADD(s2, s1, REG_ITMP1);
1570 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1571 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1574 case ICMD_IASTORECONST: /* ..., 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_ASLL_IMM(s2, 2, REG_ITMP2);
1581 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1582 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1585 case ICMD_LASTORECONST: /* ..., 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_ASLL_IMM(s2, 3, REG_ITMP2);
1592 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1593 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1596 case ICMD_AASTORECONST: /* ..., 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, POINTERSHIFT, REG_ITMP2);
1603 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1604 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1608 case ICMD_GETSTATIC: /* ... ==> ..., value */
1610 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1611 uf = iptr->sx.s23.s3.uf;
1612 fieldtype = uf->fieldref->parseddesc.fd->type;
1613 disp = dseg_add_unique_address(cd, uf);
1615 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1618 fi = iptr->sx.s23.s3.fmiref->p.field;
1619 fieldtype = fi->type;
1620 disp = dseg_add_address(cd, &(fi->value));
1622 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1623 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1626 M_ALD(REG_ITMP1, REG_PV, disp);
1628 switch (fieldtype) {
1630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1631 M_ILD_INTERN(d, REG_ITMP1, 0);
1634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1635 M_LDX_INTERN(d, REG_ITMP1, 0);
1638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1639 M_ALD_INTERN(d, REG_ITMP1, 0);
1642 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1643 M_FLD_INTERN(d, REG_ITMP1, 0);
1646 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1647 M_DLD_INTERN(d, REG_ITMP1, 0);
1650 emit_store_dst(jd, iptr, d);
1653 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1655 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1656 uf = iptr->sx.s23.s3.uf;
1657 fieldtype = uf->fieldref->parseddesc.fd->type;
1658 disp = dseg_add_unique_address(cd, uf);
1660 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1663 fi = iptr->sx.s23.s3.fmiref->p.field;
1664 fieldtype = fi->type;
1665 disp = dseg_add_address(cd, &(fi->value));
1667 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1668 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1671 M_ALD(REG_ITMP1, REG_PV, disp);
1673 switch (fieldtype) {
1675 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1676 M_IST_INTERN(s1, REG_ITMP1, 0);
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1680 M_STX_INTERN(s1, REG_ITMP1, 0);
1683 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1684 M_AST_INTERN(s1, REG_ITMP1, 0);
1687 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1688 M_FST_INTERN(s1, REG_ITMP1, 0);
1691 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1692 M_DST_INTERN(s1, REG_ITMP1, 0);
1697 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1698 /* val = value (in current instruction) */
1699 /* following NOP) */
1701 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1702 uf = iptr->sx.s23.s3.uf;
1703 fieldtype = uf->fieldref->parseddesc.fd->type;
1704 disp = dseg_add_unique_address(cd, uf);
1706 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1709 fi = iptr->sx.s23.s3.fmiref->p.field;
1710 fieldtype = fi->type;
1711 disp = dseg_add_address(cd, &(fi->value));
1713 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1714 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1717 M_ALD(REG_ITMP1, REG_PV, disp);
1719 switch (fieldtype) {
1721 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1724 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1727 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1730 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1733 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1739 case ICMD_GETFIELD: /* ... ==> ..., value */
1741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1742 emit_nullpointer_check(cd, iptr, s1);
1744 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1745 uf = iptr->sx.s23.s3.uf;
1747 fieldtype = uf->fieldref->parseddesc.fd->type;
1750 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1753 fi = iptr->sx.s23.s3.fmiref->p.field;
1754 fieldtype = fi->type;
1758 switch (fieldtype) {
1760 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1764 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1772 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1776 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1783 emit_store_dst(jd, iptr, d);
1786 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1789 emit_nullpointer_check(cd, iptr, s1);
1791 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1792 uf = iptr->sx.s23.s3.uf;
1793 fieldtype = uf->fieldref->parseddesc.fd->type;
1798 fi = iptr->sx.s23.s3.fmiref->p.field;
1799 fieldtype = fi->type;
1803 if (IS_INT_LNG_TYPE(fieldtype))
1804 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1806 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1808 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1809 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1811 switch (fieldtype) {
1813 M_IST(s2, s1, disp);
1816 M_STX(s2, s1, disp);
1819 M_AST(s2, s1, disp);
1822 M_FST(s2, s1, disp);
1825 M_DST(s2, s1, disp);
1833 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1834 /* val = value (in current instruction) */
1835 /* following NOP) */
1837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1838 emit_nullpointer_check(cd, iptr, s1);
1840 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1841 unresolved_field *uf = iptr->sx.s23.s3.uf;
1843 fieldtype = uf->fieldref->parseddesc.fd->type;
1845 codegen_addpatchref(cd, PATCHER_get_putfield,
1848 if (opt_showdisassemble) {
1856 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1858 fieldtype = fi->type;
1864 switch (fieldtype) {
1866 M_IST(REG_ZERO, s1, disp);
1869 M_STX(REG_ZERO, s1, disp);
1872 M_AST(REG_ZERO, s1, disp);
1875 M_FST(REG_ZERO, s1, disp);
1878 M_DST(REG_ZERO, s1, disp);
1884 /* branch operations **************************************************/
1886 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1889 M_INTMOVE(s1, REG_ITMP2_XPTR);
1891 #ifdef ENABLE_VERIFIER
1892 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1893 unresolved_class *uc = iptr->sx.s23.s2.uc;
1895 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1897 #endif /* ENABLE_VERIFIER */
1899 disp = dseg_add_functionptr(cd, asm_handle_exception);
1900 M_ALD(REG_ITMP1, REG_PV, disp);
1901 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1903 M_NOP; /* nop ensures that XPC is less than the end */
1904 /* of basic block */
1908 case ICMD_GOTO: /* ... ==> ... */
1909 case ICMD_RET: /* ... ==> ... */
1911 emit_br(cd, iptr->dst.block);
1915 case ICMD_JSR: /* ... ==> ... */
1917 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1921 case ICMD_IFNULL: /* ..., value ==> ... */
1922 case ICMD_IFNONNULL:
1924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1925 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1928 /* Note: int compares must not branch on the register directly. */
1929 /* Reason is, that register content is not 32-bit clean. */
1931 case ICMD_IFEQ: /* ..., value ==> ... */
1933 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1935 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1936 M_CMP_IMM(s1, iptr->sx.val.i);
1939 ICONST(REG_ITMP2, iptr->sx.val.i);
1940 M_CMP(s1, REG_ITMP2);
1942 emit_beq(cd, iptr->dst.block);
1945 case ICMD_IFLT: /* ..., value ==> ... */
1947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1949 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1950 M_CMP_IMM(s1, iptr->sx.val.i);
1953 ICONST(REG_ITMP2, iptr->sx.val.i);
1954 M_CMP(s1, REG_ITMP2);
1956 emit_blt(cd, iptr->dst.block);
1959 case ICMD_IFLE: /* ..., value ==> ... */
1961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1963 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1964 M_CMP_IMM(s1, iptr->sx.val.i);
1967 ICONST(REG_ITMP2, iptr->sx.val.i);
1968 M_CMP(s1, REG_ITMP2);
1970 emit_ble(cd, iptr->dst.block);
1973 case ICMD_IFNE: /* ..., value ==> ... */
1975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1977 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1978 M_CMP_IMM(s1, iptr->sx.val.i);
1981 ICONST(REG_ITMP2, iptr->sx.val.i);
1982 M_CMP(s1, REG_ITMP2);
1984 emit_bne(cd, iptr->dst.block);
1987 case ICMD_IFGT: /* ..., value ==> ... */
1989 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1991 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1992 M_CMP_IMM(s1, iptr->sx.val.i);
1995 ICONST(REG_ITMP2, iptr->sx.val.i);
1996 M_CMP(s1, REG_ITMP2);
1998 emit_bgt(cd, iptr->dst.block);
2001 case ICMD_IFGE: /* ..., value ==> ... */
2003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2005 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2006 M_CMP_IMM(s1, iptr->sx.val.i);
2009 ICONST(REG_ITMP2, iptr->sx.val.i);
2010 M_CMP(s1, REG_ITMP2);
2012 emit_bge(cd, iptr->dst.block);
2015 case ICMD_IF_LEQ: /* ..., value ==> ... */
2017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2018 if (iptr->sx.val.l == 0)
2019 emit_beqz(cd, iptr->dst.block, s1);
2021 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2022 M_CMP_IMM(s1, iptr->sx.val.l);
2025 LCONST(REG_ITMP2, iptr->sx.val.l);
2026 M_CMP(s1, REG_ITMP2);
2028 emit_beq_xcc(cd, iptr->dst.block);
2032 case ICMD_IF_LLT: /* ..., value ==> ... */
2034 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2035 if (iptr->sx.val.l == 0)
2036 emit_bltz(cd, iptr->dst.block, s1);
2038 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2039 M_CMP_IMM(s1, iptr->sx.val.l);
2042 LCONST(REG_ITMP2, iptr->sx.val.l);
2043 M_CMP(s1, REG_ITMP2);
2045 emit_blt_xcc(cd, iptr->dst.block);
2049 case ICMD_IF_LLE: /* ..., value ==> ... */
2051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052 if (iptr->sx.val.l == 0)
2053 emit_blez(cd, iptr->dst.block, s1);
2055 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2056 M_CMP_IMM(s1, iptr->sx.val.l);
2059 LCONST(REG_ITMP2, iptr->sx.val.l);
2060 M_CMP(s1, REG_ITMP2);
2062 emit_ble_xcc(cd, iptr->dst.block);
2066 case ICMD_IF_LNE: /* ..., value ==> ... */
2068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2069 if (iptr->sx.val.l == 0)
2070 emit_bnez(cd, iptr->dst.block, s1);
2072 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2073 M_CMP_IMM(s1, iptr->sx.val.l);
2076 LCONST(REG_ITMP2, iptr->sx.val.l);
2077 M_CMP(s1, REG_ITMP2);
2079 emit_bne_xcc(cd, iptr->dst.block);
2083 case ICMD_IF_LGT: /* ..., value ==> ... */
2085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2086 if (iptr->sx.val.l == 0)
2087 emit_bgtz(cd, iptr->dst.block, s1);
2089 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2090 M_CMP_IMM(s1, iptr->sx.val.l);
2093 LCONST(REG_ITMP2, iptr->sx.val.l);
2094 M_CMP(s1, REG_ITMP2);
2096 emit_bgt_xcc(cd, iptr->dst.block);
2100 case ICMD_IF_LGE: /* ..., value ==> ... */
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103 if (iptr->sx.val.l == 0)
2104 emit_bgez(cd, iptr->dst.block, s1);
2106 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2107 M_CMP_IMM(s1, iptr->sx.val.l);
2110 LCONST(REG_ITMP2, iptr->sx.val.l);
2111 M_CMP(s1, REG_ITMP2);
2113 emit_bge_xcc(cd, iptr->dst.block);
2118 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2119 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2124 emit_beq_xcc(cd, iptr->dst.block);
2127 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2130 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2132 emit_beq(cd, iptr->dst.block);
2135 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2136 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2138 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2139 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2141 emit_bne_xcc(cd, iptr->dst.block);
2144 case ICMD_IF_ICMPNE: /* 32-bit compare */
2146 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2147 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2149 emit_bne(cd, iptr->dst.block);
2152 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2157 emit_blt_xcc(cd, iptr->dst.block);
2160 case ICMD_IF_ICMPLT: /* 32-bit compare */
2162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2165 emit_blt(cd, iptr->dst.block);
2168 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2173 emit_bgt_xcc(cd, iptr->dst.block);
2176 case ICMD_IF_ICMPGT: /* 32-bit compare */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2181 emit_bgt(cd, iptr->dst.block);
2184 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2186 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2187 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2189 emit_ble_xcc(cd, iptr->dst.block);
2192 case ICMD_IF_ICMPLE: /* 32-bit compare */
2194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2197 emit_ble(cd, iptr->dst.block);
2201 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2203 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2204 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2206 emit_bge_xcc(cd, iptr->dst.block);
2209 case ICMD_IF_ICMPGE: /* 32-bit compare */
2211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2212 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2214 emit_bge(cd, iptr->dst.block);
2218 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2221 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2222 M_INTMOVE(s1, REG_RESULT_CALLEE);
2223 goto nowperformreturn;
2225 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2227 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2228 M_INTMOVE(s1, REG_RESULT_CALLEE);
2230 #ifdef ENABLE_VERIFIER
2231 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2232 unresolved_class *uc = iptr->sx.s23.s2.uc;
2234 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2236 #endif /* ENABLE_VERIFIER */
2237 goto nowperformreturn;
2239 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2242 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2243 M_DBLMOVE(s1, REG_FRESULT);
2244 goto nowperformreturn;
2246 case ICMD_RETURN: /* ... ==> ... */
2252 p = cd->stackframesize;
2254 #if !defined(NDEBUG)
2255 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2256 emit_verbosecall_exit(jd);
2259 #if defined(ENABLE_THREADS)
2260 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2261 /* XXX jit-c-call */
2262 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2263 M_ALD(REG_ITMP3, REG_PV, disp);
2265 /* we need to save fp return value (int saved by window) */
2267 switch (iptr->opc) {
2270 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2271 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2272 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2274 /* restore the fp return value */
2276 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2282 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2283 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2294 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2300 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2303 branch_target_t *table;
2305 table = iptr->dst.table;
2307 l = iptr->sx.s23.s2.tablelow;
2308 i = iptr->sx.s23.s3.tablehigh;
2310 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2312 M_INTMOVE(s1, REG_ITMP1);
2314 else if (l <= 4095) {
2315 M_ADD_IMM(s1, -l, REG_ITMP1);
2318 ICONST(REG_ITMP2, l);
2319 /* XXX: do I need to truncate s1 to 32-bit ? */
2320 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2328 M_CMP_IMM(REG_ITMP1, i - 1);
2331 ICONST(REG_ITMP2, i - 1);
2332 M_CMP(REG_ITMP1, REG_ITMP2);
2334 emit_bugt(cd, table[0].block); /* default target */
2336 /* build jump table top down and use address of lowest entry */
2341 dseg_add_target(cd, table->block);
2346 /* length of dataseg after last dseg_addtarget is used by load */
2348 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2349 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2350 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2351 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2356 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2359 lookup_target_t *lookup;
2361 lookup = iptr->dst.lookup;
2363 i = iptr->sx.s23.s2.lookupcount;
2365 MCODECHECK((i<<2)+8);
2366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2369 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2370 M_CMP_IMM(s1, lookup->value);
2372 ICONST(REG_ITMP2, lookup->value);
2373 M_CMP(s1, REG_ITMP2);
2375 emit_beq(cd, lookup->target.block);
2379 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2385 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2387 bte = iptr->sx.s23.s3.bte;
2390 /* XXX: builtin calling with stack arguments not implemented */
2391 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2393 s3 = md->paramcount;
2395 MCODECHECK((s3 << 1) + 64);
2397 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2399 /* copy float arguments according to ABI convention */
2401 int num_fltregargs = 0;
2402 int fltregarg_inswap[16];
2404 for (s3 = s3 - 1; s3 >= 0; s3--) {
2405 var = VAR(iptr->sx.s23.s2.args[s3]);
2407 if (IS_FLT_DBL_TYPE(var->type)) {
2408 if (!md->params[s3].inmemory) {
2409 s1 = s3; /*native flt args use argument index directly*/
2410 d = emit_load(jd, iptr, var, REG_FTMP1);
2413 fltregarg_inswap[num_fltregargs] = s1;
2415 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2424 /* move swapped float args to target regs */
2425 for (i = 0; i < num_fltregargs; i++) {
2426 s1 = fltregarg_inswap[i];
2427 M_DMOV(s1 + 16, s1);
2428 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2432 assert(md->argfltreguse == 0);
2437 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2439 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2440 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2441 case ICMD_INVOKEINTERFACE:
2443 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2445 um = iptr->sx.s23.s3.um;
2446 md = um->methodref->parseddesc.md;
2449 lm = iptr->sx.s23.s3.fmiref->p.method;
2451 md = lm->parseddesc;
2455 s3 = md->paramcount;
2457 MCODECHECK((s3 << 1) + 64);
2459 /* copy arguments to registers or stack location */
2461 for (s3 = s3 - 1; s3 >= 0; s3--) {
2462 var = VAR(iptr->sx.s23.s2.args[s3]);
2463 d = md->params[s3].regoff;
2465 if (var->flags & PREALLOC)
2468 if (IS_INT_LNG_TYPE(var->type)) {
2469 if (!md->params[s3].inmemory) {
2470 s1 = emit_load(jd, iptr, var, d);
2474 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2475 M_STX(s1, REG_SP, JITSTACK + d);
2479 #ifdef BUILTIN_FLOAT_ARGS
2480 if (iptr->opc == ICMD_BUILTIN)
2484 if (!md->params[s3].inmemory) {
2485 s1 = emit_load(jd, iptr, var, d);
2486 if (IS_2_WORD_TYPE(var->type))
2492 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2493 M_DST(s1, REG_SP, JITSTACK + d);
2498 switch (iptr->opc) {
2500 disp = dseg_add_functionptr(cd, bte->fp);
2502 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2504 /* XXX jit-c-call */
2505 /* generate the actual call */
2507 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2509 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2510 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2511 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2513 emit_exception_check(cd, iptr);
2514 if (md->returntype.type == TYPE_FLT) {
2515 /* special handling for float return value in %f0 */
2520 case ICMD_INVOKESPECIAL:
2521 emit_nullpointer_check(cd, iptr, REG_OUT0);
2524 case ICMD_INVOKESTATIC:
2526 disp = dseg_add_unique_address(cd, NULL);
2528 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2532 disp = dseg_add_address(cd, lm->stubroutine);
2534 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2536 /* generate the actual call */
2538 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2540 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2541 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2542 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2545 case ICMD_INVOKEVIRTUAL:
2546 emit_nullpointer_check(cd, iptr, REG_OUT0);
2549 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2554 s1 = OFFSET(vftbl_t, table[0]) +
2555 sizeof(methodptr) * lm->vftblindex;
2557 /* implicit null-pointer check */
2558 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2559 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2561 /* generate the actual call */
2563 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2565 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2566 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2567 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2570 case ICMD_INVOKEINTERFACE:
2571 emit_nullpointer_check(cd, iptr, REG_OUT0);
2574 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2580 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2581 sizeof(methodptr*) * lm->class->index;
2583 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2586 /* implicit null-pointer check */
2587 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2588 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2589 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2591 /* generate the actual call */
2593 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2595 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2596 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2597 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2601 /* store return value */
2603 d = md->returntype.type;
2605 if (d != TYPE_VOID) {
2606 if (IS_INT_LNG_TYPE(d)) {
2607 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2608 M_INTMOVE(REG_RESULT_CALLER, s1);
2611 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2612 if (IS_2_WORD_TYPE(d)) {
2613 M_DBLMOVE(REG_FRESULT, s1);
2615 M_FLTMOVE(REG_FRESULT, s1);
2618 emit_store_dst(jd, iptr, s1);
2623 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2624 /* val.a: (classinfo*) superclass */
2626 /* superclass is an interface:
2628 * OK if ((sub == NULL) ||
2629 * (sub->vftbl->interfacetablelength > super->index) &&
2630 * (sub->vftbl->interfacetable[-super->index] != NULL));
2632 * superclass is a class:
2634 * OK if ((sub == NULL) || (0
2635 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2636 * super->vftbl->diffvall));
2639 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2643 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2648 super = iptr->sx.s23.s3.c.cls;
2649 superindex = super->index;
2652 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2653 CODEGEN_CRITICAL_SECTION_NEW;
2655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2657 /* if class is not resolved, check which code to call */
2659 if (super == NULL) {
2660 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2662 cr = iptr->sx.s23.s3.c.ref;
2663 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2665 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2668 M_ILD(REG_ITMP2, REG_PV, disp);
2669 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2670 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2673 /* interface checkcast code */
2675 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2676 if (super == NULL) {
2677 cr = iptr->sx.s23.s3.c.ref;
2679 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2683 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2686 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2687 M_ILD(REG_ITMP3, REG_ITMP2,
2688 OFFSET(vftbl_t, interfacetablelength));
2689 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2690 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2692 M_ALD(REG_ITMP3, REG_ITMP2,
2693 OFFSET(vftbl_t, interfacetable[0]) -
2694 superindex * sizeof(methodptr*));
2695 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2698 emit_label_br(cd, BRANCH_LABEL_4);
2700 emit_label(cd, BRANCH_LABEL_3);
2703 /* class checkcast code */
2705 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2706 if (super == NULL) {
2707 emit_label(cd, BRANCH_LABEL_2);
2709 cr = iptr->sx.s23.s3.c.ref;
2710 disp = dseg_add_unique_address(cd, NULL);
2712 codegen_add_patch_ref(cd,
2713 PATCHER_checkcast_instanceof_class,
2717 disp = dseg_add_address(cd, super->vftbl);
2719 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2722 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2723 M_ALD(REG_ITMP3, REG_PV, disp);
2725 CODEGEN_CRITICAL_SECTION_START;
2727 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2728 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2729 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2730 M_ALD(REG_ITMP3, REG_PV, disp);
2731 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2733 CODEGEN_CRITICAL_SECTION_END;
2736 M_CMP(REG_ITMP3, REG_ITMP2);
2737 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2740 emit_label(cd, BRANCH_LABEL_5);
2743 if (super == NULL) {
2744 emit_label(cd, BRANCH_LABEL_1);
2745 emit_label(cd, BRANCH_LABEL_4);
2748 d = codegen_reg_of_dst(jd, iptr, s1);
2751 /* array type cast-check */
2753 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2754 M_INTMOVE(s1, REG_OUT0);
2756 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2758 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2759 cr = iptr->sx.s23.s3.c.ref;
2760 disp = dseg_add_unique_address(cd, NULL);
2762 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2766 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2768 M_ALD(REG_OUT1, REG_PV, disp);
2769 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2770 M_ALD(REG_ITMP3, REG_PV, disp);
2771 /* XXX jit-c-call */
2772 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2776 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2778 d = codegen_reg_of_dst(jd, iptr, s1);
2782 emit_store_dst(jd, iptr, d);
2785 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2786 /* val.a: (classinfo*) superclass */
2788 /* superclass is an interface:
2790 * return (sub != NULL) &&
2791 * (sub->vftbl->interfacetablelength > super->index) &&
2792 * (sub->vftbl->interfacetable[-super->index] != NULL);
2794 * superclass is a class:
2796 * return ((sub != NULL) && (0
2797 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2798 * super->vftbl->diffvall));
2803 vftbl_t *supervftbl;
2806 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2812 super = iptr->sx.s23.s3.c.cls;
2813 superindex = super->index;
2814 supervftbl = super->vftbl;
2817 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2818 CODEGEN_CRITICAL_SECTION_NEW;
2820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2823 M_MOV(s1, REG_ITMP1);
2829 /* if class is not resolved, check which code to call */
2831 if (super == NULL) {
2832 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2834 cr = iptr->sx.s23.s3.c.ref;
2835 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2837 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2840 M_ILD(REG_ITMP3, REG_PV, disp);
2841 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2842 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2845 /* interface instanceof code */
2847 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2848 if (super == NULL) {
2849 cr = iptr->sx.s23.s3.c.ref;
2851 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2855 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2858 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2859 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2860 M_CMP_IMM(REG_ITMP3, superindex);
2863 M_ALD(REG_ITMP1, REG_ITMP1,
2864 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2865 superindex * sizeof(methodptr*)));
2866 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2869 emit_label_br(cd, BRANCH_LABEL_4);
2871 emit_label(cd, BRANCH_LABEL_3);
2874 /* class instanceof code */
2876 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2877 if (super == NULL) {
2878 emit_label(cd, BRANCH_LABEL_2);
2880 cr = iptr->sx.s23.s3.c.ref;
2881 disp = dseg_add_unique_address(cd, NULL);
2883 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2887 disp = dseg_add_address(cd, supervftbl);
2889 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2892 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2893 M_ALD(REG_ITMP2, REG_PV, disp);
2895 CODEGEN_CRITICAL_SECTION_START;
2897 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2898 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2899 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2901 CODEGEN_CRITICAL_SECTION_END;
2903 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2904 M_CMP(REG_ITMP1, REG_ITMP2);
2905 M_XCMOVULE_IMM(1, d);
2908 emit_label(cd, BRANCH_LABEL_5);
2911 if (super == NULL) {
2912 emit_label(cd, BRANCH_LABEL_1);
2913 emit_label(cd, BRANCH_LABEL_4);
2916 emit_store_dst(jd, iptr, d);
2920 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2922 /* check for negative sizes and copy sizes to stack if necessary */
2924 MCODECHECK((iptr->s1.argcount << 1) + 64);
2926 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2928 var = VAR(iptr->sx.s23.s2.args[s1]);
2930 /* copy SAVEDVAR sizes to stack */
2932 /* Already Preallocated? */
2934 if (!(var->flags & PREALLOC)) {
2935 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2936 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2940 /* arg 0 = dimension count */
2942 ICONST(REG_OUT0, iptr->s1.argcount);
2944 /* is patcher function set? */
2946 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2947 disp = dseg_add_unique_address(cd, 0);
2949 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2950 iptr->sx.s23.s3.c.ref,
2954 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2956 /* arg 1 = arraydescriptor */
2958 M_ALD(REG_OUT1, REG_PV, disp);
2960 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2962 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2964 /* XXX c abi call */
2965 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2966 M_ALD(REG_ITMP3, REG_PV, disp);
2967 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2970 /* check for exception before result assignment */
2972 emit_exception_check(cd, iptr);
2974 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2975 M_INTMOVE(REG_RESULT_CALLER, d);
2976 emit_store_dst(jd, iptr, d);
2980 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2986 } /* for instruction */
2990 /* At the end of a basic block we may have to append some nops,
2991 because the patcher stub calling code might be longer than the
2992 actual instruction. So codepatching does not change the
2993 following block unintentionally. */
2995 if (cd->mcodeptr < cd->lastmcodeptr) {
2996 while (cd->mcodeptr < cd->lastmcodeptr) {
3001 } /* if (bptr -> flags >= BBREACHED) */
3002 } /* for basic block */
3004 dseg_createlinenumbertable(cd);
3006 /* generate stubs */
3008 emit_patcher_stubs(jd);
3009 REPLACEMENT_EMIT_STUBS(jd);
3011 /* everything's ok */
3017 /* codegen_emit_stub_compiler **************************************************
3019 Emits a stub routine which calls the compiler.
3021 *******************************************************************************/
3023 void codegen_emit_stub_compiler(jitdata *jd)
3028 /* get required compiler data */
3033 /* code for the stub */
3035 /* no window save yet, user caller's PV */
3036 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3037 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3038 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3043 /* codegen_emit_stub_native ****************************************************
3045 Emits a stub routine which calls a native method.
3047 *******************************************************************************/
3049 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3056 s4 i, j; /* count variables */
3059 s4 funcdisp; /* displacement of the function */
3060 s4 fltregarg_offset[FLT_ARG_CNT];
3062 /* get required compiler data */
3068 /* initialize variables */
3071 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3073 /* calculate stack frame size */
3075 cd->stackframesize =
3076 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3077 sizeof(localref_table) / SIZEOF_VOID_P +
3078 md->paramcount + /* for saving arguments over calls */
3079 nmd->memuse + /* nmd knows about the native stackframe layout */
3083 /* keep stack 16-byte aligned (ABI requirement) */
3085 if (cd->stackframesize & 1)
3086 cd->stackframesize++;
3088 /* create method header */
3090 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3091 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3092 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3093 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3094 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3095 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3096 (void) dseg_addlinenumbertablesize(cd);
3097 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3099 /* generate stub code */
3101 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3103 #if !defined(NDEBUG)
3104 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3105 emit_verbosecall_enter(jd);
3108 /* get function address (this must happen before the stackframeinfo) */
3110 funcdisp = dseg_add_functionptr(cd, f);
3112 #if !defined(WITH_STATIC_CLASSPATH)
3114 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3118 /* save float argument registers (into abi parameter slots) */
3120 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3122 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3123 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3124 s1 = WINSAVE_CNT + nmd->memuse + j;
3125 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3126 fltregarg_offset[i] = s1; /* remember stack offset */
3131 /* prepare data structures for native function call */
3133 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3134 M_MOV(REG_PV_CALLEE, REG_OUT1);
3135 M_MOV(REG_FP, REG_OUT2); /* java sp */
3136 M_MOV(REG_RA_CALLEE, REG_OUT3);
3137 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3138 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3139 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3140 M_NOP; /* XXX fill me! */
3142 /* keep float arguments on stack */
3144 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3145 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3146 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3152 /* copy or spill arguments to new locations */
3154 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3155 t = md->paramtypes[i].type;
3157 if (IS_INT_LNG_TYPE(t)) {
3159 /* integral types */
3161 if (!md->params[i].inmemory) {
3162 s1 = md->params[i].regoff;
3163 /* s1 refers to the old window, transpose */
3164 s1 = REG_WINDOW_TRANSPOSE(s1);
3166 if (!nmd->params[j].inmemory) {
3167 s2 = nat_argintregs[nmd->params[j].regoff];
3170 s2 = nmd->params[j].regoff - 6 * 8;
3171 M_AST(s1, REG_SP, CSTACK + s2);
3175 if (!nmd->params[j].inmemory) {
3176 /* JIT stack arg -> NAT reg arg */
3178 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3179 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3181 assert(false); /* path never taken */
3184 s1 = md->params[i].regoff + cd->stackframesize * 8;
3185 s2 = nmd->params[j].regoff - 6 * 8;
3186 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3187 M_AST(REG_ITMP1, REG_SP, CSTACK + s2);
3192 /* floating point types */
3194 if (!md->params[i].inmemory) {
3195 s1 = md->params[i].regoff;
3197 if (!nmd->params[j].inmemory) {
3199 /* no mapping to regs needed, native flt args use regoff */
3200 s2 = nmd->params[j].regoff;
3202 /* JIT float regs are still on the stack */
3203 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3206 /* not supposed to happen with 16 NAT flt args */
3209 s2 = nmd->params[j].regoff;
3210 if (IS_2_WORD_TYPE(t))
3211 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3213 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3219 s1 = md->params[i].regoff + cd->stackframesize * 8;
3221 if (!nmd->params[j].inmemory) {
3223 /* JIT stack -> NAT reg */
3225 s2 = nmd->params[j].regoff;
3226 M_DLD(s2, REG_SP, CSTACK + s1);
3230 /* JIT stack -> NAT stack */
3232 s2 = nmd->params[j].regoff - 6 * 8;
3234 /* The FTMP register may already be loaded with args */
3235 /* we know $f0 is unused because of the env pointer */
3236 M_DLD(REG_F0, REG_SP, CSTACK + s1);
3237 M_DST(REG_F0, REG_SP, CSTACK + s2);
3244 /* put class into second argument register */
3246 if (m->flags & ACC_STATIC) {
3247 disp = dseg_add_address(cd, m->class);
3248 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3251 /* put env into first argument register */
3253 disp = dseg_add_address(cd, _Jv_env);
3254 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3256 /* do the native function call */
3258 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3259 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3260 M_NOP; /* delay slot */
3262 /* save return value */
3264 if (md->returntype.type != TYPE_VOID) {
3265 if (IS_INT_LNG_TYPE(md->returntype.type))
3266 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3268 M_DST(REG_FRESULT, REG_SP, CSTACK);
3271 /* Note: native functions return float values in %f0 (see ABI) */
3272 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3274 #if !defined(NDEBUG)
3275 /* But for the trace function we need to put a flt result into %f1 */
3276 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3277 if (!IS_2_WORD_TYPE(md->returntype.type))
3278 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3279 emit_verbosecall_exit(jd);
3283 /* remove native stackframe info */
3285 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3286 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3287 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3288 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3289 M_NOP; /* XXX fill me! */
3290 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3292 /* restore float return value, int return value already in our return reg */
3294 if (md->returntype.type != TYPE_VOID) {
3295 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3296 if (IS_2_WORD_TYPE(md->returntype.type))
3297 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3299 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3303 /* check for exception */
3304 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3307 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3310 /* handle exception */
3312 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3313 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3314 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3315 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3316 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3318 /* generate patcher stubs */
3320 emit_patcher_stubs(jd);
3324 * These are local overrides for various environment variables in Emacs.
3325 * Please do not remove this and leave it at the end of the file, where
3326 * Emacs will automagically detect them.
3327 * ---------------------------------------------------------------------
3330 * indent-tabs-mode: t
3334 * vim:noexpandtab:sw=4:ts=4: