1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
40 /* #include "vm/jit/sparc64/arch.h" */
41 #include "vm/jit/sparc64/codegen.h"
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/localref.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/sparc64/emit.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/parse.h"
60 #include "vm/jit/patcher.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vmcore/loader.h"
65 #include "vmcore/options.h"
67 #include "vm/jit/sparc64/solaris/macro_rename.h"
69 #define BUILTIN_FLOAT_ARGS 1
71 /* XXX use something like this for window control ?
72 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
74 #define REG_PV REG_PV_CALLEE
79 if ((disp < -4096) || (disp > 4095))
80 printf("disp %d\n", disp);
83 return (disp >= -4096) && (disp <= 4095);
86 s4 get_lopart_disp(disp)
91 lodisp = setlo_part(disp);
93 if (setlo_part(disp) == 0)
96 lodisp = setlo_part(disp) | 0x1c00;
103 /* codegen_emit ****************************************************************
105 Generates machine code.
107 *******************************************************************************/
109 bool codegen_emit(jitdata *jd)
115 s4 len, s1, s2, s3, d, disp, slots;
121 constant_classref *cr;
122 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
123 unresolved_method *um;
124 builtintable_entry *bte;
127 unresolved_field *uf;
131 /* get required compiler data */
138 /* prevent compiler warnings */
149 #if 0 /* no leaf optimization yet */
150 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
152 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
155 /* space to save used callee saved registers */
157 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
158 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
160 cd->stackframesize = rd->memuse + savedregs_num;
162 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
163 if (checksync && (m->flags & ACC_SYNCHRONIZED))
164 cd->stackframesize++;
167 /* keep stack 16-byte aligned (ABI requirement) */
169 if (cd->stackframesize & 1)
170 cd->stackframesize++;
172 /* create method header */
174 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
175 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
177 #if defined(ENABLE_THREADS)
178 /* IsSync contains the offset relative to the stack pointer for the
179 argument of monitor_exit used in the exception handler. Since the
180 offset could be zero and give a wrong meaning of the flag it is
184 if (checksync && (m->flags & ACC_SYNCHRONIZED))
185 (void) dseg_add_unique_s4(cd, JITSTACK + (rd->memuse + 1) * 8); /* IsSync */
188 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
190 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
191 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
192 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
193 dseg_addlinenumbertablesize(cd);
194 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
196 /* create exception table */
198 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
199 dseg_add_target(cd, ex->start);
200 dseg_add_target(cd, ex->end);
201 dseg_add_target(cd, ex->handler);
202 (void) dseg_add_unique_address(cd, ex->catchtype.any);
205 /* save register window and create stack frame (if necessary) */
207 if (cd->stackframesize)
208 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
211 /* save callee saved float registers (none right now) */
213 p = cd->stackframesize;
214 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
215 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
220 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
221 emit_verbosecall_enter(jd);
225 /* call monitorenter function */
226 #if defined(ENABLE_THREADS)
227 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
228 /* stack offset for monitor argument */
232 /* save float argument registers */
236 ALIGN_STACK_SLOTS(slots);
238 M_LDA(REG_SP, REG_SP, -(slots * 8));
239 for (i = 0; i < FLT_ARG_CNT; i++)
240 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
244 /* get correct lock object */
246 if (m->flags & ACC_STATIC) {
247 disp = dseg_add_address(cd, &m->class->object.header);
248 M_ALD(REG_OUT0, REG_PV, disp);
249 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
250 M_ALD(REG_ITMP3, REG_PV, disp);
253 /* copy class pointer: $i0 -> $o0 */
254 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
256 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
257 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
258 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
261 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
262 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
264 /* restore float argument registers */
266 for (i = 0; i < FLT_ARG_CNT; i++)
267 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
269 M_LDA(REG_SP, REG_SP, slots * 8);
274 /* take arguments out of register or stack frame */
278 for (p = 0, l = 0; p < md->paramcount; p++) {
279 t = md->paramtypes[p].type;
281 varindex = jd->local_map[l * 5 + t];
284 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
287 if (varindex == UNUSED)
291 s1 = md->params[p].regoff;
293 if (IS_INT_LNG_TYPE(t)) { /* integer args */
297 if (!md->params[p].inmemory) { /* register arguments */
298 s1 = REG_WINDOW_TRANSPOSE(s1);
300 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
302 /* the register allocator does not know about the window. */
303 /* avoid copying the locals from save to save regs by */
304 /* swapping variables. */
307 int old_dest = var->vv.regoff;
308 int new_dest = p + 24;
310 /* run through all variables */
312 for (i = 0; i < jd->varcount; i++) {
313 varinfo* uvar = VAR(i);
315 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
318 s2 = uvar->vv.regoff;
320 /* free the in reg by moving all other references */
322 if (s2 == new_dest) {
323 uvar->vv.regoff = old_dest;
324 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
327 /* move all variables to the in reg */
329 if (s2 == old_dest) {
330 uvar->vv.regoff = new_dest;
331 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
339 else { /* reg arg -> spilled */
340 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
343 } else { /* stack arguments */
344 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
345 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
347 } else { /* stack arg -> spilled */
348 /* add the callers window save registers */
349 var->vv.regoff = cd->stackframesize * 8 + s1;
353 } else { /* floating args */
354 if (!md->params[p].inmemory) { /* register arguments */
355 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
356 M_FLTMOVE(s1, var->vv.regoff);
358 } else { /* reg arg -> spilled */
359 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
362 } else { /* stack arguments */
363 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
364 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
366 } else { /* stack-arg -> spilled */
367 var->vv.regoff = cd->stackframesize * 8 + s1;
376 /* end of header generation */
378 /* create replacement points */
380 REPLACEMENT_POINTS_INIT(cd, jd);
382 /* walk through all basic blocks */
384 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
386 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
388 if (bptr->flags >= BBREACHED) {
390 /* branch resolving */
392 codegen_resolve_branchrefs(cd, bptr);
394 /* handle replacement points */
397 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
398 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
404 /* copy interface registers to their destination */
409 #if defined(ENABLE_LSRA)
410 #error XXX LSRA not tested yet
414 src = bptr->invars[len];
415 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
416 /* d = reg_of_var(m, src, REG_ITMP1); */
417 if (!(src->flags & INMEMORY))
421 M_INTMOVE(REG_ITMP1, d);
422 emit_store(jd, NULL, src, d);
429 var = VAR(bptr->invars[len]);
430 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
431 d = codegen_reg_of_var(0, var, REG_ITMP1);
432 M_INTMOVE(REG_ITMP2_XPTR, d);
433 emit_store(jd, NULL, var, d);
436 assert((var->flags & INOUT));
439 #if defined(ENABLE_LSRA)
442 /* walk through all instructions */
446 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
447 if (iptr->line != currentline) {
448 dseg_addlinenumber(cd, iptr->line);
449 currentline = iptr->line;
452 MCODECHECK(64); /* an instruction usually needs < 64 words */
456 case ICMD_INLINE_START:
457 case ICMD_INLINE_END:
460 case ICMD_NOP: /* ... ==> ... */
463 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
466 emit_nullpointer_check(cd, iptr, s1);
469 /* constant operations ************************************************/
471 case ICMD_ICONST: /* ... ==> ..., constant */
473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
474 ICONST(d, iptr->sx.val.i);
475 emit_store_dst(jd, iptr, d);
478 case ICMD_LCONST: /* ... ==> ..., constant */
480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
481 LCONST(d, iptr->sx.val.l);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_FCONST: /* ... ==> ..., constant */
487 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
488 disp = dseg_add_float(cd, iptr->sx.val.f);
489 M_FLD(d, REG_PV, disp);
490 emit_store_dst(jd, iptr, d);
493 case ICMD_DCONST: /* ... ==> ..., constant */
495 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
496 disp = dseg_add_double(cd, iptr->sx.val.d);
497 M_DLD(d, REG_PV, disp);
498 emit_store_dst(jd, iptr, d);
501 case ICMD_ACONST: /* ... ==> ..., constant */
503 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
505 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
506 cr = iptr->sx.val.c.ref;
507 disp = dseg_add_unique_address(cd, cr);
509 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
511 M_ALD(d, REG_PV, disp);
515 if (iptr->sx.val.anyptr == NULL) {
516 M_INTMOVE(REG_ZERO, d);
519 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
520 M_ALD(d, REG_PV, disp);
523 emit_store_dst(jd, iptr, d);
527 /* load/store/copy/move operations ************************************/
529 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
534 case ICMD_ISTORE: /* ..., value ==> ... */
545 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
550 /* pop/dup/swap operations ********************************************/
552 /* attention: double and longs are only one entry in CACAO ICMDs */
554 case ICMD_POP: /* ..., value ==> ... */
555 case ICMD_POP2: /* ..., value, value ==> ... */
559 /* integer operations *************************************************/
561 case ICMD_INEG: /* ..., value ==> ..., - value */
564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 M_SUB(REG_ZERO, s1, d);
567 emit_store_dst(jd, iptr, d);
570 case ICMD_I2L: /* ..., value ==> ..., value */
572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
573 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
575 emit_store_dst(jd, iptr, d);
578 case ICMD_L2I: /* ..., value ==> ..., value */
580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
582 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
583 emit_store_dst(jd, iptr, d);
586 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
590 M_SLLX_IMM(s1, 56, d);
591 M_SRAX_IMM( d, 56, d);
592 emit_store_dst(jd, iptr, d);
595 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
597 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
599 M_SLLX_IMM(s1, 48, d);
600 M_SRLX_IMM( d, 48, d);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 M_SLLX_IMM(s1, 48, d);
609 M_SRAX_IMM( d, 48, d);
610 emit_store_dst(jd, iptr, d);
613 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 emit_store_dst(jd, iptr, d);
624 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
625 /* sx.val.i = constant */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
629 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
630 M_ADD_IMM(s1, iptr->sx.val.i, d);
632 ICONST(REG_ITMP2, iptr->sx.val.i);
633 M_ADD(s1, REG_ITMP2, d);
635 emit_store_dst(jd, iptr, d);
638 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
639 /* sx.val.l = constant */
641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
643 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
644 M_ADD_IMM(s1, iptr->sx.val.l, d);
646 LCONST(REG_ITMP2, iptr->sx.val.l);
647 M_ADD(s1, REG_ITMP2, d);
649 emit_store_dst(jd, iptr, d);
652 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
656 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
659 emit_store_dst(jd, iptr, d);
662 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
663 /* sx.val.i = constant */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
667 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
668 M_SUB_IMM(s1, iptr->sx.val.i, d);
670 ICONST(REG_ITMP2, iptr->sx.val.i);
671 M_SUB(s1, REG_ITMP2, d);
673 emit_store_dst(jd, iptr, d);
676 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
677 /* sx.val.l = constant */
679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
681 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
682 M_SUB_IMM(s1, iptr->sx.val.l, d);
684 LCONST(REG_ITMP2, iptr->sx.val.l);
685 M_SUB(s1, REG_ITMP2, d);
687 emit_store_dst(jd, iptr, d);
690 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
697 emit_store_dst(jd, iptr, d);
700 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
701 /* sx.val.i = constant */
703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
705 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
706 M_MULX_IMM(s1, iptr->sx.val.i, d);
708 ICONST(REG_ITMP2, iptr->sx.val.i);
709 M_MULX(s1, REG_ITMP2, d);
711 emit_store_dst(jd, iptr, d);
714 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
715 /* sx.val.l = constant */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
719 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
720 M_MULX_IMM(s1, iptr->sx.val.l, d);
722 LCONST(REG_ITMP2, iptr->sx.val.l);
723 M_MULX(s1, REG_ITMP2, d);
725 emit_store_dst(jd, iptr, d);
728 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
729 /* XXX could also clear Y and use 32bit div */
730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
733 emit_arithmetic_check(cd, iptr, s2);
735 /* XXX trim s2 like s1 ? */
737 emit_store_dst(jd, iptr, d);
740 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
745 emit_arithmetic_check(cd, iptr, s2);
747 emit_store_dst(jd, iptr, d);
750 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
755 emit_arithmetic_check(cd, iptr, s2);
757 /* XXX trim s2 like s1 ? */
758 M_DIVX(s1, s2, REG_ITMP3);
759 M_MULX(s2, REG_ITMP3, REG_ITMP3);
760 M_SUB(s1, REG_ITMP3, d);
761 emit_store_dst(jd, iptr, d);
764 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
769 emit_arithmetic_check(cd, iptr, s2);
770 M_DIVX(s1, s2, REG_ITMP3);
771 M_MULX(s2, REG_ITMP3, REG_ITMP3);
772 M_SUB(s1, REG_ITMP3, d);
773 emit_store_dst(jd, iptr, d);
776 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
777 case ICMD_LDIVPOW2: /* val.i = constant */
779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
780 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
781 M_SRAX_IMM(s1, 63, REG_ITMP2);
782 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
783 M_ADD(s1, REG_ITMP2, REG_ITMP2);
784 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
785 emit_store_dst(jd, iptr, d);
788 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
800 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803 emit_store_dst(jd, iptr, d);
806 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
807 /* val.i = constant */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
811 M_SLL_IMM(s1, iptr->sx.val.i, d);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
816 /* val.i = constant */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
820 M_SLLX_IMM(s1, iptr->sx.val.i, d);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
834 /* sx.val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
838 M_SRA_IMM(s1, iptr->sx.val.i, d);
839 emit_store_dst(jd, iptr, d);
842 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
844 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
845 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
848 emit_store_dst(jd, iptr, d);
851 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
852 /* sx.val.i = constant */
854 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
855 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
856 M_SRL_IMM(s1, iptr->sx.val.i, d);
857 emit_store_dst(jd, iptr, d);
860 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
863 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
864 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 emit_store_dst(jd, iptr, d);
869 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
870 /* sx.val.i = constant */
872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
874 M_SRAX_IMM(s1, iptr->sx.val.i, d);
875 emit_store_dst(jd, iptr, d);
878 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
880 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
881 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
882 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
884 emit_store_dst(jd, iptr, d);
887 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
888 /* sx.val.i = constant */
890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
891 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
892 M_SRLX_IMM(s1, iptr->sx.val.i, d);
893 emit_store_dst(jd, iptr, d);
896 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
901 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
903 emit_store_dst(jd, iptr, d);
906 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
907 /* sx.val.i = constant */
909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
910 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
911 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
912 M_AND_IMM(s1, iptr->sx.val.i, d);
914 ICONST(REG_ITMP2, iptr->sx.val.i);
915 M_AND(s1, REG_ITMP2, d);
917 emit_store_dst(jd, iptr, d);
920 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
921 /* sx.val.i = constant */
922 /* constant is actually constant - 1 */
924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
927 M_MOV(s1, REG_ITMP1);
930 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
931 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
932 M_AND_IMM(s1, iptr->sx.val.i, d);
935 M_SUB(REG_ZERO, s1, d);
936 M_AND_IMM(d, iptr->sx.val.i, d);
938 ICONST(REG_ITMP2, iptr->sx.val.i);
939 M_AND(s1, REG_ITMP2, d);
942 M_SUB(REG_ZERO, s1, d);
943 M_AND(d, REG_ITMP2, d);
945 M_SUB(REG_ZERO, d, d);
946 emit_store_dst(jd, iptr, d);
949 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
950 /* sx.val.l = constant */
952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
953 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
954 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
955 M_AND_IMM(s1, iptr->sx.val.l, d);
957 LCONST(REG_ITMP2, iptr->sx.val.l);
958 M_AND(s1, REG_ITMP2, d);
960 emit_store_dst(jd, iptr, d);
963 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
964 /* sx.val.l = constant */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
969 M_MOV(s1, REG_ITMP1);
972 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
973 M_AND_IMM(s1, iptr->sx.val.l, d);
976 M_SUB(REG_ZERO, s1, d);
977 M_AND_IMM(d, iptr->sx.val.l, d);
979 LCONST(REG_ITMP2, iptr->sx.val.l);
980 M_AND(s1, REG_ITMP2, d);
983 M_SUB(REG_ZERO, s1, d);
984 M_AND(d, REG_ITMP2, d);
986 M_SUB(REG_ZERO, d, d);
987 emit_store_dst(jd, iptr, d);
990 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
993 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
994 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
997 emit_store_dst(jd, iptr, d);
1000 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1001 /* sx.val.i = constant */
1003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1004 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1005 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1006 M_OR_IMM(s1, iptr->sx.val.i, d);
1008 ICONST(REG_ITMP2, iptr->sx.val.i);
1009 M_OR(s1, REG_ITMP2, d);
1011 emit_store_dst(jd, iptr, d);
1014 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1015 /* sx.val.l = constant */
1017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1018 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1019 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1020 M_OR_IMM(s1, iptr->sx.val.l, d);
1022 LCONST(REG_ITMP2, iptr->sx.val.l);
1023 M_OR(s1, REG_ITMP2, d);
1025 emit_store_dst(jd, iptr, d);
1028 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1032 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1033 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1035 emit_store_dst(jd, iptr, d);
1038 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1039 /* sx.val.i = constant */
1041 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1042 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1043 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1044 M_XOR_IMM(s1, iptr->sx.val.i, d);
1046 ICONST(REG_ITMP2, iptr->sx.val.i);
1047 M_XOR(s1, REG_ITMP2, d);
1049 emit_store_dst(jd, iptr, d);
1052 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1053 /* sx.val.l = constant */
1055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1056 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1057 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1058 M_XOR_IMM(s1, iptr->sx.val.l, d);
1060 LCONST(REG_ITMP2, iptr->sx.val.l);
1061 M_XOR(s1, REG_ITMP2, d);
1063 emit_store_dst(jd, iptr, d);
1067 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1070 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1071 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1074 M_XCMOVLT_IMM(-1, d);
1075 M_XCMOVGT_IMM(1, d);
1076 emit_store_dst(jd, iptr, d);
1080 /* floating operations ************************************************/
1082 case ICMD_FNEG: /* ..., value ==> ..., - value */
1084 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1085 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_DNEG: /* ..., value ==> ..., - value */
1092 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1093 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1100 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1101 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1102 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1109 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1118 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1119 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1120 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1127 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1128 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1129 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1131 emit_store_dst(jd, iptr, d);
1134 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1136 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1137 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1146 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1147 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1154 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1155 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1158 emit_store_dst(jd, iptr, d);
1161 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1163 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1164 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1167 emit_store_dst(jd, iptr, d);
1171 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1172 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1173 disp = dseg_add_unique_float(cd, 0.0);
1174 M_IST (s1, REG_PV_CALLEE, disp);
1175 M_FLD (d, REG_PV_CALLEE, disp);
1176 M_CVTIF (d, d); /* rd gets translated to double target register */
1177 emit_store_dst(jd, iptr, d);
1181 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1182 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1183 disp = dseg_add_unique_float(cd, 0.0);
1184 M_IST(s1, REG_PV_CALLEE, disp);
1185 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1186 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1187 emit_store_dst(jd, iptr, d);
1191 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1193 disp = dseg_add_unique_double(cd, 0.0);
1194 M_STX(s1, REG_PV_CALLEE, disp);
1195 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1196 M_CVTLF(REG_FTMP3, d);
1197 emit_store_dst(jd, iptr, d);
1201 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1202 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1203 disp = dseg_add_unique_double(cd, 0.0);
1204 M_STX(s1, REG_PV_CALLEE, disp);
1205 M_DLD(d, REG_PV_CALLEE, disp);
1207 emit_store_dst(jd, iptr, d);
1210 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1211 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1212 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1213 disp = dseg_add_unique_float(cd, 0.0);
1215 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1218 M_MOV(REG_ZERO, d); /* delay slot */
1220 M_CVTFI(s1, REG_FTMP2);
1221 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1222 M_ILD(d, REG_PV, disp);
1223 emit_store_dst(jd, iptr, d);
1227 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1228 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1229 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1230 disp = dseg_add_unique_float(cd, 0.0);
1232 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1235 M_MOV(REG_ZERO, d); /* delay slot */
1237 M_CVTDI(s1, REG_FTMP2);
1238 M_FST(REG_FTMP2, REG_PV, disp);
1239 M_ILD(d, REG_PV, disp);
1240 emit_store_dst(jd, iptr, d);
1243 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1244 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1246 disp = dseg_add_unique_double(cd, 0.0);
1248 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1251 M_MOV(REG_ZERO, d); /* delay slot */
1253 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1254 M_DST(REG_FTMP2, REG_PV, disp);
1255 M_LDX(d, REG_PV, disp);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1260 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1261 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1262 disp = dseg_add_unique_double(cd, 0.0);
1264 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1267 M_MOV(REG_ZERO, d); /* delay slot */
1269 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1270 M_DST(REG_FTMP2, REG_PV, disp);
1271 M_LDX(d, REG_PV, disp);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1277 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1280 emit_store_dst(jd, iptr, d);
1283 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1285 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1286 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1288 emit_store_dst(jd, iptr, d);
1291 /* XXX merge F/D versions? only compare instr. is different */
1292 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1294 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1295 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1296 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1298 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1299 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1300 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1306 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1307 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1308 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1310 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1311 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1312 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1313 emit_store_dst(jd, iptr, d);
1316 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1318 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1319 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1320 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1322 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1323 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1324 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1330 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1332 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1334 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1335 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1336 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1337 emit_store_dst(jd, iptr, d);
1341 /* memory operations **************************************************/
1343 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1347 emit_nullpointer_check(cd, iptr, s1);
1348 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1349 emit_store_dst(jd, iptr, d);
1352 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1354 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1355 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1356 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1357 /* implicit null-pointer check */
1358 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1359 M_AADD(s2, s1, REG_ITMP3);
1360 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1361 emit_store_dst(jd, iptr, d);
1364 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1368 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1369 /* implicit null-pointer check */
1370 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1371 M_AADD(s2, s1, REG_ITMP3);
1372 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1373 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1374 emit_store_dst(jd, iptr, d);
1377 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1379 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1380 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1381 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1382 /* implicit null-pointer check */
1383 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1384 M_AADD(s2, s1, REG_ITMP3);
1385 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1386 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1387 emit_store_dst(jd, iptr, d);
1390 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1392 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1393 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1394 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1395 /* implicit null-pointer check */
1396 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1397 M_ASLL_IMM(s2, 2, REG_ITMP3);
1398 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1399 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1400 emit_store_dst(jd, iptr, d);
1403 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1405 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1406 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1407 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1408 /* implicit null-pointer check */
1409 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1410 M_ASLL_IMM(s2, 3, REG_ITMP3);
1411 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1412 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1419 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1420 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1421 /* implicit null-pointer check */
1422 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1423 M_ASLL_IMM(s2, 2, REG_ITMP3);
1424 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1425 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1432 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1433 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1434 /* implicit null-pointer check */
1435 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436 M_ASLL_IMM(s2, 3, REG_ITMP3);
1437 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1438 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1439 emit_store_dst(jd, iptr, d);
1442 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1444 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1445 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1447 /* implicit null-pointer check */
1448 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1449 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1450 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1451 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1452 emit_store_dst(jd, iptr, d);
1456 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1458 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1459 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1460 /* implicit null-pointer check */
1461 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1462 M_AADD(s2, s1, REG_ITMP1);
1463 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1464 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1467 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1468 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1472 /* implicit null-pointer check */
1473 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1474 M_AADD(s2, s1, REG_ITMP1);
1475 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1476 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1477 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1480 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1484 /* implicit null-pointer check */
1485 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1486 M_ASLL_IMM(s2, 2, REG_ITMP2);
1487 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1488 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1489 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1492 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1494 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1495 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1496 /* implicit null-pointer check */
1497 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1498 M_ASLL_IMM(s2, 3, REG_ITMP2);
1499 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1500 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1501 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1504 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1508 /* implicit null-pointer check */
1509 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1510 M_ASLL_IMM(s2, 2, REG_ITMP2);
1511 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1512 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1513 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1516 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1519 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1520 /* implicit null-pointer check */
1521 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1522 M_ASLL_IMM(s2, 3, REG_ITMP2);
1523 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1524 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1525 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1529 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1533 /* implicit null-pointer check */
1534 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1535 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1537 M_MOV(s1, REG_OUT0);
1538 M_MOV(s3, REG_OUT1);
1539 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1540 M_ALD(REG_ITMP3, REG_PV, disp);
1541 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1543 emit_exception_check(cd, iptr);
1545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1546 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1547 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1548 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1549 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1550 /* implicit null-pointer check */
1551 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1555 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1558 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1559 /* implicit null-pointer check */
1560 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1561 M_AADD(s2, s1, REG_ITMP1);
1562 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1565 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1566 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1570 /* implicit null-pointer check */
1571 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1572 M_AADD(s2, s1, REG_ITMP1);
1573 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1574 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1577 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1580 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1581 /* implicit null-pointer check */
1582 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1583 M_ASLL_IMM(s2, 2, REG_ITMP2);
1584 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1585 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1588 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1591 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1592 /* implicit null-pointer check */
1593 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1594 M_ASLL_IMM(s2, 3, REG_ITMP2);
1595 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1596 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1599 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1602 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1603 /* implicit null-pointer check */
1604 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1605 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1606 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1607 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1611 case ICMD_GETSTATIC: /* ... ==> ..., value */
1613 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1614 uf = iptr->sx.s23.s3.uf;
1615 fieldtype = uf->fieldref->parseddesc.fd->type;
1616 disp = dseg_add_unique_address(cd, uf);
1618 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1621 fi = iptr->sx.s23.s3.fmiref->p.field;
1622 fieldtype = fi->type;
1623 disp = dseg_add_address(cd, fi->value);
1625 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1626 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1629 M_ALD(REG_ITMP1, REG_PV, disp);
1631 switch (fieldtype) {
1633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1634 M_ILD_INTERN(d, REG_ITMP1, 0);
1637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1638 M_LDX_INTERN(d, REG_ITMP1, 0);
1641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1642 M_ALD_INTERN(d, REG_ITMP1, 0);
1645 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1646 M_FLD_INTERN(d, REG_ITMP1, 0);
1649 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1650 M_DLD_INTERN(d, REG_ITMP1, 0);
1653 emit_store_dst(jd, iptr, d);
1656 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1658 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1659 uf = iptr->sx.s23.s3.uf;
1660 fieldtype = uf->fieldref->parseddesc.fd->type;
1661 disp = dseg_add_unique_address(cd, uf);
1663 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1666 fi = iptr->sx.s23.s3.fmiref->p.field;
1667 fieldtype = fi->type;
1668 disp = dseg_add_address(cd, fi->value);
1670 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1671 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1674 M_ALD(REG_ITMP1, REG_PV, disp);
1676 switch (fieldtype) {
1678 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1679 M_IST_INTERN(s1, REG_ITMP1, 0);
1682 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1683 M_STX_INTERN(s1, REG_ITMP1, 0);
1686 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1687 M_AST_INTERN(s1, REG_ITMP1, 0);
1690 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1691 M_FST_INTERN(s1, REG_ITMP1, 0);
1694 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1695 M_DST_INTERN(s1, REG_ITMP1, 0);
1700 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1701 /* val = value (in current instruction) */
1702 /* following NOP) */
1704 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1705 uf = iptr->sx.s23.s3.uf;
1706 fieldtype = uf->fieldref->parseddesc.fd->type;
1707 disp = dseg_add_unique_address(cd, uf);
1709 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1712 fi = iptr->sx.s23.s3.fmiref->p.field;
1713 fieldtype = fi->type;
1714 disp = dseg_add_address(cd, fi->value);
1716 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1717 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1720 M_ALD(REG_ITMP1, REG_PV, disp);
1722 switch (fieldtype) {
1724 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1727 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1730 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1733 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1736 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1742 case ICMD_GETFIELD: /* ... ==> ..., value */
1744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1745 emit_nullpointer_check(cd, iptr, s1);
1747 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1748 uf = iptr->sx.s23.s3.uf;
1750 fieldtype = uf->fieldref->parseddesc.fd->type;
1753 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1756 fi = iptr->sx.s23.s3.fmiref->p.field;
1757 fieldtype = fi->type;
1761 switch (fieldtype) {
1763 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1775 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1779 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1786 emit_store_dst(jd, iptr, d);
1789 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1792 emit_nullpointer_check(cd, iptr, s1);
1794 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1795 uf = iptr->sx.s23.s3.uf;
1796 fieldtype = uf->fieldref->parseddesc.fd->type;
1801 fi = iptr->sx.s23.s3.fmiref->p.field;
1802 fieldtype = fi->type;
1806 if (IS_INT_LNG_TYPE(fieldtype))
1807 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1809 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1811 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1812 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1814 switch (fieldtype) {
1816 M_IST(s2, s1, disp);
1819 M_STX(s2, s1, disp);
1822 M_AST(s2, s1, disp);
1825 M_FST(s2, s1, disp);
1828 M_DST(s2, s1, disp);
1836 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1837 /* val = value (in current instruction) */
1838 /* following NOP) */
1840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1841 emit_nullpointer_check(cd, iptr, s1);
1843 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1844 unresolved_field *uf = iptr->sx.s23.s3.uf;
1846 fieldtype = uf->fieldref->parseddesc.fd->type;
1848 codegen_addpatchref(cd, PATCHER_get_putfield,
1851 if (opt_showdisassemble) {
1859 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1861 fieldtype = fi->type;
1867 switch (fieldtype) {
1869 M_IST(REG_ZERO, s1, disp);
1872 M_STX(REG_ZERO, s1, disp);
1875 M_AST(REG_ZERO, s1, disp);
1878 M_FST(REG_ZERO, s1, disp);
1881 M_DST(REG_ZERO, s1, disp);
1887 /* branch operations **************************************************/
1889 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1892 M_INTMOVE(s1, REG_ITMP2_XPTR);
1894 #ifdef ENABLE_VERIFIER
1895 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1896 unresolved_class *uc = iptr->sx.s23.s2.uc;
1898 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1900 #endif /* ENABLE_VERIFIER */
1902 disp = dseg_add_functionptr(cd, asm_handle_exception);
1903 M_ALD(REG_ITMP1, REG_PV, disp);
1904 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1906 M_NOP; /* nop ensures that XPC is less than the end */
1907 /* of basic block */
1911 case ICMD_GOTO: /* ... ==> ... */
1912 case ICMD_RET: /* ... ==> ... */
1914 emit_br(cd, iptr->dst.block);
1918 case ICMD_JSR: /* ... ==> ... */
1920 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1924 case ICMD_IFNULL: /* ..., value ==> ... */
1925 case ICMD_IFNONNULL:
1927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1928 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1931 /* Note: int compares must not branch on the register directly. */
1932 /* Reason is, that register content is not 32-bit clean. */
1934 case ICMD_IFEQ: /* ..., value ==> ... */
1936 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1938 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1939 M_CMP_IMM(s1, iptr->sx.val.i);
1942 ICONST(REG_ITMP2, iptr->sx.val.i);
1943 M_CMP(s1, REG_ITMP2);
1945 emit_beq(cd, iptr->dst.block);
1948 case ICMD_IFLT: /* ..., value ==> ... */
1950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1952 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1953 M_CMP_IMM(s1, iptr->sx.val.i);
1956 ICONST(REG_ITMP2, iptr->sx.val.i);
1957 M_CMP(s1, REG_ITMP2);
1959 emit_blt(cd, iptr->dst.block);
1962 case ICMD_IFLE: /* ..., value ==> ... */
1964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1966 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1967 M_CMP_IMM(s1, iptr->sx.val.i);
1970 ICONST(REG_ITMP2, iptr->sx.val.i);
1971 M_CMP(s1, REG_ITMP2);
1973 emit_ble(cd, iptr->dst.block);
1976 case ICMD_IFNE: /* ..., value ==> ... */
1978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1980 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1981 M_CMP_IMM(s1, iptr->sx.val.i);
1984 ICONST(REG_ITMP2, iptr->sx.val.i);
1985 M_CMP(s1, REG_ITMP2);
1987 emit_bne(cd, iptr->dst.block);
1990 case ICMD_IFGT: /* ..., value ==> ... */
1992 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1994 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1995 M_CMP_IMM(s1, iptr->sx.val.i);
1998 ICONST(REG_ITMP2, iptr->sx.val.i);
1999 M_CMP(s1, REG_ITMP2);
2001 emit_bgt(cd, iptr->dst.block);
2004 case ICMD_IFGE: /* ..., value ==> ... */
2006 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2008 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2009 M_CMP_IMM(s1, iptr->sx.val.i);
2012 ICONST(REG_ITMP2, iptr->sx.val.i);
2013 M_CMP(s1, REG_ITMP2);
2015 emit_bge(cd, iptr->dst.block);
2018 case ICMD_IF_LEQ: /* ..., value ==> ... */
2020 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2021 if (iptr->sx.val.l == 0)
2022 emit_beqz(cd, iptr->dst.block, s1);
2024 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2025 M_CMP_IMM(s1, iptr->sx.val.l);
2028 LCONST(REG_ITMP2, iptr->sx.val.l);
2029 M_CMP(s1, REG_ITMP2);
2031 emit_beq_xcc(cd, iptr->dst.block);
2035 case ICMD_IF_LLT: /* ..., value ==> ... */
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2038 if (iptr->sx.val.l == 0)
2039 emit_bltz(cd, iptr->dst.block, s1);
2041 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2042 M_CMP_IMM(s1, iptr->sx.val.l);
2045 LCONST(REG_ITMP2, iptr->sx.val.l);
2046 M_CMP(s1, REG_ITMP2);
2048 emit_blt_xcc(cd, iptr->dst.block);
2052 case ICMD_IF_LLE: /* ..., value ==> ... */
2054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2055 if (iptr->sx.val.l == 0)
2056 emit_blez(cd, iptr->dst.block, s1);
2058 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2059 M_CMP_IMM(s1, iptr->sx.val.l);
2062 LCONST(REG_ITMP2, iptr->sx.val.l);
2063 M_CMP(s1, REG_ITMP2);
2065 emit_ble_xcc(cd, iptr->dst.block);
2069 case ICMD_IF_LNE: /* ..., value ==> ... */
2071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2072 if (iptr->sx.val.l == 0)
2073 emit_bnez(cd, iptr->dst.block, s1);
2075 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2076 M_CMP_IMM(s1, iptr->sx.val.l);
2079 LCONST(REG_ITMP2, iptr->sx.val.l);
2080 M_CMP(s1, REG_ITMP2);
2082 emit_bne_xcc(cd, iptr->dst.block);
2086 case ICMD_IF_LGT: /* ..., value ==> ... */
2088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2089 if (iptr->sx.val.l == 0)
2090 emit_bgtz(cd, iptr->dst.block, s1);
2092 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2093 M_CMP_IMM(s1, iptr->sx.val.l);
2096 LCONST(REG_ITMP2, iptr->sx.val.l);
2097 M_CMP(s1, REG_ITMP2);
2099 emit_bgt_xcc(cd, iptr->dst.block);
2103 case ICMD_IF_LGE: /* ..., value ==> ... */
2105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2106 if (iptr->sx.val.l == 0)
2107 emit_bgez(cd, iptr->dst.block, s1);
2109 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2110 M_CMP_IMM(s1, iptr->sx.val.l);
2113 LCONST(REG_ITMP2, iptr->sx.val.l);
2114 M_CMP(s1, REG_ITMP2);
2116 emit_bge_xcc(cd, iptr->dst.block);
2121 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2122 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2124 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2125 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2127 emit_beq_xcc(cd, iptr->dst.block);
2130 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2133 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2135 emit_beq(cd, iptr->dst.block);
2138 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2139 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2142 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2144 emit_bne_xcc(cd, iptr->dst.block);
2147 case ICMD_IF_ICMPNE: /* 32-bit compare */
2149 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2150 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2152 emit_bne(cd, iptr->dst.block);
2155 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2160 emit_blt_xcc(cd, iptr->dst.block);
2163 case ICMD_IF_ICMPLT: /* 32-bit compare */
2165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2166 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2168 emit_blt(cd, iptr->dst.block);
2171 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2174 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2176 emit_bgt_xcc(cd, iptr->dst.block);
2179 case ICMD_IF_ICMPGT: /* 32-bit compare */
2181 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2182 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2184 emit_bgt(cd, iptr->dst.block);
2187 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2190 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2192 emit_ble_xcc(cd, iptr->dst.block);
2195 case ICMD_IF_ICMPLE: /* 32-bit compare */
2197 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2198 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2200 emit_ble(cd, iptr->dst.block);
2204 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2206 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2207 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2209 emit_bge_xcc(cd, iptr->dst.block);
2212 case ICMD_IF_ICMPGE: /* 32-bit compare */
2214 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2215 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2217 emit_bge(cd, iptr->dst.block);
2221 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2224 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2225 M_INTMOVE(s1, REG_RESULT_CALLEE);
2226 goto nowperformreturn;
2228 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2230 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2231 M_INTMOVE(s1, REG_RESULT_CALLEE);
2233 #ifdef ENABLE_VERIFIER
2234 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2235 unresolved_class *uc = iptr->sx.s23.s2.uc;
2237 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2239 #endif /* ENABLE_VERIFIER */
2240 goto nowperformreturn;
2242 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2245 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2246 M_DBLMOVE(s1, REG_FRESULT);
2247 goto nowperformreturn;
2249 case ICMD_RETURN: /* ... ==> ... */
2255 p = cd->stackframesize;
2257 #if !defined(NDEBUG)
2258 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2259 emit_verbosecall_exit(jd);
2262 #if defined(ENABLE_THREADS)
2263 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2264 /* XXX jit-c-call */
2265 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2266 M_ALD(REG_ITMP3, REG_PV, disp);
2268 /* we need to save fp return value (int saved by window) */
2270 switch (iptr->opc) {
2273 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2274 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2275 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2277 /* restore the fp return value */
2279 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2285 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2286 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2297 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2303 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2306 branch_target_t *table;
2308 table = iptr->dst.table;
2310 l = iptr->sx.s23.s2.tablelow;
2311 i = iptr->sx.s23.s3.tablehigh;
2313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2315 M_INTMOVE(s1, REG_ITMP1);
2317 else if (l <= 4095) {
2318 M_ADD_IMM(s1, -l, REG_ITMP1);
2321 ICONST(REG_ITMP2, l);
2322 /* XXX: do I need to truncate s1 to 32-bit ? */
2323 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2331 M_CMP_IMM(REG_ITMP1, i - 1);
2334 ICONST(REG_ITMP2, i - 1);
2335 M_CMP(REG_ITMP1, REG_ITMP2);
2337 emit_bugt(cd, table[0].block); /* default target */
2339 /* build jump table top down and use address of lowest entry */
2344 dseg_add_target(cd, table->block);
2349 /* length of dataseg after last dseg_addtarget is used by load */
2351 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2352 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2353 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2354 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2359 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2362 lookup_target_t *lookup;
2364 lookup = iptr->dst.lookup;
2366 i = iptr->sx.s23.s2.lookupcount;
2368 MCODECHECK((i<<2)+8);
2369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2372 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2373 M_CMP_IMM(s1, lookup->value);
2375 ICONST(REG_ITMP2, lookup->value);
2376 M_CMP(s1, REG_ITMP2);
2378 emit_beq(cd, lookup->target.block);
2382 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2388 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2390 bte = iptr->sx.s23.s3.bte;
2393 /* XXX: builtin calling with stack arguments not implemented */
2394 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2396 s3 = md->paramcount;
2398 MCODECHECK((s3 << 1) + 64);
2400 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2402 /* copy float arguments according to ABI convention */
2404 int num_fltregargs = 0;
2405 int fltregarg_inswap[16];
2407 for (s3 = s3 - 1; s3 >= 0; s3--) {
2408 var = VAR(iptr->sx.s23.s2.args[s3]);
2410 if (IS_FLT_DBL_TYPE(var->type)) {
2411 if (!md->params[s3].inmemory) {
2412 s1 = s3; /*native flt args use argument index directly*/
2413 d = emit_load(jd, iptr, var, REG_FTMP1);
2416 fltregarg_inswap[num_fltregargs] = s1;
2418 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2427 /* move swapped float args to target regs */
2428 for (i = 0; i < num_fltregargs; i++) {
2429 s1 = fltregarg_inswap[i];
2430 M_DMOV(s1 + 16, s1);
2431 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2435 assert(md->argfltreguse == 0);
2440 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2442 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2443 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2444 case ICMD_INVOKEINTERFACE:
2446 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2448 um = iptr->sx.s23.s3.um;
2449 md = um->methodref->parseddesc.md;
2452 lm = iptr->sx.s23.s3.fmiref->p.method;
2454 md = lm->parseddesc;
2458 s3 = md->paramcount;
2460 MCODECHECK((s3 << 1) + 64);
2462 /* copy arguments to registers or stack location */
2464 for (s3 = s3 - 1; s3 >= 0; s3--) {
2465 var = VAR(iptr->sx.s23.s2.args[s3]);
2466 d = md->params[s3].regoff;
2468 if (var->flags & PREALLOC)
2471 if (IS_INT_LNG_TYPE(var->type)) {
2472 if (!md->params[s3].inmemory) {
2473 s1 = emit_load(jd, iptr, var, d);
2477 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2478 M_STX(s1, REG_SP, JITSTACK + d);
2482 #ifdef BUILTIN_FLOAT_ARGS
2483 if (iptr->opc == ICMD_BUILTIN)
2487 if (!md->params[s3].inmemory) {
2488 s1 = emit_load(jd, iptr, var, d);
2489 if (IS_2_WORD_TYPE(var->type))
2495 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2496 M_DST(s1, REG_SP, JITSTACK + d);
2501 switch (iptr->opc) {
2503 disp = dseg_add_functionptr(cd, bte->fp);
2505 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2507 /* XXX jit-c-call */
2508 /* generate the actual call */
2510 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2512 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2513 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2514 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2516 emit_exception_check(cd, iptr);
2517 if (md->returntype.type == TYPE_FLT) {
2518 /* special handling for float return value in %f0 */
2523 case ICMD_INVOKESPECIAL:
2524 emit_nullpointer_check(cd, iptr, REG_OUT0);
2527 case ICMD_INVOKESTATIC:
2529 disp = dseg_add_unique_address(cd, NULL);
2531 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2535 disp = dseg_add_address(cd, lm->stubroutine);
2537 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2539 /* generate the actual call */
2541 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2543 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2544 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2545 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2548 case ICMD_INVOKEVIRTUAL:
2549 emit_nullpointer_check(cd, iptr, REG_OUT0);
2552 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2557 s1 = OFFSET(vftbl_t, table[0]) +
2558 sizeof(methodptr) * lm->vftblindex;
2560 /* implicit null-pointer check */
2561 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2562 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2564 /* generate the actual call */
2566 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2568 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2569 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2570 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2573 case ICMD_INVOKEINTERFACE:
2574 emit_nullpointer_check(cd, iptr, REG_OUT0);
2577 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2583 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2584 sizeof(methodptr*) * lm->class->index;
2586 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2589 /* implicit null-pointer check */
2590 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2591 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2592 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2594 /* generate the actual call */
2596 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2598 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2599 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2600 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2604 /* store return value */
2606 d = md->returntype.type;
2608 if (d != TYPE_VOID) {
2609 if (IS_INT_LNG_TYPE(d)) {
2610 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2611 M_INTMOVE(REG_RESULT_CALLER, s1);
2614 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2615 if (IS_2_WORD_TYPE(d)) {
2616 M_DBLMOVE(REG_FRESULT, s1);
2618 M_FLTMOVE(REG_FRESULT, s1);
2621 emit_store_dst(jd, iptr, s1);
2626 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2627 /* val.a: (classinfo*) superclass */
2629 /* superclass is an interface:
2631 * OK if ((sub == NULL) ||
2632 * (sub->vftbl->interfacetablelength > super->index) &&
2633 * (sub->vftbl->interfacetable[-super->index] != NULL));
2635 * superclass is a class:
2637 * OK if ((sub == NULL) || (0
2638 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2639 * super->vftbl->diffvall));
2642 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2646 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2651 super = iptr->sx.s23.s3.c.cls;
2652 superindex = super->index;
2655 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2656 CODEGEN_CRITICAL_SECTION_NEW;
2658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2660 /* if class is not resolved, check which code to call */
2662 if (super == NULL) {
2663 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2665 cr = iptr->sx.s23.s3.c.ref;
2666 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2668 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2671 M_ILD(REG_ITMP2, REG_PV, disp);
2672 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2673 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2676 /* interface checkcast code */
2678 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2679 if (super == NULL) {
2680 cr = iptr->sx.s23.s3.c.ref;
2682 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2686 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2689 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2690 M_ILD(REG_ITMP3, REG_ITMP2,
2691 OFFSET(vftbl_t, interfacetablelength));
2692 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2693 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2695 M_ALD(REG_ITMP3, REG_ITMP2,
2696 OFFSET(vftbl_t, interfacetable[0]) -
2697 superindex * sizeof(methodptr*));
2698 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2701 emit_label_br(cd, BRANCH_LABEL_4);
2703 emit_label(cd, BRANCH_LABEL_3);
2706 /* class checkcast code */
2708 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2709 if (super == NULL) {
2710 emit_label(cd, BRANCH_LABEL_2);
2712 cr = iptr->sx.s23.s3.c.ref;
2713 disp = dseg_add_unique_address(cd, NULL);
2715 codegen_add_patch_ref(cd,
2716 PATCHER_checkcast_instanceof_class,
2720 disp = dseg_add_address(cd, super->vftbl);
2722 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2725 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2726 M_ALD(REG_ITMP3, REG_PV, disp);
2728 CODEGEN_CRITICAL_SECTION_START;
2730 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2731 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2732 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2733 M_ALD(REG_ITMP3, REG_PV, disp);
2734 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2736 CODEGEN_CRITICAL_SECTION_END;
2739 M_CMP(REG_ITMP3, REG_ITMP2);
2740 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2743 emit_label(cd, BRANCH_LABEL_5);
2746 if (super == NULL) {
2747 emit_label(cd, BRANCH_LABEL_1);
2748 emit_label(cd, BRANCH_LABEL_4);
2751 d = codegen_reg_of_dst(jd, iptr, s1);
2754 /* array type cast-check */
2756 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2757 M_INTMOVE(s1, REG_OUT0);
2759 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2761 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2762 cr = iptr->sx.s23.s3.c.ref;
2763 disp = dseg_add_unique_address(cd, NULL);
2765 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2769 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2771 M_ALD(REG_OUT1, REG_PV, disp);
2772 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2773 M_ALD(REG_ITMP3, REG_PV, disp);
2774 /* XXX jit-c-call */
2775 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2779 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2781 d = codegen_reg_of_dst(jd, iptr, s1);
2785 emit_store_dst(jd, iptr, d);
2788 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2789 /* val.a: (classinfo*) superclass */
2791 /* superclass is an interface:
2793 * return (sub != NULL) &&
2794 * (sub->vftbl->interfacetablelength > super->index) &&
2795 * (sub->vftbl->interfacetable[-super->index] != NULL);
2797 * superclass is a class:
2799 * return ((sub != NULL) && (0
2800 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2801 * super->vftbl->diffvall));
2806 vftbl_t *supervftbl;
2809 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2815 super = iptr->sx.s23.s3.c.cls;
2816 superindex = super->index;
2817 supervftbl = super->vftbl;
2820 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2821 CODEGEN_CRITICAL_SECTION_NEW;
2823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2826 M_MOV(s1, REG_ITMP1);
2832 /* if class is not resolved, check which code to call */
2834 if (super == NULL) {
2835 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2837 cr = iptr->sx.s23.s3.c.ref;
2838 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2840 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2843 M_ILD(REG_ITMP3, REG_PV, disp);
2844 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2845 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2848 /* interface instanceof code */
2850 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2851 if (super == NULL) {
2852 cr = iptr->sx.s23.s3.c.ref;
2854 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2858 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2861 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2862 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2863 M_CMP_IMM(REG_ITMP3, superindex);
2866 M_ALD(REG_ITMP1, REG_ITMP1,
2867 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2868 superindex * sizeof(methodptr*)));
2869 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2872 emit_label_br(cd, BRANCH_LABEL_4);
2874 emit_label(cd, BRANCH_LABEL_3);
2877 /* class instanceof code */
2879 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2880 if (super == NULL) {
2881 emit_label(cd, BRANCH_LABEL_2);
2883 cr = iptr->sx.s23.s3.c.ref;
2884 disp = dseg_add_unique_address(cd, NULL);
2886 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2890 disp = dseg_add_address(cd, supervftbl);
2892 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2895 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2896 M_ALD(REG_ITMP2, REG_PV, disp);
2898 CODEGEN_CRITICAL_SECTION_START;
2900 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2901 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2902 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2904 CODEGEN_CRITICAL_SECTION_END;
2906 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2907 M_CMP(REG_ITMP1, REG_ITMP2);
2908 M_XCMOVULE_IMM(1, d);
2911 emit_label(cd, BRANCH_LABEL_5);
2914 if (super == NULL) {
2915 emit_label(cd, BRANCH_LABEL_1);
2916 emit_label(cd, BRANCH_LABEL_4);
2919 emit_store_dst(jd, iptr, d);
2923 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2925 /* check for negative sizes and copy sizes to stack if necessary */
2927 MCODECHECK((iptr->s1.argcount << 1) + 64);
2929 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2931 var = VAR(iptr->sx.s23.s2.args[s1]);
2933 /* copy SAVEDVAR sizes to stack */
2935 /* Already Preallocated? */
2937 if (!(var->flags & PREALLOC)) {
2938 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2939 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2943 /* arg 0 = dimension count */
2945 ICONST(REG_OUT0, iptr->s1.argcount);
2947 /* is patcher function set? */
2949 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2950 disp = dseg_add_unique_address(cd, 0);
2952 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2953 iptr->sx.s23.s3.c.ref,
2957 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2959 /* arg 1 = arraydescriptor */
2961 M_ALD(REG_OUT1, REG_PV, disp);
2963 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2965 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2967 /* XXX c abi call */
2968 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2969 M_ALD(REG_ITMP3, REG_PV, disp);
2970 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2973 /* check for exception before result assignment */
2975 emit_exception_check(cd, iptr);
2977 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2978 M_INTMOVE(REG_RESULT_CALLER, d);
2979 emit_store_dst(jd, iptr, d);
2983 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2989 } /* for instruction */
2993 /* At the end of a basic block we may have to append some nops,
2994 because the patcher stub calling code might be longer than the
2995 actual instruction. So codepatching does not change the
2996 following block unintentionally. */
2998 if (cd->mcodeptr < cd->lastmcodeptr) {
2999 while (cd->mcodeptr < cd->lastmcodeptr) {
3004 } /* if (bptr -> flags >= BBREACHED) */
3005 } /* for basic block */
3007 dseg_createlinenumbertable(cd);
3009 /* generate stubs */
3011 emit_patcher_stubs(jd);
3013 /* everything's ok */
3019 /* codegen_emit_stub_compiler **************************************************
3021 Emits a stub routine which calls the compiler.
3023 *******************************************************************************/
3025 void codegen_emit_stub_compiler(jitdata *jd)
3030 /* get required compiler data */
3035 /* code for the stub */
3037 /* no window save yet, user caller's PV */
3038 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3039 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3040 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3045 /* codegen_emit_stub_native ****************************************************
3047 Emits a stub routine which calls a native method.
3049 *******************************************************************************/
3051 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3058 s4 i, j; /* count variables */
3061 s4 funcdisp; /* displacement of the function */
3062 s4 fltregarg_offset[FLT_ARG_CNT];
3064 /* get required compiler data */
3070 /* initialize variables */
3073 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3075 /* calculate stack frame size */
3077 cd->stackframesize =
3078 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3079 sizeof(localref_table) / SIZEOF_VOID_P +
3080 md->paramcount + /* for saving arguments over calls */
3081 nmd->memuse + /* nmd->memuse includes the (6) abi params */
3085 /* keep stack 16-byte aligned (ABI requirement) */
3087 if (cd->stackframesize & 1)
3088 cd->stackframesize++;
3090 /* create method header */
3092 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3093 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3094 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3095 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3096 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3097 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3098 (void) dseg_addlinenumbertablesize(cd);
3099 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3101 /* generate stub code */
3103 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3105 #if !defined(NDEBUG)
3106 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3107 emit_verbosecall_enter(jd);
3110 /* get function address (this must happen before the stackframeinfo) */
3112 funcdisp = dseg_add_functionptr(cd, f);
3114 #if !defined(WITH_STATIC_CLASSPATH)
3116 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3120 /* save float argument registers */
3122 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3124 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3125 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3126 s1 = WINSAVE_CNT + nmd->memuse + j;
3127 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3128 fltregarg_offset[i] = s1; /* remember stack offset */
3133 /* prepare data structures for native function call */
3135 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3136 M_MOV(REG_PV_CALLEE, REG_OUT1);
3137 M_MOV(REG_FP, REG_OUT2); /* java sp */
3138 M_MOV(REG_RA_CALLEE, REG_OUT3);
3139 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3140 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3141 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3142 M_NOP; /* XXX fill me! */
3144 /* keep float arguments on stack */
3146 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3147 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3148 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3154 /* copy or spill arguments to new locations */
3156 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3157 t = md->paramtypes[i].type;
3159 if (IS_INT_LNG_TYPE(t)) {
3161 /* integral types */
3163 if (!md->params[i].inmemory) {
3164 s1 = md->params[i].regoff;
3165 /* s1 refers to the old window, transpose */
3166 s1 = REG_WINDOW_TRANSPOSE(s1);
3168 if (!nmd->params[j].inmemory) {
3169 s2 = nmd->params[j].regoff;
3172 /* nmd's regoff is relative to the start of the param array */
3173 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3174 M_AST(s1, REG_SP, s2);
3178 if (!nmd->params[j].inmemory) {
3179 /* JIT stack arg -> NAT reg arg */
3181 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3182 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3184 assert(false); /* path never taken */
3187 s1 = md->params[i].regoff + cd->stackframesize * 8;
3188 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3189 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3190 M_AST(REG_ITMP1, REG_SP, s2);
3195 /* floating point types */
3197 if (!md->params[i].inmemory) {
3198 s1 = md->params[i].regoff;
3200 if (!nmd->params[j].inmemory) {
3202 /* no mapping to regs needed, native flt args use regoff */
3203 s2 = nmd->params[j].regoff;
3205 /* JIT float regs are still on the stack */
3206 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3209 /* not supposed to happen with 16 NAT flt args */
3212 s2 = nmd->params[j].regoff;
3213 if (IS_2_WORD_TYPE(t))
3214 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3216 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3222 s1 = md->params[i].regoff;
3224 if (!nmd->params[j].inmemory) {
3226 /* JIT stack -> NAT reg */
3228 s2 = nmd->params[j].regoff;
3229 M_DLD(s2, REG_FP, JITSTACK + s1);
3233 /* JIT stack -> NAT stack */
3235 s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3237 /* The FTMP register may already be loaded with args */
3238 /* we know $f0 is unused because of the env pointer */
3239 M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3240 M_DST(REG_F0, REG_SP, BIAS + s2);
3247 /* put class into second argument register */
3249 if (m->flags & ACC_STATIC) {
3250 disp = dseg_add_address(cd, m->class);
3251 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3254 /* put env into first argument register */
3256 disp = dseg_add_address(cd, _Jv_env);
3257 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3259 /* do the native function call */
3261 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3262 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3263 M_NOP; /* delay slot */
3265 /* save return value */
3267 if (md->returntype.type != TYPE_VOID) {
3268 if (IS_INT_LNG_TYPE(md->returntype.type))
3269 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3271 M_DST(REG_FRESULT, REG_SP, CSTACK);
3274 /* Note: native functions return float values in %f0 (see ABI) */
3275 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3277 #if !defined(NDEBUG)
3278 /* But for the trace function we need to put a flt result into %f1 */
3279 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3280 if (!IS_2_WORD_TYPE(md->returntype.type))
3281 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3282 emit_verbosecall_exit(jd);
3286 /* remove native stackframe info */
3288 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3289 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3290 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3291 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3292 M_NOP; /* XXX fill me! */
3293 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3295 /* restore float return value, int return value already in our return reg */
3297 if (md->returntype.type != TYPE_VOID) {
3298 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3299 if (IS_2_WORD_TYPE(md->returntype.type))
3300 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3302 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3306 /* check for exception */
3307 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3310 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3313 /* handle exception */
3315 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3316 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3317 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3318 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3319 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3321 /* generate patcher stubs */
3323 emit_patcher_stubs(jd);
3327 * These are local overrides for various environment variables in Emacs.
3328 * Please do not remove this and leave it at the end of the file, where
3329 * Emacs will automagically detect them.
3330 * ---------------------------------------------------------------------
3333 * indent-tabs-mode: t
3337 * vim:noexpandtab:sw=4:ts=4: