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 = (code_is_leafmethod(code)) ? 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 && code_is_synchronized(code))
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 /* IsSync contains the offset relative to the stack pointer for the
193 argument of monitor_exit used in the exception handler. Since the
194 offset could be zero and give a wrong meaning of the flag it is
197 /* XXX Remove this "offset by one". */
199 code->synchronizedoffset = JITSTACK + (rd->memuse + 1) * 8;
201 /* REMOVEME: We still need it for exception handling in assembler. */
203 if (code_is_leafmethod(code))
204 (void) dseg_add_unique_s4(cd, 1);
206 (void) dseg_add_unique_s4(cd, 0);
208 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
209 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
210 dseg_addlinenumbertablesize(cd);
211 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
213 /* create exception table */
215 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
216 dseg_add_target(cd, ex->start);
217 dseg_add_target(cd, ex->end);
218 dseg_add_target(cd, ex->handler);
219 (void) dseg_add_unique_address(cd, ex->catchtype.any);
222 /* save register window and create stack frame (if necessary) */
224 if (cd->stackframesize) {
225 if (cd->stackframesize <= 4095)
226 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
228 M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
229 M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
230 M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
234 /* save callee saved float registers (none right now) */
236 p = cd->stackframesize;
237 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
238 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
243 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
244 emit_verbosecall_enter(jd);
248 /* call monitorenter function */
249 #if defined(ENABLE_THREADS)
250 if (checksync && code_is_synchronized(code)) {
251 /* stack offset for monitor argument */
255 /* save float argument registers */
259 ALIGN_STACK_SLOTS(slots);
261 M_LDA(REG_SP, REG_SP, -(slots * 8));
262 for (i = 0; i < FLT_ARG_CNT; i++)
263 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
267 /* get correct lock object */
269 if (m->flags & ACC_STATIC) {
270 disp = dseg_add_address(cd, &m->class->object.header);
271 M_ALD(REG_OUT0, REG_PV, disp);
272 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
273 M_ALD(REG_ITMP3, REG_PV, disp);
276 /* copy class pointer: $i0 -> $o0 */
277 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
279 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
280 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
281 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
284 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
285 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
287 /* restore float argument registers */
289 for (i = 0; i < FLT_ARG_CNT; i++)
290 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
292 M_LDA(REG_SP, REG_SP, slots * 8);
297 /* take arguments out of register or stack frame */
301 for (p = 0, l = 0; p < md->paramcount; p++) {
302 t = md->paramtypes[p].type;
304 varindex = jd->local_map[l * 5 + t];
307 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
310 if (varindex == UNUSED)
314 s1 = md->params[p].regoff;
316 if (IS_INT_LNG_TYPE(t)) { /* integer args */
320 if (!md->params[p].inmemory) { /* register arguments */
321 s1 = REG_WINDOW_TRANSPOSE(s1);
323 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
325 /* the register allocator does not know about the window. */
326 /* avoid copying the locals from save to save regs by */
327 /* swapping variables. */
330 int old_dest = var->vv.regoff;
331 int new_dest = p + 24;
333 /* run through all variables */
335 for (i = 0; i < jd->varcount; i++) {
336 varinfo* uvar = VAR(i);
338 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
341 s2 = uvar->vv.regoff;
343 /* free the in reg by moving all other references */
345 if (s2 == new_dest) {
346 uvar->vv.regoff = old_dest;
347 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
350 /* move all variables to the in reg */
352 if (s2 == old_dest) {
353 uvar->vv.regoff = new_dest;
354 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
362 else { /* reg arg -> spilled */
363 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
366 } else { /* stack arguments */
367 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
368 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
370 } else { /* stack arg -> spilled */
371 /* add the callers window save registers */
372 var->vv.regoff = cd->stackframesize * 8 + s1;
376 } else { /* floating args */
377 if (!md->params[p].inmemory) { /* register arguments */
378 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
379 M_FLTMOVE(s1, var->vv.regoff);
381 } else { /* reg arg -> spilled */
382 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
385 } else { /* stack arguments */
386 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
387 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
389 } else { /* stack-arg -> spilled */
390 var->vv.regoff = cd->stackframesize * 8 + s1;
399 /* end of header generation */
401 /* create replacement points */
403 REPLACEMENT_POINTS_INIT(cd, jd);
405 /* walk through all basic blocks */
407 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
409 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
411 if (bptr->flags >= BBREACHED) {
413 /* branch resolving */
415 codegen_resolve_branchrefs(cd, bptr);
417 /* handle replacement points */
419 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
422 /* copy interface registers to their destination */
427 #if defined(ENABLE_LSRA)
428 #error XXX LSRA not tested yet
432 src = bptr->invars[len];
433 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
434 /* d = reg_of_var(m, src, REG_ITMP1); */
435 if (!(src->flags & INMEMORY))
439 M_INTMOVE(REG_ITMP1, d);
440 emit_store(jd, NULL, src, d);
447 var = VAR(bptr->invars[len]);
448 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
449 d = codegen_reg_of_var(0, var, REG_ITMP1);
450 M_INTMOVE(REG_ITMP2_XPTR, d);
451 emit_store(jd, NULL, var, d);
454 assert((var->flags & INOUT));
457 #if defined(ENABLE_LSRA)
460 /* walk through all instructions */
464 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
465 if (iptr->line != currentline) {
466 dseg_addlinenumber(cd, iptr->line);
467 currentline = iptr->line;
470 MCODECHECK(64); /* an instruction usually needs < 64 words */
474 case ICMD_INLINE_START:
475 case ICMD_INLINE_END:
478 case ICMD_NOP: /* ... ==> ... */
481 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
484 emit_nullpointer_check(cd, iptr, s1);
487 /* constant operations ************************************************/
489 case ICMD_ICONST: /* ... ==> ..., constant */
491 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
492 ICONST(d, iptr->sx.val.i);
493 emit_store_dst(jd, iptr, d);
496 case ICMD_LCONST: /* ... ==> ..., constant */
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
499 LCONST(d, iptr->sx.val.l);
500 emit_store_dst(jd, iptr, d);
503 case ICMD_FCONST: /* ... ==> ..., constant */
505 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
506 disp = dseg_add_float(cd, iptr->sx.val.f);
507 M_FLD(d, REG_PV, disp);
508 emit_store_dst(jd, iptr, d);
511 case ICMD_DCONST: /* ... ==> ..., constant */
513 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
514 disp = dseg_add_double(cd, iptr->sx.val.d);
515 M_DLD(d, REG_PV, disp);
516 emit_store_dst(jd, iptr, d);
519 case ICMD_ACONST: /* ... ==> ..., constant */
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
523 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
524 cr = iptr->sx.val.c.ref;
525 disp = dseg_add_unique_address(cd, cr);
527 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
529 M_ALD(d, REG_PV, disp);
533 if (iptr->sx.val.anyptr == NULL) {
534 M_INTMOVE(REG_ZERO, d);
537 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
538 M_ALD(d, REG_PV, disp);
541 emit_store_dst(jd, iptr, d);
545 /* load/store/copy/move operations ************************************/
547 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
552 case ICMD_ISTORE: /* ..., value ==> ... */
563 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
568 /* pop/dup/swap operations ********************************************/
570 /* attention: double and longs are only one entry in CACAO ICMDs */
572 case ICMD_POP: /* ..., value ==> ... */
573 case ICMD_POP2: /* ..., value, value ==> ... */
577 /* integer operations *************************************************/
579 case ICMD_INEG: /* ..., value ==> ..., - value */
582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
584 M_SUB(REG_ZERO, s1, d);
585 emit_store_dst(jd, iptr, d);
588 case ICMD_I2L: /* ..., value ==> ..., value */
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_L2I: /* ..., value ==> ..., value */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
600 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
601 emit_store_dst(jd, iptr, d);
604 case ICMD_INT2BYTE: /* ..., 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, 56, d);
609 M_SRAX_IMM( d, 56, d);
610 emit_store_dst(jd, iptr, d);
613 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
617 M_SLLX_IMM(s1, 48, d);
618 M_SRLX_IMM( d, 48, d);
619 emit_store_dst(jd, iptr, d);
622 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626 M_SLLX_IMM(s1, 48, d);
627 M_SRAX_IMM( d, 48, d);
628 emit_store_dst(jd, iptr, d);
631 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 emit_store_dst(jd, iptr, d);
642 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
643 /* sx.val.i = constant */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
647 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
648 M_ADD_IMM(s1, iptr->sx.val.i, d);
650 ICONST(REG_ITMP2, iptr->sx.val.i);
651 M_ADD(s1, REG_ITMP2, d);
653 emit_store_dst(jd, iptr, d);
656 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
657 /* sx.val.l = constant */
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
662 M_ADD_IMM(s1, iptr->sx.val.l, d);
664 LCONST(REG_ITMP2, iptr->sx.val.l);
665 M_ADD(s1, REG_ITMP2, d);
667 emit_store_dst(jd, iptr, d);
670 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 emit_store_dst(jd, iptr, d);
680 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
681 /* sx.val.i = constant */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
686 M_SUB_IMM(s1, iptr->sx.val.i, d);
688 ICONST(REG_ITMP2, iptr->sx.val.i);
689 M_SUB(s1, REG_ITMP2, d);
691 emit_store_dst(jd, iptr, d);
694 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
695 /* sx.val.l = constant */
697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
699 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
700 M_SUB_IMM(s1, iptr->sx.val.l, d);
702 LCONST(REG_ITMP2, iptr->sx.val.l);
703 M_SUB(s1, REG_ITMP2, d);
705 emit_store_dst(jd, iptr, d);
708 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
715 emit_store_dst(jd, iptr, d);
718 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
719 /* sx.val.i = constant */
721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
722 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
723 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
724 M_MULX_IMM(s1, iptr->sx.val.i, d);
726 ICONST(REG_ITMP2, iptr->sx.val.i);
727 M_MULX(s1, REG_ITMP2, d);
729 emit_store_dst(jd, iptr, d);
732 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
733 /* sx.val.l = constant */
735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
737 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
738 M_MULX_IMM(s1, iptr->sx.val.l, d);
740 LCONST(REG_ITMP2, iptr->sx.val.l);
741 M_MULX(s1, REG_ITMP2, d);
743 emit_store_dst(jd, iptr, d);
746 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
747 /* XXX could also clear Y and use 32bit div */
748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
751 emit_arithmetic_check(cd, iptr, s2);
753 /* XXX trim s2 like s1 ? */
755 emit_store_dst(jd, iptr, d);
758 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
761 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
763 emit_arithmetic_check(cd, iptr, s2);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
773 emit_arithmetic_check(cd, iptr, s2);
775 /* XXX trim s2 like s1 ? */
776 M_DIVX(s1, s2, REG_ITMP3);
777 M_MULX(s2, REG_ITMP3, REG_ITMP3);
778 M_SUB(s1, REG_ITMP3, d);
779 emit_store_dst(jd, iptr, d);
782 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
786 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
787 emit_arithmetic_check(cd, iptr, s2);
788 M_DIVX(s1, s2, REG_ITMP3);
789 M_MULX(s2, REG_ITMP3, REG_ITMP3);
790 M_SUB(s1, REG_ITMP3, d);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
795 case ICMD_LDIVPOW2: /* val.i = constant */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
799 M_SRAX_IMM(s1, 63, REG_ITMP2);
800 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
801 M_ADD(s1, REG_ITMP2, REG_ITMP2);
802 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
803 emit_store_dst(jd, iptr, d);
806 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
825 /* val.i = constant */
827 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829 M_SLL_IMM(s1, iptr->sx.val.i, d);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
834 /* val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
838 M_SLLX_IMM(s1, iptr->sx.val.i, d);
839 emit_store_dst(jd, iptr, d);
842 case ICMD_ISHR: /* ..., 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_ISHRCONST: /* ..., 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_SRA_IMM(s1, iptr->sx.val.i, d);
857 emit_store_dst(jd, iptr, d);
860 case ICMD_IUSHR: /* ..., 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_IUSHRCONST: /* ..., 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_SRL_IMM(s1, iptr->sx.val.i, d);
875 emit_store_dst(jd, iptr, d);
878 case ICMD_LSHR: /* ..., 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_LSHRCONST: /* ..., 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_SRAX_IMM(s1, iptr->sx.val.i, d);
893 emit_store_dst(jd, iptr, d);
896 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
902 emit_store_dst(jd, iptr, d);
905 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
906 /* sx.val.i = constant */
908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
910 M_SRLX_IMM(s1, iptr->sx.val.i, d);
911 emit_store_dst(jd, iptr, d);
914 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
921 emit_store_dst(jd, iptr, d);
924 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
925 /* sx.val.i = constant */
927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
928 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
929 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
930 M_AND_IMM(s1, iptr->sx.val.i, d);
932 ICONST(REG_ITMP2, iptr->sx.val.i);
933 M_AND(s1, REG_ITMP2, d);
935 emit_store_dst(jd, iptr, d);
938 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
939 /* sx.val.i = constant */
940 /* constant is actually constant - 1 */
942 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
943 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
945 M_MOV(s1, REG_ITMP1);
948 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
949 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
950 M_AND_IMM(s1, iptr->sx.val.i, d);
953 M_SUB(REG_ZERO, s1, d);
954 M_AND_IMM(d, iptr->sx.val.i, d);
956 ICONST(REG_ITMP2, iptr->sx.val.i);
957 M_AND(s1, REG_ITMP2, d);
960 M_SUB(REG_ZERO, s1, d);
961 M_AND(d, REG_ITMP2, d);
963 M_SUB(REG_ZERO, d, d);
964 emit_store_dst(jd, iptr, d);
967 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
968 /* sx.val.l = constant */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
972 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
973 M_AND_IMM(s1, iptr->sx.val.l, d);
975 LCONST(REG_ITMP2, iptr->sx.val.l);
976 M_AND(s1, REG_ITMP2, d);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
982 /* sx.val.l = constant */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987 M_MOV(s1, REG_ITMP1);
990 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
991 M_AND_IMM(s1, iptr->sx.val.l, d);
994 M_SUB(REG_ZERO, s1, d);
995 M_AND_IMM(d, iptr->sx.val.l, d);
997 LCONST(REG_ITMP2, iptr->sx.val.l);
998 M_AND(s1, REG_ITMP2, d);
1001 M_SUB(REG_ZERO, s1, d);
1002 M_AND(d, REG_ITMP2, d);
1004 M_SUB(REG_ZERO, d, d);
1005 emit_store_dst(jd, iptr, d);
1008 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1012 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1013 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1015 emit_store_dst(jd, iptr, d);
1018 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1019 /* sx.val.i = constant */
1021 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1022 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1023 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1024 M_OR_IMM(s1, iptr->sx.val.i, d);
1026 ICONST(REG_ITMP2, iptr->sx.val.i);
1027 M_OR(s1, REG_ITMP2, d);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1033 /* sx.val.l = constant */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1037 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1038 M_OR_IMM(s1, iptr->sx.val.l, d);
1040 LCONST(REG_ITMP2, iptr->sx.val.l);
1041 M_OR(s1, REG_ITMP2, d);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1053 emit_store_dst(jd, iptr, d);
1056 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1057 /* sx.val.i = constant */
1059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1061 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1062 M_XOR_IMM(s1, iptr->sx.val.i, d);
1064 ICONST(REG_ITMP2, iptr->sx.val.i);
1065 M_XOR(s1, REG_ITMP2, d);
1067 emit_store_dst(jd, iptr, d);
1070 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1071 /* sx.val.l = constant */
1073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1075 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1076 M_XOR_IMM(s1, iptr->sx.val.l, d);
1078 LCONST(REG_ITMP2, iptr->sx.val.l);
1079 M_XOR(s1, REG_ITMP2, d);
1081 emit_store_dst(jd, iptr, d);
1085 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1092 M_XCMOVLT_IMM(-1, d);
1093 M_XCMOVGT_IMM(1, d);
1094 emit_store_dst(jd, iptr, d);
1098 /* floating operations ************************************************/
1100 case ICMD_FNEG: /* ..., value ==> ..., - value */
1102 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1103 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_DNEG: /* ..., value ==> ..., - value */
1110 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_FADD: /* ..., 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_DADD: /* ..., 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_FSUB: /* ..., 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_DSUB: /* ..., 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_FMUL: /* ..., 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_DMUL: /* ..., 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);
1170 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1172 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1173 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1174 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1176 emit_store_dst(jd, iptr, d);
1179 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1181 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1182 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1183 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1185 emit_store_dst(jd, iptr, d);
1189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1190 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1191 disp = dseg_add_unique_float(cd, 0.0);
1192 M_IST (s1, REG_PV_CALLEE, disp);
1193 M_FLD (d, REG_PV_CALLEE, disp);
1194 M_CVTIF (d, d); /* rd gets translated to double target register */
1195 emit_store_dst(jd, iptr, d);
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1201 disp = dseg_add_unique_float(cd, 0.0);
1202 M_IST(s1, REG_PV_CALLEE, disp);
1203 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1204 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1205 emit_store_dst(jd, iptr, d);
1209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1210 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1211 disp = dseg_add_unique_double(cd, 0.0);
1212 M_STX(s1, REG_PV_CALLEE, disp);
1213 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1214 M_CVTLF(REG_FTMP3, d);
1215 emit_store_dst(jd, iptr, d);
1219 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1221 disp = dseg_add_unique_double(cd, 0.0);
1222 M_STX(s1, REG_PV_CALLEE, disp);
1223 M_DLD(d, REG_PV_CALLEE, disp);
1225 emit_store_dst(jd, iptr, d);
1228 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1229 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1231 disp = dseg_add_unique_float(cd, 0.0);
1233 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1236 M_MOV(REG_ZERO, d); /* delay slot */
1238 M_CVTFI(s1, REG_FTMP2);
1239 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1240 M_ILD(d, REG_PV, disp);
1241 emit_store_dst(jd, iptr, d);
1245 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1246 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1248 disp = dseg_add_unique_float(cd, 0.0);
1250 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1253 M_MOV(REG_ZERO, d); /* delay slot */
1255 M_CVTDI(s1, REG_FTMP2);
1256 M_FST(REG_FTMP2, REG_PV, disp);
1257 M_ILD(d, REG_PV, disp);
1258 emit_store_dst(jd, iptr, d);
1261 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1262 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1263 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1264 disp = dseg_add_unique_double(cd, 0.0);
1266 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1269 M_MOV(REG_ZERO, d); /* delay slot */
1271 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1272 M_DST(REG_FTMP2, REG_PV, disp);
1273 M_LDX(d, REG_PV, disp);
1274 emit_store_dst(jd, iptr, d);
1277 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1278 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1279 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1280 disp = dseg_add_unique_double(cd, 0.0);
1282 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1285 M_MOV(REG_ZERO, d); /* delay slot */
1287 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1288 M_DST(REG_FTMP2, REG_PV, disp);
1289 M_LDX(d, REG_PV, disp);
1290 emit_store_dst(jd, iptr, d);
1293 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1295 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1296 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1303 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1304 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1306 emit_store_dst(jd, iptr, d);
1309 /* XXX merge F/D versions? only compare instr. is different */
1310 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1312 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1313 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1314 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1316 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1317 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1318 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1319 emit_store_dst(jd, iptr, d);
1322 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1324 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1325 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1326 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1328 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1329 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1330 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1331 emit_store_dst(jd, iptr, d);
1334 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1336 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1337 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1338 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1340 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1341 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1342 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1343 emit_store_dst(jd, iptr, d);
1346 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1348 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1349 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1352 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1353 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1354 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1355 emit_store_dst(jd, iptr, d);
1359 /* memory operations **************************************************/
1361 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1365 emit_nullpointer_check(cd, iptr, s1);
1366 M_ILD(d, s1, OFFSET(java_array_t, size));
1367 emit_store_dst(jd, iptr, d);
1370 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1372 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1373 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1375 /* implicit null-pointer check */
1376 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1377 M_AADD(s2, s1, REG_ITMP3);
1378 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1385 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1387 /* implicit null-pointer check */
1388 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1389 M_AADD(s2, s1, REG_ITMP3);
1390 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1391 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1392 emit_store_dst(jd, iptr, d);
1395 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1397 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1398 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1400 /* implicit null-pointer check */
1401 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1402 M_AADD(s2, s1, REG_ITMP3);
1403 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1404 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1405 emit_store_dst(jd, iptr, d);
1408 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1411 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1412 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1413 /* implicit null-pointer check */
1414 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1415 M_ASLL_IMM(s2, 2, REG_ITMP3);
1416 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1417 M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1418 emit_store_dst(jd, iptr, d);
1421 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1423 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1424 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1426 /* implicit null-pointer check */
1427 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1428 M_ASLL_IMM(s2, 3, REG_ITMP3);
1429 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1430 M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1431 emit_store_dst(jd, iptr, d);
1434 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1437 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1438 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1439 /* implicit null-pointer check */
1440 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1441 M_ASLL_IMM(s2, 2, REG_ITMP3);
1442 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1443 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1444 emit_store_dst(jd, iptr, d);
1447 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1451 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1452 /* implicit null-pointer check */
1453 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1454 M_ASLL_IMM(s2, 3, REG_ITMP3);
1455 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1456 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1465 /* implicit null-pointer check */
1466 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1467 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1468 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1469 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1470 emit_store_dst(jd, iptr, d);
1474 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1476 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1478 /* implicit null-pointer check */
1479 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1480 M_AADD(s2, s1, REG_ITMP1);
1481 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1482 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1485 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1486 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1489 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1490 /* implicit null-pointer check */
1491 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1492 M_AADD(s2, s1, REG_ITMP1);
1493 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1494 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1495 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1498 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1501 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1502 /* implicit null-pointer check */
1503 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1504 M_ASLL_IMM(s2, 2, REG_ITMP2);
1505 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1506 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1507 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1510 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1513 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1514 /* implicit null-pointer check */
1515 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1516 M_ASLL_IMM(s2, 3, REG_ITMP2);
1517 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1518 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1519 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1522 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1525 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1526 /* implicit null-pointer check */
1527 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1528 M_ASLL_IMM(s2, 2, REG_ITMP2);
1529 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1530 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1531 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1534 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1537 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1538 /* implicit null-pointer check */
1539 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1540 M_ASLL_IMM(s2, 3, REG_ITMP2);
1541 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1542 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1543 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1547 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1550 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1551 /* implicit null-pointer check */
1552 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1553 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1555 M_MOV(s1, REG_OUT0);
1556 M_MOV(s3, REG_OUT1);
1557 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1558 M_ALD(REG_ITMP3, REG_PV, disp);
1559 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1561 emit_arraystore_check(cd, iptr);
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1565 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1566 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1567 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1568 /* implicit null-pointer check */
1569 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1573 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577 /* implicit null-pointer check */
1578 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1579 M_AADD(s2, s1, REG_ITMP1);
1580 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1583 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1584 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1587 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1588 /* implicit null-pointer check */
1589 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1590 M_AADD(s2, s1, REG_ITMP1);
1591 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1592 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1595 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1597 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1598 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1599 /* implicit null-pointer check */
1600 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1601 M_ASLL_IMM(s2, 2, REG_ITMP2);
1602 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1603 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1606 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1609 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1610 /* implicit null-pointer check */
1611 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1612 M_ASLL_IMM(s2, 3, REG_ITMP2);
1613 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1614 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1617 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621 /* implicit null-pointer check */
1622 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1623 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1624 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1625 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1629 case ICMD_GETSTATIC: /* ... ==> ..., value */
1631 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1632 uf = iptr->sx.s23.s3.uf;
1633 fieldtype = uf->fieldref->parseddesc.fd->type;
1634 disp = dseg_add_unique_address(cd, uf);
1636 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1639 fi = iptr->sx.s23.s3.fmiref->p.field;
1640 fieldtype = fi->type;
1641 disp = dseg_add_address(cd, fi->value);
1643 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1644 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1647 M_ALD(REG_ITMP1, REG_PV, disp);
1649 switch (fieldtype) {
1651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1652 M_ILD_INTERN(d, REG_ITMP1, 0);
1655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1656 M_LDX_INTERN(d, REG_ITMP1, 0);
1659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1660 M_ALD_INTERN(d, REG_ITMP1, 0);
1663 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1664 M_FLD_INTERN(d, REG_ITMP1, 0);
1667 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1668 M_DLD_INTERN(d, REG_ITMP1, 0);
1671 emit_store_dst(jd, iptr, d);
1674 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1676 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1677 uf = iptr->sx.s23.s3.uf;
1678 fieldtype = uf->fieldref->parseddesc.fd->type;
1679 disp = dseg_add_unique_address(cd, uf);
1681 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1684 fi = iptr->sx.s23.s3.fmiref->p.field;
1685 fieldtype = fi->type;
1686 disp = dseg_add_address(cd, fi->value);
1688 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1689 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1692 M_ALD(REG_ITMP1, REG_PV, disp);
1694 switch (fieldtype) {
1696 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1697 M_IST_INTERN(s1, REG_ITMP1, 0);
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1701 M_STX_INTERN(s1, REG_ITMP1, 0);
1704 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1705 M_AST_INTERN(s1, REG_ITMP1, 0);
1708 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1709 M_FST_INTERN(s1, REG_ITMP1, 0);
1712 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1713 M_DST_INTERN(s1, REG_ITMP1, 0);
1718 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1719 /* val = value (in current instruction) */
1720 /* following NOP) */
1722 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1723 uf = iptr->sx.s23.s3.uf;
1724 fieldtype = uf->fieldref->parseddesc.fd->type;
1725 disp = dseg_add_unique_address(cd, uf);
1727 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1730 fi = iptr->sx.s23.s3.fmiref->p.field;
1731 fieldtype = fi->type;
1732 disp = dseg_add_address(cd, fi->value);
1734 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1735 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1738 M_ALD(REG_ITMP1, REG_PV, disp);
1740 switch (fieldtype) {
1742 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1745 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1748 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1751 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1754 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1760 case ICMD_GETFIELD: /* ... ==> ..., value */
1762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1763 emit_nullpointer_check(cd, iptr, s1);
1765 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1766 uf = iptr->sx.s23.s3.uf;
1768 fieldtype = uf->fieldref->parseddesc.fd->type;
1771 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1774 fi = iptr->sx.s23.s3.fmiref->p.field;
1775 fieldtype = fi->type;
1779 switch (fieldtype) {
1781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1793 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1797 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1804 emit_store_dst(jd, iptr, d);
1807 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1810 emit_nullpointer_check(cd, iptr, s1);
1812 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1813 uf = iptr->sx.s23.s3.uf;
1814 fieldtype = uf->fieldref->parseddesc.fd->type;
1819 fi = iptr->sx.s23.s3.fmiref->p.field;
1820 fieldtype = fi->type;
1824 if (IS_INT_LNG_TYPE(fieldtype))
1825 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1827 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1829 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1830 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1832 switch (fieldtype) {
1834 M_IST(s2, s1, disp);
1837 M_STX(s2, s1, disp);
1840 M_AST(s2, s1, disp);
1843 M_FST(s2, s1, disp);
1846 M_DST(s2, s1, disp);
1854 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1855 /* val = value (in current instruction) */
1856 /* following NOP) */
1858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1859 emit_nullpointer_check(cd, iptr, s1);
1861 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1862 unresolved_field *uf = iptr->sx.s23.s3.uf;
1864 fieldtype = uf->fieldref->parseddesc.fd->type;
1866 codegen_addpatchref(cd, PATCHER_get_putfield,
1869 if (opt_showdisassemble) {
1877 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1879 fieldtype = fi->type;
1885 switch (fieldtype) {
1887 M_IST(REG_ZERO, s1, disp);
1890 M_STX(REG_ZERO, s1, disp);
1893 M_AST(REG_ZERO, s1, disp);
1896 M_FST(REG_ZERO, s1, disp);
1899 M_DST(REG_ZERO, s1, disp);
1905 /* branch operations **************************************************/
1907 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1910 M_INTMOVE(s1, REG_ITMP2_XPTR);
1912 #ifdef ENABLE_VERIFIER
1913 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1914 unresolved_class *uc = iptr->sx.s23.s2.uc;
1916 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1918 #endif /* ENABLE_VERIFIER */
1920 disp = dseg_add_functionptr(cd, asm_handle_exception);
1921 M_ALD(REG_ITMP1, REG_PV, disp);
1922 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1924 M_NOP; /* nop ensures that XPC is less than the end */
1925 /* of basic block */
1929 case ICMD_GOTO: /* ... ==> ... */
1930 case ICMD_RET: /* ... ==> ... */
1932 emit_br(cd, iptr->dst.block);
1936 case ICMD_JSR: /* ... ==> ... */
1938 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1942 case ICMD_IFNULL: /* ..., value ==> ... */
1943 case ICMD_IFNONNULL:
1945 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1946 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1949 /* Note: int compares must not branch on the register directly. */
1950 /* Reason is, that register content is not 32-bit clean. */
1952 case ICMD_IFEQ: /* ..., value ==> ... */
1954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1956 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1957 M_CMP_IMM(s1, iptr->sx.val.i);
1960 ICONST(REG_ITMP2, iptr->sx.val.i);
1961 M_CMP(s1, REG_ITMP2);
1963 emit_beq(cd, iptr->dst.block);
1966 case ICMD_IFLT: /* ..., value ==> ... */
1968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1970 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1971 M_CMP_IMM(s1, iptr->sx.val.i);
1974 ICONST(REG_ITMP2, iptr->sx.val.i);
1975 M_CMP(s1, REG_ITMP2);
1977 emit_blt(cd, iptr->dst.block);
1980 case ICMD_IFLE: /* ..., value ==> ... */
1982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1984 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1985 M_CMP_IMM(s1, iptr->sx.val.i);
1988 ICONST(REG_ITMP2, iptr->sx.val.i);
1989 M_CMP(s1, REG_ITMP2);
1991 emit_ble(cd, iptr->dst.block);
1994 case ICMD_IFNE: /* ..., value ==> ... */
1996 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1999 M_CMP_IMM(s1, iptr->sx.val.i);
2002 ICONST(REG_ITMP2, iptr->sx.val.i);
2003 M_CMP(s1, REG_ITMP2);
2005 emit_bne(cd, iptr->dst.block);
2008 case ICMD_IFGT: /* ..., value ==> ... */
2010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2012 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2013 M_CMP_IMM(s1, iptr->sx.val.i);
2016 ICONST(REG_ITMP2, iptr->sx.val.i);
2017 M_CMP(s1, REG_ITMP2);
2019 emit_bgt(cd, iptr->dst.block);
2022 case ICMD_IFGE: /* ..., value ==> ... */
2024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2026 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2027 M_CMP_IMM(s1, iptr->sx.val.i);
2030 ICONST(REG_ITMP2, iptr->sx.val.i);
2031 M_CMP(s1, REG_ITMP2);
2033 emit_bge(cd, iptr->dst.block);
2036 case ICMD_IF_LEQ: /* ..., value ==> ... */
2038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2039 if (iptr->sx.val.l == 0)
2040 emit_beqz(cd, iptr->dst.block, s1);
2042 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2043 M_CMP_IMM(s1, iptr->sx.val.l);
2046 LCONST(REG_ITMP2, iptr->sx.val.l);
2047 M_CMP(s1, REG_ITMP2);
2049 emit_beq_xcc(cd, iptr->dst.block);
2053 case ICMD_IF_LLT: /* ..., value ==> ... */
2055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2056 if (iptr->sx.val.l == 0)
2057 emit_bltz(cd, iptr->dst.block, s1);
2059 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2060 M_CMP_IMM(s1, iptr->sx.val.l);
2063 LCONST(REG_ITMP2, iptr->sx.val.l);
2064 M_CMP(s1, REG_ITMP2);
2066 emit_blt_xcc(cd, iptr->dst.block);
2070 case ICMD_IF_LLE: /* ..., value ==> ... */
2072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2073 if (iptr->sx.val.l == 0)
2074 emit_blez(cd, iptr->dst.block, s1);
2076 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2077 M_CMP_IMM(s1, iptr->sx.val.l);
2080 LCONST(REG_ITMP2, iptr->sx.val.l);
2081 M_CMP(s1, REG_ITMP2);
2083 emit_ble_xcc(cd, iptr->dst.block);
2087 case ICMD_IF_LNE: /* ..., value ==> ... */
2089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2090 if (iptr->sx.val.l == 0)
2091 emit_bnez(cd, iptr->dst.block, s1);
2093 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2094 M_CMP_IMM(s1, iptr->sx.val.l);
2097 LCONST(REG_ITMP2, iptr->sx.val.l);
2098 M_CMP(s1, REG_ITMP2);
2100 emit_bne_xcc(cd, iptr->dst.block);
2104 case ICMD_IF_LGT: /* ..., value ==> ... */
2106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2107 if (iptr->sx.val.l == 0)
2108 emit_bgtz(cd, iptr->dst.block, s1);
2110 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2111 M_CMP_IMM(s1, iptr->sx.val.l);
2114 LCONST(REG_ITMP2, iptr->sx.val.l);
2115 M_CMP(s1, REG_ITMP2);
2117 emit_bgt_xcc(cd, iptr->dst.block);
2121 case ICMD_IF_LGE: /* ..., value ==> ... */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 if (iptr->sx.val.l == 0)
2125 emit_bgez(cd, iptr->dst.block, s1);
2127 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2128 M_CMP_IMM(s1, iptr->sx.val.l);
2131 LCONST(REG_ITMP2, iptr->sx.val.l);
2132 M_CMP(s1, REG_ITMP2);
2134 emit_bge_xcc(cd, iptr->dst.block);
2139 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2140 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2143 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2145 emit_beq_xcc(cd, iptr->dst.block);
2148 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2153 emit_beq(cd, iptr->dst.block);
2156 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2157 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2160 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2162 emit_bne_xcc(cd, iptr->dst.block);
2165 case ICMD_IF_ICMPNE: /* 32-bit compare */
2167 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2168 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2170 emit_bne(cd, iptr->dst.block);
2173 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2176 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2178 emit_blt_xcc(cd, iptr->dst.block);
2181 case ICMD_IF_ICMPLT: /* 32-bit compare */
2183 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2184 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2186 emit_blt(cd, iptr->dst.block);
2189 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2191 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2192 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2194 emit_bgt_xcc(cd, iptr->dst.block);
2197 case ICMD_IF_ICMPGT: /* 32-bit compare */
2199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2200 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2202 emit_bgt(cd, iptr->dst.block);
2205 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2207 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2208 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2210 emit_ble_xcc(cd, iptr->dst.block);
2213 case ICMD_IF_ICMPLE: /* 32-bit compare */
2215 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2216 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2218 emit_ble(cd, iptr->dst.block);
2222 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2225 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2227 emit_bge_xcc(cd, iptr->dst.block);
2230 case ICMD_IF_ICMPGE: /* 32-bit compare */
2232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2235 emit_bge(cd, iptr->dst.block);
2239 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2242 REPLACEMENT_POINT_RETURN(cd, iptr);
2244 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2245 M_INTMOVE(s1, REG_RESULT_CALLEE);
2246 goto nowperformreturn;
2248 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2250 REPLACEMENT_POINT_RETURN(cd, iptr);
2252 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2253 M_INTMOVE(s1, REG_RESULT_CALLEE);
2255 #ifdef ENABLE_VERIFIER
2256 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2257 unresolved_class *uc = iptr->sx.s23.s2.uc;
2259 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2261 #endif /* ENABLE_VERIFIER */
2262 goto nowperformreturn;
2264 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2267 REPLACEMENT_POINT_RETURN(cd, iptr);
2269 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2270 M_DBLMOVE(s1, REG_FRESULT);
2271 goto nowperformreturn;
2273 case ICMD_RETURN: /* ... ==> ... */
2275 REPLACEMENT_POINT_RETURN(cd, iptr);
2281 p = cd->stackframesize;
2283 #if !defined(NDEBUG)
2284 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2285 emit_verbosecall_exit(jd);
2288 #if defined(ENABLE_THREADS)
2289 if (checksync && code_is_synchronized(code)) {
2290 /* XXX jit-c-call */
2291 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2292 M_ALD(REG_ITMP3, REG_PV, disp);
2294 /* we need to save fp return value (int saved by window) */
2296 switch (iptr->opc) {
2299 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2300 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2301 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2303 /* restore the fp return value */
2305 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2311 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2312 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2323 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2329 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2332 branch_target_t *table;
2334 table = iptr->dst.table;
2336 l = iptr->sx.s23.s2.tablelow;
2337 i = iptr->sx.s23.s3.tablehigh;
2339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2341 M_INTMOVE(s1, REG_ITMP1);
2343 else if (-l >= 4096 && -l <= 4095) {
2344 M_ADD_IMM(s1, -l, REG_ITMP1);
2347 ICONST(REG_ITMP2, l);
2348 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2351 i = i - l + 1; /* number of targets (>0) */
2357 M_CMP_IMM(REG_ITMP1, i - 1);
2360 ICONST(REG_ITMP2, i - 1);
2361 M_CMP(REG_ITMP1, REG_ITMP2);
2363 emit_bugt(cd, table[0].block); /* default target */
2365 /* build jump table top down and use address of lowest entry */
2370 dseg_add_target(cd, table->block);
2375 /* length of dataseg after last dseg_addtarget is used by load */
2377 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2378 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2379 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2380 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2385 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2388 lookup_target_t *lookup;
2390 lookup = iptr->dst.lookup;
2392 i = iptr->sx.s23.s2.lookupcount;
2394 MCODECHECK((i<<2)+8);
2395 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2398 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2399 M_CMP_IMM(s1, lookup->value);
2401 ICONST(REG_ITMP2, lookup->value);
2402 M_CMP(s1, REG_ITMP2);
2404 emit_beq(cd, lookup->target.block);
2408 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2414 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2416 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2418 bte = iptr->sx.s23.s3.bte;
2421 /* XXX: builtin calling with stack arguments not implemented */
2422 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2424 s3 = md->paramcount;
2426 MCODECHECK((s3 << 1) + 64);
2428 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2430 /* copy float arguments according to ABI convention */
2432 int num_fltregargs = 0;
2433 int fltregarg_inswap[16];
2435 for (s3 = s3 - 1; s3 >= 0; s3--) {
2436 var = VAR(iptr->sx.s23.s2.args[s3]);
2438 if (IS_FLT_DBL_TYPE(var->type)) {
2439 if (!md->params[s3].inmemory) {
2440 s1 = s3; /*native flt args use argument index directly*/
2441 d = emit_load(jd, iptr, var, REG_FTMP1);
2444 fltregarg_inswap[num_fltregargs] = s1;
2446 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2455 /* move swapped float args to target regs */
2456 for (i = 0; i < num_fltregargs; i++) {
2457 s1 = fltregarg_inswap[i];
2458 M_DMOV(s1 + 16, s1);
2459 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2463 assert(md->argfltreguse == 0);
2468 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2469 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2470 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2471 case ICMD_INVOKEINTERFACE:
2473 REPLACEMENT_POINT_INVOKE(cd, iptr);
2475 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2477 um = iptr->sx.s23.s3.um;
2478 md = um->methodref->parseddesc.md;
2481 lm = iptr->sx.s23.s3.fmiref->p.method;
2483 md = lm->parseddesc;
2487 s3 = md->paramcount;
2489 MCODECHECK((s3 << 1) + 64);
2491 /* copy arguments to registers or stack location */
2493 for (s3 = s3 - 1; s3 >= 0; s3--) {
2494 var = VAR(iptr->sx.s23.s2.args[s3]);
2495 d = md->params[s3].regoff;
2497 if (var->flags & PREALLOC)
2500 if (IS_INT_LNG_TYPE(var->type)) {
2501 if (!md->params[s3].inmemory) {
2502 s1 = emit_load(jd, iptr, var, d);
2506 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2507 M_STX(s1, REG_SP, JITSTACK + d);
2511 #ifdef BUILTIN_FLOAT_ARGS
2512 if (iptr->opc == ICMD_BUILTIN)
2516 if (!md->params[s3].inmemory) {
2517 s1 = emit_load(jd, iptr, var, d);
2518 if (IS_2_WORD_TYPE(var->type))
2524 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2525 M_DST(s1, REG_SP, JITSTACK + d);
2530 switch (iptr->opc) {
2532 if (bte->stub == NULL) {
2533 disp = dseg_add_functionptr(cd, bte->fp);
2536 disp = dseg_add_functionptr(cd, bte->stub);
2539 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2541 /* XXX jit-c-call */
2542 /* generate the actual call */
2544 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2546 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2547 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2548 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2549 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2550 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2552 if (md->returntype.type == TYPE_FLT) {
2553 /* special handling for float return value in %f0 */
2558 case ICMD_INVOKESPECIAL:
2559 emit_nullpointer_check(cd, iptr, REG_OUT0);
2562 case ICMD_INVOKESTATIC:
2564 disp = dseg_add_unique_address(cd, NULL);
2566 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2570 disp = dseg_add_address(cd, lm->stubroutine);
2572 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2574 /* generate the actual call */
2576 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2578 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2579 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2580 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2581 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2584 case ICMD_INVOKEVIRTUAL:
2585 emit_nullpointer_check(cd, iptr, REG_OUT0);
2588 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2593 s1 = OFFSET(vftbl_t, table[0]) +
2594 sizeof(methodptr) * lm->vftblindex;
2596 /* implicit null-pointer check */
2597 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2598 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2600 /* generate the actual call */
2602 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2604 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2605 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2606 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2607 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2610 case ICMD_INVOKEINTERFACE:
2611 emit_nullpointer_check(cd, iptr, REG_OUT0);
2614 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2620 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2621 sizeof(methodptr*) * lm->class->index;
2623 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2626 /* implicit null-pointer check */
2627 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2628 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2629 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2631 /* generate the actual call */
2633 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2635 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2636 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2637 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2638 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2642 /* store return value */
2644 d = md->returntype.type;
2646 if (d != TYPE_VOID) {
2647 if (IS_INT_LNG_TYPE(d)) {
2648 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2649 M_INTMOVE(REG_RESULT_CALLER, s1);
2652 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2653 if (IS_2_WORD_TYPE(d)) {
2654 M_DBLMOVE(REG_FRESULT, s1);
2656 M_FLTMOVE(REG_FRESULT, s1);
2659 emit_store_dst(jd, iptr, s1);
2664 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2665 /* val.a: (classinfo*) superclass */
2667 /* superclass is an interface:
2669 * OK if ((sub == NULL) ||
2670 * (sub->vftbl->interfacetablelength > super->index) &&
2671 * (sub->vftbl->interfacetable[-super->index] != NULL));
2673 * superclass is a class:
2675 * OK if ((sub == NULL) || (0
2676 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2677 * super->vftbl->diffvall));
2680 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2684 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2689 super = iptr->sx.s23.s3.c.cls;
2690 superindex = super->index;
2693 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2694 CODEGEN_CRITICAL_SECTION_NEW;
2696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2698 /* if class is not resolved, check which code to call */
2700 if (super == NULL) {
2701 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2703 cr = iptr->sx.s23.s3.c.ref;
2704 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2706 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2709 M_ILD(REG_ITMP2, REG_PV, disp);
2710 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2711 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2714 /* interface checkcast code */
2716 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2717 if (super == NULL) {
2718 cr = iptr->sx.s23.s3.c.ref;
2720 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2724 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2727 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2728 M_ILD(REG_ITMP3, REG_ITMP2,
2729 OFFSET(vftbl_t, interfacetablelength));
2730 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2731 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2733 M_ALD(REG_ITMP3, REG_ITMP2,
2734 OFFSET(vftbl_t, interfacetable[0]) -
2735 superindex * sizeof(methodptr*));
2736 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2739 emit_label_br(cd, BRANCH_LABEL_4);
2741 emit_label(cd, BRANCH_LABEL_3);
2744 /* class checkcast code */
2746 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2747 if (super == NULL) {
2748 emit_label(cd, BRANCH_LABEL_2);
2750 cr = iptr->sx.s23.s3.c.ref;
2751 disp = dseg_add_unique_address(cd, NULL);
2753 codegen_add_patch_ref(cd,
2754 PATCHER_checkcast_instanceof_class,
2758 disp = dseg_add_address(cd, super->vftbl);
2760 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2763 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2764 M_ALD(REG_ITMP3, REG_PV, disp);
2766 CODEGEN_CRITICAL_SECTION_START;
2768 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2769 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2770 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2771 M_ALD(REG_ITMP3, REG_PV, disp);
2772 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2774 CODEGEN_CRITICAL_SECTION_END;
2777 M_CMP(REG_ITMP3, REG_ITMP2);
2778 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2781 emit_label(cd, BRANCH_LABEL_5);
2784 if (super == NULL) {
2785 emit_label(cd, BRANCH_LABEL_1);
2786 emit_label(cd, BRANCH_LABEL_4);
2789 d = codegen_reg_of_dst(jd, iptr, s1);
2792 /* array type cast-check */
2794 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2795 M_INTMOVE(s1, REG_OUT0);
2797 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2799 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2800 cr = iptr->sx.s23.s3.c.ref;
2801 disp = dseg_add_unique_address(cd, NULL);
2803 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2807 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2809 M_ALD(REG_OUT1, REG_PV, disp);
2810 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2811 M_ALD(REG_ITMP3, REG_PV, disp);
2812 /* XXX jit-c-call */
2813 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2817 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2819 d = codegen_reg_of_dst(jd, iptr, s1);
2823 emit_store_dst(jd, iptr, d);
2826 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2827 /* val.a: (classinfo*) superclass */
2829 /* superclass is an interface:
2831 * return (sub != NULL) &&
2832 * (sub->vftbl->interfacetablelength > super->index) &&
2833 * (sub->vftbl->interfacetable[-super->index] != NULL);
2835 * superclass is a class:
2837 * return ((sub != NULL) && (0
2838 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2839 * super->vftbl->diffvall));
2844 vftbl_t *supervftbl;
2847 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2853 super = iptr->sx.s23.s3.c.cls;
2854 superindex = super->index;
2855 supervftbl = super->vftbl;
2858 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2859 CODEGEN_CRITICAL_SECTION_NEW;
2861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2862 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2864 M_MOV(s1, REG_ITMP1);
2870 /* if class is not resolved, check which code to call */
2872 if (super == NULL) {
2873 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2875 cr = iptr->sx.s23.s3.c.ref;
2876 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2878 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2881 M_ILD(REG_ITMP3, REG_PV, disp);
2882 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2883 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2886 /* interface instanceof code */
2888 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2889 if (super == NULL) {
2890 cr = iptr->sx.s23.s3.c.ref;
2892 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2896 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2899 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2900 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2901 M_CMP_IMM(REG_ITMP3, superindex);
2904 M_ALD(REG_ITMP1, REG_ITMP1,
2905 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2906 superindex * sizeof(methodptr*)));
2907 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2910 emit_label_br(cd, BRANCH_LABEL_4);
2912 emit_label(cd, BRANCH_LABEL_3);
2915 /* class instanceof code */
2917 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2918 if (super == NULL) {
2919 emit_label(cd, BRANCH_LABEL_2);
2921 cr = iptr->sx.s23.s3.c.ref;
2922 disp = dseg_add_unique_address(cd, NULL);
2924 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2928 disp = dseg_add_address(cd, supervftbl);
2930 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2933 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2934 M_ALD(REG_ITMP2, REG_PV, disp);
2936 CODEGEN_CRITICAL_SECTION_START;
2938 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2939 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2940 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2942 CODEGEN_CRITICAL_SECTION_END;
2944 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2945 M_CMP(REG_ITMP1, REG_ITMP2);
2946 M_XCMOVULE_IMM(1, d);
2949 emit_label(cd, BRANCH_LABEL_5);
2952 if (super == NULL) {
2953 emit_label(cd, BRANCH_LABEL_1);
2954 emit_label(cd, BRANCH_LABEL_4);
2957 emit_store_dst(jd, iptr, d);
2961 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2963 /* check for negative sizes and copy sizes to stack if necessary */
2965 MCODECHECK((iptr->s1.argcount << 1) + 64);
2967 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2969 var = VAR(iptr->sx.s23.s2.args[s1]);
2971 /* copy SAVEDVAR sizes to stack */
2973 /* Already Preallocated? */
2975 if (!(var->flags & PREALLOC)) {
2976 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2977 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2981 /* arg 0 = dimension count */
2983 ICONST(REG_OUT0, iptr->s1.argcount);
2985 /* is patcher function set? */
2987 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2988 disp = dseg_add_unique_address(cd, 0);
2990 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2991 iptr->sx.s23.s3.c.ref,
2995 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2997 /* arg 1 = arraydescriptor */
2999 M_ALD(REG_OUT1, REG_PV, disp);
3001 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
3003 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
3005 /* XXX c abi call */
3006 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3007 M_ALD(REG_ITMP3, REG_PV, disp);
3008 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3011 /* check for exception before result assignment */
3013 emit_exception_check(cd, iptr);
3015 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
3016 M_INTMOVE(REG_RESULT_CALLER, d);
3017 emit_store_dst(jd, iptr, d);
3021 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3027 } /* for instruction */
3031 /* At the end of a basic block we may have to append some nops,
3032 because the patcher stub calling code might be longer than the
3033 actual instruction. So codepatching does not change the
3034 following block unintentionally. */
3036 if (cd->mcodeptr < cd->lastmcodeptr) {
3037 while (cd->mcodeptr < cd->lastmcodeptr) {
3042 } /* if (bptr -> flags >= BBREACHED) */
3043 } /* for basic block */
3045 dseg_createlinenumbertable(cd);
3047 /* generate stubs */
3049 emit_patcher_stubs(jd);
3051 /* everything's ok */
3057 /* codegen_emit_stub_compiler **************************************************
3059 Emits a stub routine which calls the compiler.
3061 *******************************************************************************/
3063 void codegen_emit_stub_compiler(jitdata *jd)
3068 /* get required compiler data */
3073 /* code for the stub */
3075 /* no window save yet, user caller's PV */
3076 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3077 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3078 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3083 /* codegen_emit_stub_builtin ***************************************************
3085 Creates a stub routine which calls a builtin function.
3087 *******************************************************************************/
3089 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
3098 /* get required compiler data */
3102 /* set some variables */
3105 /* calculate stack frame size */
3106 cd->stackframesize =
3110 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3111 4; /* 4 arguments or return value */
3114 /* keep stack 16-byte aligned (ABI requirement) */
3116 if (cd->stackframesize & 1)
3117 cd->stackframesize++;
3119 /* create method header */
3120 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3121 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3122 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3123 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3124 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3125 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3126 (void) dseg_addlinenumbertablesize(cd);
3127 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3130 /* generate stub code */
3131 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3133 #if defined(ENABLE_GC_CACAO)
3134 /* Save callee saved integer registers in stackframeinfo (GC may
3135 need to recover them during a collection). */
3137 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3138 OFFSET(stackframeinfo_t, intregs) + BIAS;
3140 for (i = 0; i < INT_SAV_CNT; i++)
3141 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3144 for (i = 0; i < md->paramcount; i++) {
3145 s1 = md->params[i].regoff;
3147 switch (md->paramtypes[i].type) {
3154 M_DST(s1, REG_SP, JITSTACK + i * 8);
3159 /* create dynamic stack info */
3161 M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
3162 M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
3163 M_MOV(REG_FP, REG_OUT2); /* java sp */
3164 M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
3166 disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
3167 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3168 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3169 M_NOP; /* XXX fill me! */
3172 /* builtins are allowed to have 5 arguments max */
3174 assert(md->paramcount <= 5);
3176 /* copy arguments into position */
3178 for (i = 0; i < md->paramcount; i++) {
3179 assert(!md->params[i].inmemory);
3181 s1 = md->params[i].regoff;
3183 switch (md->paramtypes[i].type) {
3187 M_MOV(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]), s1);
3191 M_DLD(s1, REG_SP, JITSTACK + i * 8);
3197 /* call the builtin function */
3199 disp = dseg_add_functionptr(cd, bte->fp);
3200 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
3201 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin */
3202 M_NOP; /* delay slot */
3205 /* save return value */
3207 if (md->returntype.type != TYPE_VOID) {
3208 if (IS_INT_LNG_TYPE(md->returntype.type))
3209 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3211 M_DST(REG_FRESULT, REG_SP, CSTACK);
3215 /* remove native stackframe info */
3217 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3218 disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
3219 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3220 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3223 /* restore float return value, int return value already in our return reg */
3225 if (md->returntype.type != TYPE_VOID) {
3226 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3227 if (IS_2_WORD_TYPE(md->returntype.type))
3228 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3230 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3235 #if defined(ENABLE_GC_CACAO)
3236 /* Restore callee saved integer registers from stackframeinfo (GC
3237 might have modified them during a collection). */
3239 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3240 OFFSET(stackframeinfo_t, intregs) + BIAS;
3242 for (i = 0; i < INT_SAV_CNT; i++)
3243 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3247 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3254 /* codegen_emit_stub_native ****************************************************
3256 Emits a stub routine which calls a native method.
3258 *******************************************************************************/
3260 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3267 s4 i, j; /* count variables */
3270 s4 funcdisp; /* displacement of the function */
3271 s4 fltregarg_offset[FLT_ARG_CNT];
3273 /* get required compiler data */
3279 /* initialize variables */
3282 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3284 /* calculate stack frame size */
3286 cd->stackframesize =
3287 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3288 sizeof(localref_table) / SIZEOF_VOID_P +
3289 md->paramcount + /* for saving arguments over calls */
3290 nmd->memuse + /* nmd->memuse includes the (6) abi params */
3294 /* keep stack 16-byte aligned (ABI requirement) */
3296 if (cd->stackframesize & 1)
3297 cd->stackframesize++;
3299 /* create method header */
3301 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3302 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3303 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3304 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3305 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3306 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3307 (void) dseg_addlinenumbertablesize(cd);
3308 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3310 /* generate stub code */
3312 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3314 #if !defined(NDEBUG)
3315 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3316 emit_verbosecall_enter(jd);
3319 /* get function address (this must happen before the stackframeinfo) */
3321 funcdisp = dseg_add_functionptr(cd, f);
3324 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3326 /* save float argument registers */
3328 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3330 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3331 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3332 s1 = WINSAVE_CNT + nmd->memuse + j;
3333 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3334 fltregarg_offset[i] = s1; /* remember stack offset */
3339 /* prepare data structures for native function call */
3341 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3342 M_MOV(REG_PV_CALLEE, REG_OUT1);
3343 M_MOV(REG_FP, REG_OUT2); /* java sp */
3344 M_MOV(REG_RA_CALLEE, REG_OUT3);
3345 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3346 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3347 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3348 M_NOP; /* XXX fill me! */
3350 /* remember class argument */
3352 if (m->flags & ACC_STATIC)
3353 M_MOV(REG_RESULT_CALLER, REG_ITMP3);
3355 /* keep float arguments on stack */
3357 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3358 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3359 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3365 /* copy or spill arguments to new locations */
3367 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3368 t = md->paramtypes[i].type;
3370 if (IS_INT_LNG_TYPE(t)) {
3372 /* integral types */
3374 if (!md->params[i].inmemory) {
3375 s1 = md->params[i].regoff;
3376 /* s1 refers to the old window, transpose */
3377 s1 = REG_WINDOW_TRANSPOSE(s1);
3379 if (!nmd->params[j].inmemory) {
3380 s2 = nmd->params[j].regoff;
3383 /* nmd's regoff is relative to the start of the param array */
3384 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3385 M_AST(s1, REG_SP, s2);
3389 if (!nmd->params[j].inmemory) {
3390 /* JIT stack arg -> NAT reg arg */
3392 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3393 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3395 assert(false); /* path never taken */
3398 s1 = md->params[i].regoff + cd->stackframesize * 8;
3399 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3400 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3401 M_AST(REG_ITMP1, REG_SP, s2);
3406 /* floating point types */
3408 if (!md->params[i].inmemory) {
3409 s1 = md->params[i].regoff;
3411 if (!nmd->params[j].inmemory) {
3413 /* no mapping to regs needed, native flt args use regoff */
3414 s2 = nmd->params[j].regoff;
3416 /* JIT float regs are still on the stack */
3417 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3420 /* not supposed to happen with 16 NAT flt args */
3423 s2 = nmd->params[j].regoff;
3424 if (IS_2_WORD_TYPE(t))
3425 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3427 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3433 s1 = md->params[i].regoff;
3435 if (!nmd->params[j].inmemory) {
3437 /* JIT stack -> NAT reg */
3439 s2 = nmd->params[j].regoff;
3440 M_DLD(s2, REG_FP, JITSTACK + s1);
3444 /* JIT stack -> NAT stack */
3446 s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3448 /* The FTMP register may already be loaded with args */
3449 /* we know $f0 is unused because of the env pointer */
3450 M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3451 M_DST(REG_F0, REG_SP, BIAS + s2);
3458 /* put class into second argument register */
3460 if (m->flags & ACC_STATIC)
3461 M_MOV(REG_ITMP3, REG_OUT1);
3463 /* put env into first argument register */
3465 disp = dseg_add_address(cd, _Jv_env);
3466 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3468 /* do the native function call */
3470 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3471 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3472 M_NOP; /* delay slot */
3474 /* save return value */
3476 if (md->returntype.type != TYPE_VOID) {
3477 if (IS_INT_LNG_TYPE(md->returntype.type))
3478 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3480 M_DST(REG_FRESULT, REG_SP, CSTACK);
3483 /* Note: native functions return float values in %f0 (see ABI) */
3484 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3486 #if !defined(NDEBUG)
3487 /* But for the trace function we need to put a flt result into %f1 */
3488 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3489 if (!IS_2_WORD_TYPE(md->returntype.type))
3490 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3491 emit_verbosecall_exit(jd);
3495 /* remove native stackframe info */
3497 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3498 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3499 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3500 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3501 M_NOP; /* XXX fill me! */
3502 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3504 /* restore float return value, int return value already in our return reg */
3506 if (md->returntype.type != TYPE_VOID) {
3507 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3508 if (IS_2_WORD_TYPE(md->returntype.type))
3509 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3511 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3515 /* check for exception */
3516 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3519 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3522 /* handle exception */
3524 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3525 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3526 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3527 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3528 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3530 /* generate patcher stubs */
3532 emit_patcher_stubs(jd);
3536 * These are local overrides for various environment variables in Emacs.
3537 * Please do not remove this and leave it at the end of the file, where
3538 * Emacs will automagically detect them.
3539 * ---------------------------------------------------------------------
3542 * indent-tabs-mode: t
3546 * vim:noexpandtab:sw=4:ts=4: