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
38 /* #include "vm/jit/sparc64/arch.h" */
39 #include "vm/jit/sparc64/codegen.h"
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/localref.h"
45 #include "native/native.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
50 #include "vm/jit/abi.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/codegen-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/sparc64/emit.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/patcher.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
65 #include "vm/jit/sparc64/solaris/macro_rename.h"
67 #define BUILTIN_FLOAT_ARGS 1
69 /* XXX use something like this for window control ?
70 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
72 #define REG_PV REG_PV_CALLEE
77 if ((disp < -4096) || (disp > 4095))
78 printf("disp %d\n", disp);
81 return (disp >= -4096) && (disp <= 4095);
84 s4 get_lopart_disp(disp)
89 lodisp = setlo_part(disp);
91 if (setlo_part(disp) == 0)
94 lodisp = setlo_part(disp) | 0x1c00;
101 bool check_13bit_imm(s8 imm)
103 s4 sign = (imm >> 12) & 0x1;
106 if ((imm & ~0xfff) == 0) return true; /* pos imm. */
109 if ((imm & ~0xfff) + 0xfff == -1) return true; /* neg imm. */
111 printf("immediate out-of-bounds: %ld\n", imm);
117 /* codegen_emit ****************************************************************
119 Generates machine code.
121 *******************************************************************************/
123 bool codegen_emit(jitdata *jd)
129 s4 len, s1, s2, s3, d, disp, slots;
135 constant_classref *cr;
136 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
137 unresolved_method *um;
138 builtintable_entry *bte;
141 unresolved_field *uf;
145 /* get required compiler data */
152 /* prevent compiler warnings */
164 #if 0 /* no leaf optimization yet */
165 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
167 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
170 /* space to save used callee saved registers */
172 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
173 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
175 cd->stackframesize = rd->memuse + savedregs_num;
177 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
178 if (checksync && (m->flags & ACC_SYNCHRONIZED))
179 cd->stackframesize++;
182 /* keep stack 16-byte aligned (ABI requirement) */
184 if (cd->stackframesize & 1)
185 cd->stackframesize++;
187 /* create method header */
189 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
190 framesize_disp = dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
192 #if defined(ENABLE_THREADS)
193 /* IsSync contains the offset relative to the stack pointer for the
194 argument of monitor_exit used in the exception handler. Since the
195 offset could be zero and give a wrong meaning of the flag it is
199 if (checksync && (m->flags & ACC_SYNCHRONIZED))
200 (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
203 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
205 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
206 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
207 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
208 dseg_addlinenumbertablesize(cd);
209 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
211 /* create exception table */
213 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
214 dseg_add_target(cd, ex->start);
215 dseg_add_target(cd, ex->end);
216 dseg_add_target(cd, ex->handler);
217 (void) dseg_add_unique_address(cd, ex->catchtype.any);
220 /* save register window and create stack frame (if necessary) */
222 if (cd->stackframesize) {
223 if (cd->stackframesize <= 4095)
224 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
226 M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
227 M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
228 M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
232 /* save callee saved float registers (none right now) */
234 p = cd->stackframesize;
235 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
236 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
241 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
242 emit_verbosecall_enter(jd);
246 /* call monitorenter function */
247 #if defined(ENABLE_THREADS)
248 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
249 /* stack offset for monitor argument */
253 /* save float argument registers */
257 ALIGN_STACK_SLOTS(slots);
259 M_LDA(REG_SP, REG_SP, -(slots * 8));
260 for (i = 0; i < FLT_ARG_CNT; i++)
261 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
265 /* get correct lock object */
267 if (m->flags & ACC_STATIC) {
268 disp = dseg_add_address(cd, &m->class->object.header);
269 M_ALD(REG_OUT0, REG_PV, disp);
270 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
271 M_ALD(REG_ITMP3, REG_PV, disp);
274 /* copy class pointer: $i0 -> $o0 */
275 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
277 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
278 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
279 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
282 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
283 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
285 /* restore float argument registers */
287 for (i = 0; i < FLT_ARG_CNT; i++)
288 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
290 M_LDA(REG_SP, REG_SP, slots * 8);
295 /* take arguments out of register or stack frame */
299 for (p = 0, l = 0; p < md->paramcount; p++) {
300 t = md->paramtypes[p].type;
302 varindex = jd->local_map[l * 5 + t];
305 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
308 if (varindex == UNUSED)
312 s1 = md->params[p].regoff;
314 if (IS_INT_LNG_TYPE(t)) { /* integer args */
318 if (!md->params[p].inmemory) { /* register arguments */
319 s1 = REG_WINDOW_TRANSPOSE(s1);
321 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
323 /* the register allocator does not know about the window. */
324 /* avoid copying the locals from save to save regs by */
325 /* swapping variables. */
328 int old_dest = var->vv.regoff;
329 int new_dest = p + 24;
331 /* run through all variables */
333 for (i = 0; i < jd->varcount; i++) {
334 varinfo* uvar = VAR(i);
336 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
339 s2 = uvar->vv.regoff;
341 /* free the in reg by moving all other references */
343 if (s2 == new_dest) {
344 uvar->vv.regoff = old_dest;
345 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
348 /* move all variables to the in reg */
350 if (s2 == old_dest) {
351 uvar->vv.regoff = new_dest;
352 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
360 else { /* reg arg -> spilled */
361 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
364 } else { /* stack arguments */
365 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
366 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
368 } else { /* stack arg -> spilled */
369 /* add the callers window save registers */
370 var->vv.regoff = cd->stackframesize * 8 + s1;
374 } else { /* floating args */
375 if (!md->params[p].inmemory) { /* register arguments */
376 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
377 M_FLTMOVE(s1, var->vv.regoff);
379 } else { /* reg arg -> spilled */
380 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
383 } else { /* stack arguments */
384 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
385 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
387 } else { /* stack-arg -> spilled */
388 var->vv.regoff = cd->stackframesize * 8 + s1;
397 /* end of header generation */
399 /* create replacement points */
401 REPLACEMENT_POINTS_INIT(cd, jd);
403 /* walk through all basic blocks */
405 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
407 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
409 if (bptr->flags >= BBREACHED) {
411 /* branch resolving */
413 codegen_resolve_branchrefs(cd, bptr);
415 /* handle replacement points */
418 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
419 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
425 /* copy interface registers to their destination */
430 #if defined(ENABLE_LSRA)
431 #error XXX LSRA not tested yet
435 src = bptr->invars[len];
436 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
437 /* d = reg_of_var(m, src, REG_ITMP1); */
438 if (!(src->flags & INMEMORY))
442 M_INTMOVE(REG_ITMP1, d);
443 emit_store(jd, NULL, src, d);
450 var = VAR(bptr->invars[len]);
451 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
452 d = codegen_reg_of_var(0, var, REG_ITMP1);
453 M_INTMOVE(REG_ITMP2_XPTR, d);
454 emit_store(jd, NULL, var, d);
457 assert((var->flags & INOUT));
460 #if defined(ENABLE_LSRA)
463 /* walk through all instructions */
467 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
468 if (iptr->line != currentline) {
469 dseg_addlinenumber(cd, iptr->line);
470 currentline = iptr->line;
473 MCODECHECK(64); /* an instruction usually needs < 64 words */
477 case ICMD_INLINE_START:
478 case ICMD_INLINE_END:
481 case ICMD_NOP: /* ... ==> ... */
484 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
487 emit_nullpointer_check(cd, iptr, s1);
490 /* constant operations ************************************************/
492 case ICMD_ICONST: /* ... ==> ..., constant */
494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
495 ICONST(d, iptr->sx.val.i);
496 emit_store_dst(jd, iptr, d);
499 case ICMD_LCONST: /* ... ==> ..., constant */
501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
502 LCONST(d, iptr->sx.val.l);
503 emit_store_dst(jd, iptr, d);
506 case ICMD_FCONST: /* ... ==> ..., constant */
508 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
509 disp = dseg_add_float(cd, iptr->sx.val.f);
510 M_FLD(d, REG_PV, disp);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_DCONST: /* ... ==> ..., constant */
516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
517 disp = dseg_add_double(cd, iptr->sx.val.d);
518 M_DLD(d, REG_PV, disp);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_ACONST: /* ... ==> ..., constant */
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
526 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
527 cr = iptr->sx.val.c.ref;
528 disp = dseg_add_unique_address(cd, cr);
530 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
532 M_ALD(d, REG_PV, disp);
536 if (iptr->sx.val.anyptr == NULL) {
537 M_INTMOVE(REG_ZERO, d);
540 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
541 M_ALD(d, REG_PV, disp);
544 emit_store_dst(jd, iptr, d);
548 /* load/store/copy/move operations ************************************/
550 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
555 case ICMD_ISTORE: /* ..., value ==> ... */
566 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
571 /* pop/dup/swap operations ********************************************/
573 /* attention: double and longs are only one entry in CACAO ICMDs */
575 case ICMD_POP: /* ..., value ==> ... */
576 case ICMD_POP2: /* ..., value, value ==> ... */
580 /* integer operations *************************************************/
582 case ICMD_INEG: /* ..., value ==> ..., - value */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 M_SUB(REG_ZERO, s1, d);
588 emit_store_dst(jd, iptr, d);
591 case ICMD_I2L: /* ..., value ==> ..., value */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596 emit_store_dst(jd, iptr, d);
599 case ICMD_L2I: /* ..., value ==> ..., value */
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
604 emit_store_dst(jd, iptr, d);
607 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 M_SLLX_IMM(s1, 56, d);
612 M_SRAX_IMM( d, 56, d);
613 emit_store_dst(jd, iptr, d);
616 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 M_SLLX_IMM(s1, 48, d);
621 M_SRLX_IMM( d, 48, d);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
629 M_SLLX_IMM(s1, 48, d);
630 M_SRAX_IMM( d, 48, d);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 emit_store_dst(jd, iptr, d);
645 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
646 /* sx.val.i = constant */
648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
651 M_ADD_IMM(s1, iptr->sx.val.i, d);
653 ICONST(REG_ITMP2, iptr->sx.val.i);
654 M_ADD(s1, REG_ITMP2, d);
656 emit_store_dst(jd, iptr, d);
659 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
660 /* sx.val.l = 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.l >= -4096) && (iptr->sx.val.l <= 4095)) {
665 M_ADD_IMM(s1, iptr->sx.val.l, d);
667 LCONST(REG_ITMP2, iptr->sx.val.l);
668 M_ADD(s1, REG_ITMP2, d);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
684 /* sx.val.i = constant */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
689 M_SUB_IMM(s1, iptr->sx.val.i, d);
691 ICONST(REG_ITMP2, iptr->sx.val.i);
692 M_SUB(s1, REG_ITMP2, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
698 /* sx.val.l = 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.l >= -4096) && (iptr->sx.val.l <= 4095)) {
703 M_SUB_IMM(s1, iptr->sx.val.l, d);
705 LCONST(REG_ITMP2, iptr->sx.val.l);
706 M_SUB(s1, REG_ITMP2, d);
708 emit_store_dst(jd, iptr, d);
711 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
715 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
716 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 emit_store_dst(jd, iptr, d);
721 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
722 /* sx.val.i = constant */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
726 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
727 M_MULX_IMM(s1, iptr->sx.val.i, d);
729 ICONST(REG_ITMP2, iptr->sx.val.i);
730 M_MULX(s1, REG_ITMP2, d);
732 emit_store_dst(jd, iptr, d);
735 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
736 /* sx.val.l = constant */
738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
739 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
740 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
741 M_MULX_IMM(s1, iptr->sx.val.l, d);
743 LCONST(REG_ITMP2, iptr->sx.val.l);
744 M_MULX(s1, REG_ITMP2, d);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
750 /* XXX could also clear Y and use 32bit div */
751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 emit_arithmetic_check(cd, iptr, s2);
756 /* XXX trim s2 like s1 ? */
758 emit_store_dst(jd, iptr, d);
761 case ICMD_LDIV: /* ..., 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_ITMP2);
766 emit_arithmetic_check(cd, iptr, s2);
768 emit_store_dst(jd, iptr, d);
771 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
776 emit_arithmetic_check(cd, iptr, s2);
778 /* XXX trim s2 like s1 ? */
779 M_DIVX(s1, s2, REG_ITMP3);
780 M_MULX(s2, REG_ITMP3, REG_ITMP3);
781 M_SUB(s1, REG_ITMP3, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_LREM: /* ..., 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_ITMP3);
790 emit_arithmetic_check(cd, iptr, s2);
791 M_DIVX(s1, s2, REG_ITMP3);
792 M_MULX(s2, REG_ITMP3, REG_ITMP3);
793 M_SUB(s1, REG_ITMP3, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
798 case ICMD_LDIVPOW2: /* val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_SRAX_IMM(s1, 63, REG_ITMP2);
803 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
804 M_ADD(s1, REG_ITMP2, REG_ITMP2);
805 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
828 /* val.i = constant */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
832 M_SLL_IMM(s1, iptr->sx.val.i, d);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
837 /* val.i = constant */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841 M_SLLX_IMM(s1, iptr->sx.val.i, d);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 M_SRA_IMM(s1, iptr->sx.val.i, d);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 emit_store_dst(jd, iptr, d);
872 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
873 /* sx.val.i = constant */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
877 M_SRL_IMM(s1, iptr->sx.val.i, d);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
891 /* sx.val.i = constant */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895 M_SRAX_IMM(s1, iptr->sx.val.i, d);
896 emit_store_dst(jd, iptr, d);
899 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
902 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
903 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
909 /* sx.val.i = constant */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913 M_SRLX_IMM(s1, iptr->sx.val.i, d);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
928 /* sx.val.i = constant */
930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
933 M_AND_IMM(s1, iptr->sx.val.i, d);
935 ICONST(REG_ITMP2, iptr->sx.val.i);
936 M_AND(s1, REG_ITMP2, d);
938 emit_store_dst(jd, iptr, d);
941 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
942 /* sx.val.i = constant */
943 /* constant is actually constant - 1 */
945 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
948 M_MOV(s1, REG_ITMP1);
951 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
952 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
953 M_AND_IMM(s1, iptr->sx.val.i, d);
956 M_SUB(REG_ZERO, s1, d);
957 M_AND_IMM(d, iptr->sx.val.i, d);
959 ICONST(REG_ITMP2, iptr->sx.val.i);
960 M_AND(s1, REG_ITMP2, d);
963 M_SUB(REG_ZERO, s1, d);
964 M_AND(d, REG_ITMP2, d);
966 M_SUB(REG_ZERO, d, d);
967 emit_store_dst(jd, iptr, d);
970 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
971 /* sx.val.l = constant */
973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
976 M_AND_IMM(s1, iptr->sx.val.l, d);
978 LCONST(REG_ITMP2, iptr->sx.val.l);
979 M_AND(s1, REG_ITMP2, d);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
985 /* sx.val.l = constant */
987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990 M_MOV(s1, REG_ITMP1);
993 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
994 M_AND_IMM(s1, iptr->sx.val.l, d);
997 M_SUB(REG_ZERO, s1, d);
998 M_AND_IMM(d, iptr->sx.val.l, d);
1000 LCONST(REG_ITMP2, iptr->sx.val.l);
1001 M_AND(s1, REG_ITMP2, d);
1004 M_SUB(REG_ZERO, s1, d);
1005 M_AND(d, REG_ITMP2, d);
1007 M_SUB(REG_ZERO, d, d);
1008 emit_store_dst(jd, iptr, d);
1011 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1022 /* sx.val.i = constant */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1027 M_OR_IMM(s1, iptr->sx.val.i, d);
1029 ICONST(REG_ITMP2, iptr->sx.val.i);
1030 M_OR(s1, REG_ITMP2, d);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1036 /* sx.val.l = 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.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1041 M_OR_IMM(s1, iptr->sx.val.l, d);
1043 LCONST(REG_ITMP2, iptr->sx.val.l);
1044 M_OR(s1, REG_ITMP2, d);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1060 /* sx.val.i = constant */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1064 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1065 M_XOR_IMM(s1, iptr->sx.val.i, d);
1067 ICONST(REG_ITMP2, iptr->sx.val.i);
1068 M_XOR(s1, REG_ITMP2, d);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1074 /* sx.val.l = constant */
1076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1078 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1079 M_XOR_IMM(s1, iptr->sx.val.l, d);
1081 LCONST(REG_ITMP2, iptr->sx.val.l);
1082 M_XOR(s1, REG_ITMP2, d);
1084 emit_store_dst(jd, iptr, d);
1088 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 M_XCMOVLT_IMM(-1, d);
1096 M_XCMOVGT_IMM(1, d);
1097 emit_store_dst(jd, iptr, d);
1101 /* floating operations ************************************************/
1103 case ICMD_FNEG: /* ..., value ==> ..., - value */
1105 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1106 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_DNEG: /* ..., value ==> ..., - value */
1113 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1114 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1116 emit_store_dst(jd, iptr, d);
1119 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1121 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1122 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1123 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1130 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1131 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1132 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1139 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1140 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1143 emit_store_dst(jd, iptr, d);
1146 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1148 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1149 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1150 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1159 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1168 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1179 emit_store_dst(jd, iptr, d);
1182 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1184 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1185 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1186 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1188 emit_store_dst(jd, iptr, d);
1192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1193 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1194 disp = dseg_add_unique_float(cd, 0.0);
1195 M_IST (s1, REG_PV_CALLEE, disp);
1196 M_FLD (d, REG_PV_CALLEE, disp);
1197 M_CVTIF (d, d); /* rd gets translated to double target register */
1198 emit_store_dst(jd, iptr, d);
1202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1203 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 disp = dseg_add_unique_float(cd, 0.0);
1205 M_IST(s1, REG_PV_CALLEE, disp);
1206 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1207 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1208 emit_store_dst(jd, iptr, d);
1212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1213 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1214 disp = dseg_add_unique_double(cd, 0.0);
1215 M_STX(s1, REG_PV_CALLEE, disp);
1216 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1217 M_CVTLF(REG_FTMP3, d);
1218 emit_store_dst(jd, iptr, d);
1222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1223 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1224 disp = dseg_add_unique_double(cd, 0.0);
1225 M_STX(s1, REG_PV_CALLEE, disp);
1226 M_DLD(d, REG_PV_CALLEE, disp);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1232 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1233 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1234 disp = dseg_add_unique_float(cd, 0.0);
1236 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1239 M_MOV(REG_ZERO, d); /* delay slot */
1241 M_CVTFI(s1, REG_FTMP2);
1242 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1243 M_ILD(d, REG_PV, disp);
1244 emit_store_dst(jd, iptr, d);
1248 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1251 disp = dseg_add_unique_float(cd, 0.0);
1253 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1256 M_MOV(REG_ZERO, d); /* delay slot */
1258 M_CVTDI(s1, REG_FTMP2);
1259 M_FST(REG_FTMP2, REG_PV, disp);
1260 M_ILD(d, REG_PV, disp);
1261 emit_store_dst(jd, iptr, d);
1264 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1267 disp = dseg_add_unique_double(cd, 0.0);
1269 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1272 M_MOV(REG_ZERO, d); /* delay slot */
1274 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1275 M_DST(REG_FTMP2, REG_PV, disp);
1276 M_LDX(d, REG_PV, disp);
1277 emit_store_dst(jd, iptr, d);
1280 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1281 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1282 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1283 disp = dseg_add_unique_double(cd, 0.0);
1285 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1288 M_MOV(REG_ZERO, d); /* delay slot */
1290 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1291 M_DST(REG_FTMP2, REG_PV, disp);
1292 M_LDX(d, REG_PV, disp);
1293 emit_store_dst(jd, iptr, d);
1296 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1298 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1299 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1306 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1307 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1309 emit_store_dst(jd, iptr, d);
1312 /* XXX merge F/D versions? only compare instr. is different */
1313 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl 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); /* less by default (less or unordered) */
1320 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1321 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl 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); /* less by default (less or unordered) */
1332 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1333 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1339 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1341 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1343 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1344 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1345 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1351 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1355 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1356 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1357 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1358 emit_store_dst(jd, iptr, d);
1362 /* memory operations **************************************************/
1364 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368 emit_nullpointer_check(cd, iptr, s1);
1369 M_ILD(d, s1, OFFSET(java_array_t, size));
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1375 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1376 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1378 /* implicit null-pointer check */
1379 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1380 M_AADD(s2, s1, REG_ITMP3);
1381 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1382 emit_store_dst(jd, iptr, d);
1385 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1390 /* implicit null-pointer check */
1391 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1392 M_AADD(s2, s1, REG_ITMP3);
1393 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1394 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1395 emit_store_dst(jd, iptr, d);
1398 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1400 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1401 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1403 /* implicit null-pointer check */
1404 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1405 M_AADD(s2, s1, REG_ITMP3);
1406 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1407 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1408 emit_store_dst(jd, iptr, d);
1411 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1416 /* implicit null-pointer check */
1417 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1418 M_ASLL_IMM(s2, 2, REG_ITMP3);
1419 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1420 M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1421 emit_store_dst(jd, iptr, d);
1424 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1427 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1429 /* implicit null-pointer check */
1430 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1431 M_ASLL_IMM(s2, 3, REG_ITMP3);
1432 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1433 M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1442 /* implicit null-pointer check */
1443 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1444 M_ASLL_IMM(s2, 2, REG_ITMP3);
1445 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1446 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1447 emit_store_dst(jd, iptr, d);
1450 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1452 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1454 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1455 /* implicit null-pointer check */
1456 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1457 M_ASLL_IMM(s2, 3, REG_ITMP3);
1458 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1459 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1460 emit_store_dst(jd, iptr, d);
1463 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1468 /* implicit null-pointer check */
1469 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1470 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1471 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1472 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1473 emit_store_dst(jd, iptr, d);
1477 case ICMD_BASTORE: /* ..., 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_AADD(s2, s1, REG_ITMP1);
1484 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1485 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1488 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1489 case ICMD_SASTORE: /* ..., 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_AADD(s2, s1, REG_ITMP1);
1496 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1497 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1498 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1501 case ICMD_IASTORE: /* ..., 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_ITMP3);
1510 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1513 case ICMD_LASTORE: /* ..., 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_ITMP3);
1522 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1525 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1529 /* implicit null-pointer check */
1530 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1531 M_ASLL_IMM(s2, 2, REG_ITMP2);
1532 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1533 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1534 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1537 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 /* implicit null-pointer check */
1542 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1543 M_ASLL_IMM(s2, 3, REG_ITMP2);
1544 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1545 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1546 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1550 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1554 /* implicit null-pointer check */
1555 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1556 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1558 M_MOV(s1, REG_OUT0);
1559 M_MOV(s3, REG_OUT1);
1560 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1561 M_ALD(REG_ITMP3, REG_PV, disp);
1562 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1564 emit_exception_check(cd, iptr);
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1568 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1569 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1570 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1571 /* implicit null-pointer check */
1572 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1576 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1580 /* implicit null-pointer check */
1581 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1582 M_AADD(s2, s1, REG_ITMP1);
1583 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1586 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1587 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591 /* implicit null-pointer check */
1592 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1593 M_AADD(s2, s1, REG_ITMP1);
1594 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1595 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1598 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1602 /* implicit null-pointer check */
1603 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1604 M_ASLL_IMM(s2, 2, REG_ITMP2);
1605 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1606 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1609 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1612 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1613 /* implicit null-pointer check */
1614 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1615 M_ASLL_IMM(s2, 3, REG_ITMP2);
1616 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1617 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1620 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1624 /* implicit null-pointer check */
1625 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1626 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1627 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1628 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1632 case ICMD_GETSTATIC: /* ... ==> ..., value */
1634 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1635 uf = iptr->sx.s23.s3.uf;
1636 fieldtype = uf->fieldref->parseddesc.fd->type;
1637 disp = dseg_add_unique_address(cd, uf);
1639 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1642 fi = iptr->sx.s23.s3.fmiref->p.field;
1643 fieldtype = fi->type;
1644 disp = dseg_add_address(cd, fi->value);
1646 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1647 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1650 M_ALD(REG_ITMP1, REG_PV, disp);
1652 switch (fieldtype) {
1654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1655 M_ILD_INTERN(d, REG_ITMP1, 0);
1658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1659 M_LDX_INTERN(d, REG_ITMP1, 0);
1662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1663 M_ALD_INTERN(d, REG_ITMP1, 0);
1666 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1667 M_FLD_INTERN(d, REG_ITMP1, 0);
1670 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1671 M_DLD_INTERN(d, REG_ITMP1, 0);
1674 emit_store_dst(jd, iptr, d);
1677 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1679 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1680 uf = iptr->sx.s23.s3.uf;
1681 fieldtype = uf->fieldref->parseddesc.fd->type;
1682 disp = dseg_add_unique_address(cd, uf);
1684 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1687 fi = iptr->sx.s23.s3.fmiref->p.field;
1688 fieldtype = fi->type;
1689 disp = dseg_add_address(cd, fi->value);
1691 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1692 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1695 M_ALD(REG_ITMP1, REG_PV, disp);
1697 switch (fieldtype) {
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1700 M_IST_INTERN(s1, REG_ITMP1, 0);
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1704 M_STX_INTERN(s1, REG_ITMP1, 0);
1707 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1708 M_AST_INTERN(s1, REG_ITMP1, 0);
1711 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1712 M_FST_INTERN(s1, REG_ITMP1, 0);
1715 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1716 M_DST_INTERN(s1, REG_ITMP1, 0);
1721 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1722 /* val = value (in current instruction) */
1723 /* following NOP) */
1725 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1726 uf = iptr->sx.s23.s3.uf;
1727 fieldtype = uf->fieldref->parseddesc.fd->type;
1728 disp = dseg_add_unique_address(cd, uf);
1730 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1733 fi = iptr->sx.s23.s3.fmiref->p.field;
1734 fieldtype = fi->type;
1735 disp = dseg_add_address(cd, fi->value);
1737 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1738 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1741 M_ALD(REG_ITMP1, REG_PV, disp);
1743 switch (fieldtype) {
1745 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1748 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1751 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1754 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1757 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1763 case ICMD_GETFIELD: /* ... ==> ..., value */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 emit_nullpointer_check(cd, iptr, s1);
1768 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1769 uf = iptr->sx.s23.s3.uf;
1771 fieldtype = uf->fieldref->parseddesc.fd->type;
1774 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1777 fi = iptr->sx.s23.s3.fmiref->p.field;
1778 fieldtype = fi->type;
1782 switch (fieldtype) {
1784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1796 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1800 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1807 emit_store_dst(jd, iptr, d);
1810 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1813 emit_nullpointer_check(cd, iptr, s1);
1815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816 uf = iptr->sx.s23.s3.uf;
1817 fieldtype = uf->fieldref->parseddesc.fd->type;
1822 fi = iptr->sx.s23.s3.fmiref->p.field;
1823 fieldtype = fi->type;
1827 if (IS_INT_LNG_TYPE(fieldtype))
1828 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1830 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1832 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1833 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1835 switch (fieldtype) {
1837 M_IST(s2, s1, disp);
1840 M_STX(s2, s1, disp);
1843 M_AST(s2, s1, disp);
1846 M_FST(s2, s1, disp);
1849 M_DST(s2, s1, disp);
1857 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1858 /* val = value (in current instruction) */
1859 /* following NOP) */
1861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1862 emit_nullpointer_check(cd, iptr, s1);
1864 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1865 unresolved_field *uf = iptr->sx.s23.s3.uf;
1867 fieldtype = uf->fieldref->parseddesc.fd->type;
1869 codegen_addpatchref(cd, PATCHER_get_putfield,
1872 if (opt_showdisassemble) {
1880 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1882 fieldtype = fi->type;
1888 switch (fieldtype) {
1890 M_IST(REG_ZERO, s1, disp);
1893 M_STX(REG_ZERO, s1, disp);
1896 M_AST(REG_ZERO, s1, disp);
1899 M_FST(REG_ZERO, s1, disp);
1902 M_DST(REG_ZERO, s1, disp);
1908 /* branch operations **************************************************/
1910 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913 M_INTMOVE(s1, REG_ITMP2_XPTR);
1915 #ifdef ENABLE_VERIFIER
1916 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1917 unresolved_class *uc = iptr->sx.s23.s2.uc;
1919 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1921 #endif /* ENABLE_VERIFIER */
1923 disp = dseg_add_functionptr(cd, asm_handle_exception);
1924 M_ALD(REG_ITMP1, REG_PV, disp);
1925 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1927 M_NOP; /* nop ensures that XPC is less than the end */
1928 /* of basic block */
1932 case ICMD_GOTO: /* ... ==> ... */
1933 case ICMD_RET: /* ... ==> ... */
1935 emit_br(cd, iptr->dst.block);
1939 case ICMD_JSR: /* ... ==> ... */
1941 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1945 case ICMD_IFNULL: /* ..., value ==> ... */
1946 case ICMD_IFNONNULL:
1948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1949 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1952 /* Note: int compares must not branch on the register directly. */
1953 /* Reason is, that register content is not 32-bit clean. */
1955 case ICMD_IFEQ: /* ..., value ==> ... */
1957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1960 M_CMP_IMM(s1, iptr->sx.val.i);
1963 ICONST(REG_ITMP2, iptr->sx.val.i);
1964 M_CMP(s1, REG_ITMP2);
1966 emit_beq(cd, iptr->dst.block);
1969 case ICMD_IFLT: /* ..., value ==> ... */
1971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1973 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1974 M_CMP_IMM(s1, iptr->sx.val.i);
1977 ICONST(REG_ITMP2, iptr->sx.val.i);
1978 M_CMP(s1, REG_ITMP2);
1980 emit_blt(cd, iptr->dst.block);
1983 case ICMD_IFLE: /* ..., value ==> ... */
1985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1988 M_CMP_IMM(s1, iptr->sx.val.i);
1991 ICONST(REG_ITMP2, iptr->sx.val.i);
1992 M_CMP(s1, REG_ITMP2);
1994 emit_ble(cd, iptr->dst.block);
1997 case ICMD_IFNE: /* ..., value ==> ... */
1999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2001 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2002 M_CMP_IMM(s1, iptr->sx.val.i);
2005 ICONST(REG_ITMP2, iptr->sx.val.i);
2006 M_CMP(s1, REG_ITMP2);
2008 emit_bne(cd, iptr->dst.block);
2011 case ICMD_IFGT: /* ..., value ==> ... */
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2015 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2016 M_CMP_IMM(s1, iptr->sx.val.i);
2019 ICONST(REG_ITMP2, iptr->sx.val.i);
2020 M_CMP(s1, REG_ITMP2);
2022 emit_bgt(cd, iptr->dst.block);
2025 case ICMD_IFGE: /* ..., value ==> ... */
2027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2029 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2030 M_CMP_IMM(s1, iptr->sx.val.i);
2033 ICONST(REG_ITMP2, iptr->sx.val.i);
2034 M_CMP(s1, REG_ITMP2);
2036 emit_bge(cd, iptr->dst.block);
2039 case ICMD_IF_LEQ: /* ..., value ==> ... */
2041 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2042 if (iptr->sx.val.l == 0)
2043 emit_beqz(cd, iptr->dst.block, s1);
2045 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2046 M_CMP_IMM(s1, iptr->sx.val.l);
2049 LCONST(REG_ITMP2, iptr->sx.val.l);
2050 M_CMP(s1, REG_ITMP2);
2052 emit_beq_xcc(cd, iptr->dst.block);
2056 case ICMD_IF_LLT: /* ..., value ==> ... */
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2059 if (iptr->sx.val.l == 0)
2060 emit_bltz(cd, iptr->dst.block, s1);
2062 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2063 M_CMP_IMM(s1, iptr->sx.val.l);
2066 LCONST(REG_ITMP2, iptr->sx.val.l);
2067 M_CMP(s1, REG_ITMP2);
2069 emit_blt_xcc(cd, iptr->dst.block);
2073 case ICMD_IF_LLE: /* ..., value ==> ... */
2075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2076 if (iptr->sx.val.l == 0)
2077 emit_blez(cd, iptr->dst.block, s1);
2079 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2080 M_CMP_IMM(s1, iptr->sx.val.l);
2083 LCONST(REG_ITMP2, iptr->sx.val.l);
2084 M_CMP(s1, REG_ITMP2);
2086 emit_ble_xcc(cd, iptr->dst.block);
2090 case ICMD_IF_LNE: /* ..., value ==> ... */
2092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2093 if (iptr->sx.val.l == 0)
2094 emit_bnez(cd, iptr->dst.block, s1);
2096 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2097 M_CMP_IMM(s1, iptr->sx.val.l);
2100 LCONST(REG_ITMP2, iptr->sx.val.l);
2101 M_CMP(s1, REG_ITMP2);
2103 emit_bne_xcc(cd, iptr->dst.block);
2107 case ICMD_IF_LGT: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 if (iptr->sx.val.l == 0)
2111 emit_bgtz(cd, iptr->dst.block, s1);
2113 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2114 M_CMP_IMM(s1, iptr->sx.val.l);
2117 LCONST(REG_ITMP2, iptr->sx.val.l);
2118 M_CMP(s1, REG_ITMP2);
2120 emit_bgt_xcc(cd, iptr->dst.block);
2124 case ICMD_IF_LGE: /* ..., value ==> ... */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 if (iptr->sx.val.l == 0)
2128 emit_bgez(cd, iptr->dst.block, s1);
2130 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2131 M_CMP_IMM(s1, iptr->sx.val.l);
2134 LCONST(REG_ITMP2, iptr->sx.val.l);
2135 M_CMP(s1, REG_ITMP2);
2137 emit_bge_xcc(cd, iptr->dst.block);
2142 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2143 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2146 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2148 emit_beq_xcc(cd, iptr->dst.block);
2151 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2156 emit_beq(cd, iptr->dst.block);
2159 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2160 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2165 emit_bne_xcc(cd, iptr->dst.block);
2168 case ICMD_IF_ICMPNE: /* 32-bit compare */
2170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2173 emit_bne(cd, iptr->dst.block);
2176 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2181 emit_blt_xcc(cd, iptr->dst.block);
2184 case ICMD_IF_ICMPLT: /* 32-bit compare */
2186 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2187 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2189 emit_blt(cd, iptr->dst.block);
2192 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2197 emit_bgt_xcc(cd, iptr->dst.block);
2200 case ICMD_IF_ICMPGT: /* 32-bit compare */
2202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2203 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2205 emit_bgt(cd, iptr->dst.block);
2208 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2211 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2213 emit_ble_xcc(cd, iptr->dst.block);
2216 case ICMD_IF_ICMPLE: /* 32-bit compare */
2218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2219 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2221 emit_ble(cd, iptr->dst.block);
2225 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2227 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2228 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2230 emit_bge_xcc(cd, iptr->dst.block);
2233 case ICMD_IF_ICMPGE: /* 32-bit compare */
2235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2238 emit_bge(cd, iptr->dst.block);
2242 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2245 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2246 M_INTMOVE(s1, REG_RESULT_CALLEE);
2247 goto nowperformreturn;
2249 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2251 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2252 M_INTMOVE(s1, REG_RESULT_CALLEE);
2254 #ifdef ENABLE_VERIFIER
2255 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2256 unresolved_class *uc = iptr->sx.s23.s2.uc;
2258 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2260 #endif /* ENABLE_VERIFIER */
2261 goto nowperformreturn;
2263 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2266 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2267 M_DBLMOVE(s1, REG_FRESULT);
2268 goto nowperformreturn;
2270 case ICMD_RETURN: /* ... ==> ... */
2276 p = cd->stackframesize;
2278 #if !defined(NDEBUG)
2279 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2280 emit_verbosecall_exit(jd);
2283 #if defined(ENABLE_THREADS)
2284 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2285 /* XXX jit-c-call */
2286 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2287 M_ALD(REG_ITMP3, REG_PV, disp);
2289 /* we need to save fp return value (int saved by window) */
2291 switch (iptr->opc) {
2294 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2295 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2296 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2298 /* restore the fp return value */
2300 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2306 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2307 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2318 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2324 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2327 branch_target_t *table;
2329 table = iptr->dst.table;
2331 l = iptr->sx.s23.s2.tablelow;
2332 i = iptr->sx.s23.s3.tablehigh;
2334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2336 M_INTMOVE(s1, REG_ITMP1);
2338 else if (-l >= 4096 && -l <= 4095) {
2339 M_ADD_IMM(s1, -l, REG_ITMP1);
2342 ICONST(REG_ITMP2, l);
2343 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2346 i = i - l + 1; /* number of targets (>0) */
2352 M_CMP_IMM(REG_ITMP1, i - 1);
2355 ICONST(REG_ITMP2, i - 1);
2356 M_CMP(REG_ITMP1, REG_ITMP2);
2358 emit_bugt(cd, table[0].block); /* default target */
2360 /* build jump table top down and use address of lowest entry */
2365 dseg_add_target(cd, table->block);
2370 /* length of dataseg after last dseg_addtarget is used by load */
2372 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2373 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2374 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2375 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2380 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2383 lookup_target_t *lookup;
2385 lookup = iptr->dst.lookup;
2387 i = iptr->sx.s23.s2.lookupcount;
2389 MCODECHECK((i<<2)+8);
2390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2393 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2394 M_CMP_IMM(s1, lookup->value);
2396 ICONST(REG_ITMP2, lookup->value);
2397 M_CMP(s1, REG_ITMP2);
2399 emit_beq(cd, lookup->target.block);
2403 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2409 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2411 bte = iptr->sx.s23.s3.bte;
2414 /* XXX: builtin calling with stack arguments not implemented */
2415 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2417 s3 = md->paramcount;
2419 MCODECHECK((s3 << 1) + 64);
2421 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2423 /* copy float arguments according to ABI convention */
2425 int num_fltregargs = 0;
2426 int fltregarg_inswap[16];
2428 for (s3 = s3 - 1; s3 >= 0; s3--) {
2429 var = VAR(iptr->sx.s23.s2.args[s3]);
2431 if (IS_FLT_DBL_TYPE(var->type)) {
2432 if (!md->params[s3].inmemory) {
2433 s1 = s3; /*native flt args use argument index directly*/
2434 d = emit_load(jd, iptr, var, REG_FTMP1);
2437 fltregarg_inswap[num_fltregargs] = s1;
2439 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2448 /* move swapped float args to target regs */
2449 for (i = 0; i < num_fltregargs; i++) {
2450 s1 = fltregarg_inswap[i];
2451 M_DMOV(s1 + 16, s1);
2452 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2456 assert(md->argfltreguse == 0);
2461 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2463 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2464 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2465 case ICMD_INVOKEINTERFACE:
2467 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2469 um = iptr->sx.s23.s3.um;
2470 md = um->methodref->parseddesc.md;
2473 lm = iptr->sx.s23.s3.fmiref->p.method;
2475 md = lm->parseddesc;
2479 s3 = md->paramcount;
2481 MCODECHECK((s3 << 1) + 64);
2483 /* copy arguments to registers or stack location */
2485 for (s3 = s3 - 1; s3 >= 0; s3--) {
2486 var = VAR(iptr->sx.s23.s2.args[s3]);
2487 d = md->params[s3].regoff;
2489 if (var->flags & PREALLOC)
2492 if (IS_INT_LNG_TYPE(var->type)) {
2493 if (!md->params[s3].inmemory) {
2494 s1 = emit_load(jd, iptr, var, d);
2498 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2499 M_STX(s1, REG_SP, JITSTACK + d);
2503 #ifdef BUILTIN_FLOAT_ARGS
2504 if (iptr->opc == ICMD_BUILTIN)
2508 if (!md->params[s3].inmemory) {
2509 s1 = emit_load(jd, iptr, var, d);
2510 if (IS_2_WORD_TYPE(var->type))
2516 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2517 M_DST(s1, REG_SP, JITSTACK + d);
2522 switch (iptr->opc) {
2524 disp = dseg_add_functionptr(cd, bte->fp);
2526 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2528 /* XXX jit-c-call */
2529 /* generate the actual call */
2531 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2533 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2534 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2535 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2537 emit_exception_check(cd, iptr);
2538 if (md->returntype.type == TYPE_FLT) {
2539 /* special handling for float return value in %f0 */
2544 case ICMD_INVOKESPECIAL:
2545 emit_nullpointer_check(cd, iptr, REG_OUT0);
2548 case ICMD_INVOKESTATIC:
2550 disp = dseg_add_unique_address(cd, NULL);
2552 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2556 disp = dseg_add_address(cd, lm->stubroutine);
2558 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2560 /* generate the actual call */
2562 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2564 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2565 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2566 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2569 case ICMD_INVOKEVIRTUAL:
2570 emit_nullpointer_check(cd, iptr, REG_OUT0);
2573 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2578 s1 = OFFSET(vftbl_t, table[0]) +
2579 sizeof(methodptr) * lm->vftblindex;
2581 /* implicit null-pointer check */
2582 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2583 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2585 /* generate the actual call */
2587 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2589 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2590 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2591 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2594 case ICMD_INVOKEINTERFACE:
2595 emit_nullpointer_check(cd, iptr, REG_OUT0);
2598 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2604 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2605 sizeof(methodptr*) * lm->class->index;
2607 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2610 /* implicit null-pointer check */
2611 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2612 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2613 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2615 /* generate the actual call */
2617 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2619 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2620 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2621 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2625 /* store return value */
2627 d = md->returntype.type;
2629 if (d != TYPE_VOID) {
2630 if (IS_INT_LNG_TYPE(d)) {
2631 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2632 M_INTMOVE(REG_RESULT_CALLER, s1);
2635 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2636 if (IS_2_WORD_TYPE(d)) {
2637 M_DBLMOVE(REG_FRESULT, s1);
2639 M_FLTMOVE(REG_FRESULT, s1);
2642 emit_store_dst(jd, iptr, s1);
2647 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2648 /* val.a: (classinfo*) superclass */
2650 /* superclass is an interface:
2652 * OK if ((sub == NULL) ||
2653 * (sub->vftbl->interfacetablelength > super->index) &&
2654 * (sub->vftbl->interfacetable[-super->index] != NULL));
2656 * superclass is a class:
2658 * OK if ((sub == NULL) || (0
2659 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2660 * super->vftbl->diffvall));
2663 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2667 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2672 super = iptr->sx.s23.s3.c.cls;
2673 superindex = super->index;
2676 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2677 CODEGEN_CRITICAL_SECTION_NEW;
2679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2681 /* if class is not resolved, check which code to call */
2683 if (super == NULL) {
2684 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2686 cr = iptr->sx.s23.s3.c.ref;
2687 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2689 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2692 M_ILD(REG_ITMP2, REG_PV, disp);
2693 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2694 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2697 /* interface checkcast code */
2699 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2700 if (super == NULL) {
2701 cr = iptr->sx.s23.s3.c.ref;
2703 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2707 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2710 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2711 M_ILD(REG_ITMP3, REG_ITMP2,
2712 OFFSET(vftbl_t, interfacetablelength));
2713 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2714 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2716 M_ALD(REG_ITMP3, REG_ITMP2,
2717 OFFSET(vftbl_t, interfacetable[0]) -
2718 superindex * sizeof(methodptr*));
2719 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2722 emit_label_br(cd, BRANCH_LABEL_4);
2724 emit_label(cd, BRANCH_LABEL_3);
2727 /* class checkcast code */
2729 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2730 if (super == NULL) {
2731 emit_label(cd, BRANCH_LABEL_2);
2733 cr = iptr->sx.s23.s3.c.ref;
2734 disp = dseg_add_unique_address(cd, NULL);
2736 codegen_add_patch_ref(cd,
2737 PATCHER_checkcast_instanceof_class,
2741 disp = dseg_add_address(cd, super->vftbl);
2743 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2746 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2747 M_ALD(REG_ITMP3, REG_PV, disp);
2749 CODEGEN_CRITICAL_SECTION_START;
2751 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2752 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2753 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2754 M_ALD(REG_ITMP3, REG_PV, disp);
2755 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2757 CODEGEN_CRITICAL_SECTION_END;
2760 M_CMP(REG_ITMP3, REG_ITMP2);
2761 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2764 emit_label(cd, BRANCH_LABEL_5);
2767 if (super == NULL) {
2768 emit_label(cd, BRANCH_LABEL_1);
2769 emit_label(cd, BRANCH_LABEL_4);
2772 d = codegen_reg_of_dst(jd, iptr, s1);
2775 /* array type cast-check */
2777 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2778 M_INTMOVE(s1, REG_OUT0);
2780 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2782 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2783 cr = iptr->sx.s23.s3.c.ref;
2784 disp = dseg_add_unique_address(cd, NULL);
2786 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2790 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2792 M_ALD(REG_OUT1, REG_PV, disp);
2793 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2794 M_ALD(REG_ITMP3, REG_PV, disp);
2795 /* XXX jit-c-call */
2796 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2800 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2802 d = codegen_reg_of_dst(jd, iptr, s1);
2806 emit_store_dst(jd, iptr, d);
2809 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2810 /* val.a: (classinfo*) superclass */
2812 /* superclass is an interface:
2814 * return (sub != NULL) &&
2815 * (sub->vftbl->interfacetablelength > super->index) &&
2816 * (sub->vftbl->interfacetable[-super->index] != NULL);
2818 * superclass is a class:
2820 * return ((sub != NULL) && (0
2821 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2822 * super->vftbl->diffvall));
2827 vftbl_t *supervftbl;
2830 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2836 super = iptr->sx.s23.s3.c.cls;
2837 superindex = super->index;
2838 supervftbl = super->vftbl;
2841 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2842 CODEGEN_CRITICAL_SECTION_NEW;
2844 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2845 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2847 M_MOV(s1, REG_ITMP1);
2853 /* if class is not resolved, check which code to call */
2855 if (super == NULL) {
2856 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2858 cr = iptr->sx.s23.s3.c.ref;
2859 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2861 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2864 M_ILD(REG_ITMP3, REG_PV, disp);
2865 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2866 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2869 /* interface instanceof code */
2871 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2872 if (super == NULL) {
2873 cr = iptr->sx.s23.s3.c.ref;
2875 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2879 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2882 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2883 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2884 M_CMP_IMM(REG_ITMP3, superindex);
2887 M_ALD(REG_ITMP1, REG_ITMP1,
2888 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2889 superindex * sizeof(methodptr*)));
2890 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2893 emit_label_br(cd, BRANCH_LABEL_4);
2895 emit_label(cd, BRANCH_LABEL_3);
2898 /* class instanceof code */
2900 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2901 if (super == NULL) {
2902 emit_label(cd, BRANCH_LABEL_2);
2904 cr = iptr->sx.s23.s3.c.ref;
2905 disp = dseg_add_unique_address(cd, NULL);
2907 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2911 disp = dseg_add_address(cd, supervftbl);
2913 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2916 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2917 M_ALD(REG_ITMP2, REG_PV, disp);
2919 CODEGEN_CRITICAL_SECTION_START;
2921 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2922 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2923 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2925 CODEGEN_CRITICAL_SECTION_END;
2927 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2928 M_CMP(REG_ITMP1, REG_ITMP2);
2929 M_XCMOVULE_IMM(1, d);
2932 emit_label(cd, BRANCH_LABEL_5);
2935 if (super == NULL) {
2936 emit_label(cd, BRANCH_LABEL_1);
2937 emit_label(cd, BRANCH_LABEL_4);
2940 emit_store_dst(jd, iptr, d);
2944 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2946 /* check for negative sizes and copy sizes to stack if necessary */
2948 MCODECHECK((iptr->s1.argcount << 1) + 64);
2950 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2952 var = VAR(iptr->sx.s23.s2.args[s1]);
2954 /* copy SAVEDVAR sizes to stack */
2956 /* Already Preallocated? */
2958 if (!(var->flags & PREALLOC)) {
2959 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2960 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2964 /* arg 0 = dimension count */
2966 ICONST(REG_OUT0, iptr->s1.argcount);
2968 /* is patcher function set? */
2970 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2971 disp = dseg_add_unique_address(cd, 0);
2973 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2974 iptr->sx.s23.s3.c.ref,
2978 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2980 /* arg 1 = arraydescriptor */
2982 M_ALD(REG_OUT1, REG_PV, disp);
2984 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2986 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2988 /* XXX c abi call */
2989 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2990 M_ALD(REG_ITMP3, REG_PV, disp);
2991 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2994 /* check for exception before result assignment */
2996 emit_exception_check(cd, iptr);
2998 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2999 M_INTMOVE(REG_RESULT_CALLER, d);
3000 emit_store_dst(jd, iptr, d);
3004 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3010 } /* for instruction */
3014 /* At the end of a basic block we may have to append some nops,
3015 because the patcher stub calling code might be longer than the
3016 actual instruction. So codepatching does not change the
3017 following block unintentionally. */
3019 if (cd->mcodeptr < cd->lastmcodeptr) {
3020 while (cd->mcodeptr < cd->lastmcodeptr) {
3025 } /* if (bptr -> flags >= BBREACHED) */
3026 } /* for basic block */
3028 dseg_createlinenumbertable(cd);
3030 /* generate stubs */
3032 emit_patcher_stubs(jd);
3034 /* everything's ok */
3040 /* codegen_emit_stub_compiler **************************************************
3042 Emits a stub routine which calls the compiler.
3044 *******************************************************************************/
3046 void codegen_emit_stub_compiler(jitdata *jd)
3051 /* get required compiler data */
3056 /* code for the stub */
3058 /* no window save yet, user caller's PV */
3059 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3060 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3061 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3066 /* codegen_emit_stub_native ****************************************************
3068 Emits a stub routine which calls a native method.
3070 *******************************************************************************/
3072 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3079 s4 i, j; /* count variables */
3082 s4 funcdisp; /* displacement of the function */
3083 s4 fltregarg_offset[FLT_ARG_CNT];
3085 /* get required compiler data */
3091 /* initialize variables */
3094 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3096 /* calculate stack frame size */
3098 cd->stackframesize =
3099 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3100 sizeof(localref_table) / SIZEOF_VOID_P +
3101 md->paramcount + /* for saving arguments over calls */
3102 nmd->memuse + /* nmd->memuse includes the (6) abi params */
3106 /* keep stack 16-byte aligned (ABI requirement) */
3108 if (cd->stackframesize & 1)
3109 cd->stackframesize++;
3111 /* create method header */
3113 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3114 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3115 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3116 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3117 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3118 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3119 (void) dseg_addlinenumbertablesize(cd);
3120 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3122 /* generate stub code */
3124 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3126 #if !defined(NDEBUG)
3127 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3128 emit_verbosecall_enter(jd);
3131 /* get function address (this must happen before the stackframeinfo) */
3133 funcdisp = dseg_add_functionptr(cd, f);
3135 #if !defined(WITH_STATIC_CLASSPATH)
3137 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3141 /* save float argument registers */
3143 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3145 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3146 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3147 s1 = WINSAVE_CNT + nmd->memuse + j;
3148 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3149 fltregarg_offset[i] = s1; /* remember stack offset */
3154 /* prepare data structures for native function call */
3156 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3157 M_MOV(REG_PV_CALLEE, REG_OUT1);
3158 M_MOV(REG_FP, REG_OUT2); /* java sp */
3159 M_MOV(REG_RA_CALLEE, REG_OUT3);
3160 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3161 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3162 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3163 M_NOP; /* XXX fill me! */
3165 /* keep float arguments on stack */
3167 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3168 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3169 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3175 /* copy or spill arguments to new locations */
3177 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3178 t = md->paramtypes[i].type;
3180 if (IS_INT_LNG_TYPE(t)) {
3182 /* integral types */
3184 if (!md->params[i].inmemory) {
3185 s1 = md->params[i].regoff;
3186 /* s1 refers to the old window, transpose */
3187 s1 = REG_WINDOW_TRANSPOSE(s1);
3189 if (!nmd->params[j].inmemory) {
3190 s2 = nmd->params[j].regoff;
3193 /* nmd's regoff is relative to the start of the param array */
3194 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3195 M_AST(s1, REG_SP, s2);
3199 if (!nmd->params[j].inmemory) {
3200 /* JIT stack arg -> NAT reg arg */
3202 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3203 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3205 assert(false); /* path never taken */
3208 s1 = md->params[i].regoff + cd->stackframesize * 8;
3209 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3210 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3211 M_AST(REG_ITMP1, REG_SP, s2);
3216 /* floating point types */
3218 if (!md->params[i].inmemory) {
3219 s1 = md->params[i].regoff;
3221 if (!nmd->params[j].inmemory) {
3223 /* no mapping to regs needed, native flt args use regoff */
3224 s2 = nmd->params[j].regoff;
3226 /* JIT float regs are still on the stack */
3227 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3230 /* not supposed to happen with 16 NAT flt args */
3233 s2 = nmd->params[j].regoff;
3234 if (IS_2_WORD_TYPE(t))
3235 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3237 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3243 s1 = md->params[i].regoff;
3245 if (!nmd->params[j].inmemory) {
3247 /* JIT stack -> NAT reg */
3249 s2 = nmd->params[j].regoff;
3250 M_DLD(s2, REG_FP, JITSTACK + s1);
3254 /* JIT stack -> NAT stack */
3256 s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3258 /* The FTMP register may already be loaded with args */
3259 /* we know $f0 is unused because of the env pointer */
3260 M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3261 M_DST(REG_F0, REG_SP, BIAS + s2);
3268 /* put class into second argument register */
3270 if (m->flags & ACC_STATIC) {
3271 disp = dseg_add_address(cd, m->class);
3272 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3275 /* put env into first argument register */
3277 disp = dseg_add_address(cd, _Jv_env);
3278 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3280 /* do the native function call */
3282 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3283 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3284 M_NOP; /* delay slot */
3286 /* save return value */
3288 if (md->returntype.type != TYPE_VOID) {
3289 if (IS_INT_LNG_TYPE(md->returntype.type))
3290 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3292 M_DST(REG_FRESULT, REG_SP, CSTACK);
3295 /* Note: native functions return float values in %f0 (see ABI) */
3296 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3298 #if !defined(NDEBUG)
3299 /* But for the trace function we need to put a flt result into %f1 */
3300 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3301 if (!IS_2_WORD_TYPE(md->returntype.type))
3302 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3303 emit_verbosecall_exit(jd);
3307 /* remove native stackframe info */
3309 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3310 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3311 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3312 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3313 M_NOP; /* XXX fill me! */
3314 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3316 /* restore float return value, int return value already in our return reg */
3318 if (md->returntype.type != TYPE_VOID) {
3319 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3320 if (IS_2_WORD_TYPE(md->returntype.type))
3321 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3323 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3327 /* check for exception */
3328 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3331 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3334 /* handle exception */
3336 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3337 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3338 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3339 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3340 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3342 /* generate patcher stubs */
3344 emit_patcher_stubs(jd);
3348 * These are local overrides for various environment variables in Emacs.
3349 * Please do not remove this and leave it at the end of the file, where
3350 * Emacs will automagically detect them.
3351 * ---------------------------------------------------------------------
3354 * indent-tabs-mode: t
3358 * vim:noexpandtab:sw=4:ts=4: