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 dummy IsSync */
202 (void) dseg_add_unique_s4(cd, 0);
204 /* REMOVEME: We still need it for exception handling in assembler. */
206 if (code_is_leafmethod(code))
207 (void) dseg_add_unique_s4(cd, 1);
209 (void) dseg_add_unique_s4(cd, 0);
211 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
212 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
213 dseg_addlinenumbertablesize(cd);
214 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
216 /* create exception table */
218 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
219 dseg_add_target(cd, ex->start);
220 dseg_add_target(cd, ex->end);
221 dseg_add_target(cd, ex->handler);
222 (void) dseg_add_unique_address(cd, ex->catchtype.any);
225 /* save register window and create stack frame (if necessary) */
227 if (cd->stackframesize) {
228 if (cd->stackframesize <= 4095)
229 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
231 M_ILD_INTERN(REG_ITMP3, REG_PV_CALLER, framesize_disp);
232 M_SUB(REG_ZERO, REG_ITMP3, REG_ITMP3);
233 M_SAVE_REG(REG_SP, REG_ITMP3, REG_SP);
237 /* save callee saved float registers (none right now) */
239 p = cd->stackframesize;
240 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
241 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
246 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
247 emit_verbosecall_enter(jd);
251 /* call monitorenter function */
252 #if defined(ENABLE_THREADS)
253 if (checksync && code_is_synchronized(code)) {
254 /* stack offset for monitor argument */
258 /* save float argument registers */
262 ALIGN_STACK_SLOTS(slots);
264 M_LDA(REG_SP, REG_SP, -(slots * 8));
265 for (i = 0; i < FLT_ARG_CNT; i++)
266 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
270 /* get correct lock object */
272 if (m->flags & ACC_STATIC) {
273 disp = dseg_add_address(cd, &m->class->object.header);
274 M_ALD(REG_OUT0, REG_PV, disp);
275 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
276 M_ALD(REG_ITMP3, REG_PV, disp);
279 /* copy class pointer: $i0 -> $o0 */
280 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
282 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
283 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
284 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
287 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
288 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
290 /* restore float argument registers */
292 for (i = 0; i < FLT_ARG_CNT; i++)
293 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
295 M_LDA(REG_SP, REG_SP, slots * 8);
300 /* take arguments out of register or stack frame */
304 for (p = 0, l = 0; p < md->paramcount; p++) {
305 t = md->paramtypes[p].type;
307 varindex = jd->local_map[l * 5 + t];
310 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
313 if (varindex == UNUSED)
317 s1 = md->params[p].regoff;
319 if (IS_INT_LNG_TYPE(t)) { /* integer args */
323 if (!md->params[p].inmemory) { /* register arguments */
324 s1 = REG_WINDOW_TRANSPOSE(s1);
326 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
328 /* the register allocator does not know about the window. */
329 /* avoid copying the locals from save to save regs by */
330 /* swapping variables. */
333 int old_dest = var->vv.regoff;
334 int new_dest = p + 24;
336 /* run through all variables */
338 for (i = 0; i < jd->varcount; i++) {
339 varinfo* uvar = VAR(i);
341 if (IS_FLT_DBL_TYPE(uvar->type) || IS_INMEMORY(uvar->flags))
344 s2 = uvar->vv.regoff;
346 /* free the in reg by moving all other references */
348 if (s2 == new_dest) {
349 uvar->vv.regoff = old_dest;
350 /*printf("p%d-var[%d]: moved %d -> %d (to free save reg)\n", p, i, s2, old_dest);*/
353 /* move all variables to the in reg */
355 if (s2 == old_dest) {
356 uvar->vv.regoff = new_dest;
357 /*printf("p%d-var[%d]: moved %d -> %d (to avoid copy)\n", p, i, s2, new_dest);*/
365 else { /* reg arg -> spilled */
366 M_STX(s1, REG_SP, JITSTACK + var->vv.regoff);
369 } else { /* stack arguments */
370 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
371 M_LDX(var->vv.regoff, REG_FP, JITSTACK + s1);
373 } else { /* stack arg -> spilled */
374 /* add the callers window save registers */
375 var->vv.regoff = cd->stackframesize * 8 + s1;
379 } else { /* floating args */
380 if (!md->params[p].inmemory) { /* register arguments */
381 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
382 M_FLTMOVE(s1, var->vv.regoff);
384 } else { /* reg arg -> spilled */
385 M_DST(s1, REG_SP, JITSTACK + var->vv.regoff);
388 } else { /* stack arguments */
389 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
390 M_DLD(var->vv.regoff, REG_FP, JITSTACK + s1);
392 } else { /* stack-arg -> spilled */
393 var->vv.regoff = cd->stackframesize * 8 + s1;
402 /* end of header generation */
404 /* create replacement points */
406 REPLACEMENT_POINTS_INIT(cd, jd);
408 /* walk through all basic blocks */
410 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
412 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
414 if (bptr->flags >= BBREACHED) {
416 /* branch resolving */
418 codegen_resolve_branchrefs(cd, bptr);
420 /* handle replacement points */
422 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
425 /* copy interface registers to their destination */
430 #if defined(ENABLE_LSRA)
431 #error XXX LSRA not tested yet
435 src = bptr->invars[len];
436 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
437 /* d = reg_of_var(m, src, REG_ITMP1); */
438 if (!(src->flags & INMEMORY))
442 M_INTMOVE(REG_ITMP1, d);
443 emit_store(jd, NULL, src, d);
450 var = VAR(bptr->invars[len]);
451 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
452 d = codegen_reg_of_var(0, var, REG_ITMP1);
453 M_INTMOVE(REG_ITMP2_XPTR, d);
454 emit_store(jd, NULL, var, d);
457 assert((var->flags & INOUT));
460 #if defined(ENABLE_LSRA)
463 /* walk through all instructions */
467 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
468 if (iptr->line != currentline) {
469 dseg_addlinenumber(cd, iptr->line);
470 currentline = iptr->line;
473 MCODECHECK(64); /* an instruction usually needs < 64 words */
477 case ICMD_INLINE_START:
478 case ICMD_INLINE_END:
481 case ICMD_NOP: /* ... ==> ... */
484 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
487 emit_nullpointer_check(cd, iptr, s1);
490 /* constant operations ************************************************/
492 case ICMD_ICONST: /* ... ==> ..., constant */
494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
495 ICONST(d, iptr->sx.val.i);
496 emit_store_dst(jd, iptr, d);
499 case ICMD_LCONST: /* ... ==> ..., constant */
501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
502 LCONST(d, iptr->sx.val.l);
503 emit_store_dst(jd, iptr, d);
506 case ICMD_FCONST: /* ... ==> ..., constant */
508 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
509 disp = dseg_add_float(cd, iptr->sx.val.f);
510 M_FLD(d, REG_PV, disp);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_DCONST: /* ... ==> ..., constant */
516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
517 disp = dseg_add_double(cd, iptr->sx.val.d);
518 M_DLD(d, REG_PV, disp);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_ACONST: /* ... ==> ..., constant */
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
526 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
527 cr = iptr->sx.val.c.ref;
528 disp = dseg_add_unique_address(cd, cr);
530 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
532 M_ALD(d, REG_PV, disp);
536 if (iptr->sx.val.anyptr == NULL) {
537 M_INTMOVE(REG_ZERO, d);
540 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
541 M_ALD(d, REG_PV, disp);
544 emit_store_dst(jd, iptr, d);
548 /* load/store/copy/move operations ************************************/
550 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
555 case ICMD_ISTORE: /* ..., value ==> ... */
566 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
571 /* pop/dup/swap operations ********************************************/
573 /* attention: double and longs are only one entry in CACAO ICMDs */
575 case ICMD_POP: /* ..., value ==> ... */
576 case ICMD_POP2: /* ..., value, value ==> ... */
580 /* integer operations *************************************************/
582 case ICMD_INEG: /* ..., value ==> ..., - value */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 M_SUB(REG_ZERO, s1, d);
588 emit_store_dst(jd, iptr, d);
591 case ICMD_I2L: /* ..., value ==> ..., value */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596 emit_store_dst(jd, iptr, d);
599 case ICMD_L2I: /* ..., value ==> ..., value */
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
604 emit_store_dst(jd, iptr, d);
607 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 M_SLLX_IMM(s1, 56, d);
612 M_SRAX_IMM( d, 56, d);
613 emit_store_dst(jd, iptr, d);
616 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 M_SLLX_IMM(s1, 48, d);
621 M_SRLX_IMM( d, 48, d);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
629 M_SLLX_IMM(s1, 48, d);
630 M_SRAX_IMM( d, 48, d);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 emit_store_dst(jd, iptr, d);
645 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
646 /* sx.val.i = constant */
648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
651 M_ADD_IMM(s1, iptr->sx.val.i, d);
653 ICONST(REG_ITMP2, iptr->sx.val.i);
654 M_ADD(s1, REG_ITMP2, d);
656 emit_store_dst(jd, iptr, d);
659 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
660 /* sx.val.l = constant */
662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
665 M_ADD_IMM(s1, iptr->sx.val.l, d);
667 LCONST(REG_ITMP2, iptr->sx.val.l);
668 M_ADD(s1, REG_ITMP2, d);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
684 /* sx.val.i = constant */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
689 M_SUB_IMM(s1, iptr->sx.val.i, d);
691 ICONST(REG_ITMP2, iptr->sx.val.i);
692 M_SUB(s1, REG_ITMP2, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
698 /* sx.val.l = constant */
700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
702 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
703 M_SUB_IMM(s1, iptr->sx.val.l, d);
705 LCONST(REG_ITMP2, iptr->sx.val.l);
706 M_SUB(s1, REG_ITMP2, d);
708 emit_store_dst(jd, iptr, d);
711 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
715 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
716 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 emit_store_dst(jd, iptr, d);
721 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
722 /* sx.val.i = constant */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
726 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
727 M_MULX_IMM(s1, iptr->sx.val.i, d);
729 ICONST(REG_ITMP2, iptr->sx.val.i);
730 M_MULX(s1, REG_ITMP2, d);
732 emit_store_dst(jd, iptr, d);
735 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
736 /* sx.val.l = constant */
738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
739 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
740 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
741 M_MULX_IMM(s1, iptr->sx.val.l, d);
743 LCONST(REG_ITMP2, iptr->sx.val.l);
744 M_MULX(s1, REG_ITMP2, d);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
750 /* XXX could also clear Y and use 32bit div */
751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 emit_arithmetic_check(cd, iptr, s2);
756 /* XXX trim s2 like s1 ? */
758 emit_store_dst(jd, iptr, d);
761 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
764 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766 emit_arithmetic_check(cd, iptr, s2);
768 emit_store_dst(jd, iptr, d);
771 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
776 emit_arithmetic_check(cd, iptr, s2);
778 /* XXX trim s2 like s1 ? */
779 M_DIVX(s1, s2, REG_ITMP3);
780 M_MULX(s2, REG_ITMP3, REG_ITMP3);
781 M_SUB(s1, REG_ITMP3, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
790 emit_arithmetic_check(cd, iptr, s2);
791 M_DIVX(s1, s2, REG_ITMP3);
792 M_MULX(s2, REG_ITMP3, REG_ITMP3);
793 M_SUB(s1, REG_ITMP3, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
798 case ICMD_LDIVPOW2: /* val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_SRAX_IMM(s1, 63, REG_ITMP2);
803 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
804 M_ADD(s1, REG_ITMP2, REG_ITMP2);
805 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
828 /* val.i = constant */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
832 M_SLL_IMM(s1, iptr->sx.val.i, d);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
837 /* val.i = constant */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841 M_SLLX_IMM(s1, iptr->sx.val.i, d);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 M_SRA_IMM(s1, iptr->sx.val.i, d);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 emit_store_dst(jd, iptr, d);
872 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
873 /* sx.val.i = constant */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
877 M_SRL_IMM(s1, iptr->sx.val.i, d);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
891 /* sx.val.i = constant */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895 M_SRAX_IMM(s1, iptr->sx.val.i, d);
896 emit_store_dst(jd, iptr, d);
899 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
902 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
903 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
909 /* sx.val.i = constant */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913 M_SRLX_IMM(s1, iptr->sx.val.i, d);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
928 /* sx.val.i = constant */
930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
933 M_AND_IMM(s1, iptr->sx.val.i, d);
935 ICONST(REG_ITMP2, iptr->sx.val.i);
936 M_AND(s1, REG_ITMP2, d);
938 emit_store_dst(jd, iptr, d);
941 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
942 /* sx.val.i = constant */
943 /* constant is actually constant - 1 */
945 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
948 M_MOV(s1, REG_ITMP1);
951 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
952 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
953 M_AND_IMM(s1, iptr->sx.val.i, d);
956 M_SUB(REG_ZERO, s1, d);
957 M_AND_IMM(d, iptr->sx.val.i, d);
959 ICONST(REG_ITMP2, iptr->sx.val.i);
960 M_AND(s1, REG_ITMP2, d);
963 M_SUB(REG_ZERO, s1, d);
964 M_AND(d, REG_ITMP2, d);
966 M_SUB(REG_ZERO, d, d);
967 emit_store_dst(jd, iptr, d);
970 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
971 /* sx.val.l = constant */
973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
976 M_AND_IMM(s1, iptr->sx.val.l, d);
978 LCONST(REG_ITMP2, iptr->sx.val.l);
979 M_AND(s1, REG_ITMP2, d);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
985 /* sx.val.l = constant */
987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990 M_MOV(s1, REG_ITMP1);
993 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
994 M_AND_IMM(s1, iptr->sx.val.l, d);
997 M_SUB(REG_ZERO, s1, d);
998 M_AND_IMM(d, iptr->sx.val.l, d);
1000 LCONST(REG_ITMP2, iptr->sx.val.l);
1001 M_AND(s1, REG_ITMP2, d);
1004 M_SUB(REG_ZERO, s1, d);
1005 M_AND(d, REG_ITMP2, d);
1007 M_SUB(REG_ZERO, d, d);
1008 emit_store_dst(jd, iptr, d);
1011 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1022 /* sx.val.i = constant */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1027 M_OR_IMM(s1, iptr->sx.val.i, d);
1029 ICONST(REG_ITMP2, iptr->sx.val.i);
1030 M_OR(s1, REG_ITMP2, d);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1036 /* sx.val.l = constant */
1038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1039 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1040 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1041 M_OR_IMM(s1, iptr->sx.val.l, d);
1043 LCONST(REG_ITMP2, iptr->sx.val.l);
1044 M_OR(s1, REG_ITMP2, d);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1060 /* sx.val.i = constant */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1064 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1065 M_XOR_IMM(s1, iptr->sx.val.i, d);
1067 ICONST(REG_ITMP2, iptr->sx.val.i);
1068 M_XOR(s1, REG_ITMP2, d);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1074 /* sx.val.l = constant */
1076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1078 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1079 M_XOR_IMM(s1, iptr->sx.val.l, d);
1081 LCONST(REG_ITMP2, iptr->sx.val.l);
1082 M_XOR(s1, REG_ITMP2, d);
1084 emit_store_dst(jd, iptr, d);
1088 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 M_XCMOVLT_IMM(-1, d);
1096 M_XCMOVGT_IMM(1, d);
1097 emit_store_dst(jd, iptr, d);
1101 /* floating operations ************************************************/
1103 case ICMD_FNEG: /* ..., value ==> ..., - value */
1105 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1106 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_DNEG: /* ..., value ==> ..., - value */
1113 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1114 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1116 emit_store_dst(jd, iptr, d);
1119 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1121 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1122 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1123 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1130 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1131 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1132 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1139 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1140 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1143 emit_store_dst(jd, iptr, d);
1146 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1148 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1149 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1150 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1159 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1168 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1179 emit_store_dst(jd, iptr, d);
1182 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1184 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1185 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1186 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1188 emit_store_dst(jd, iptr, d);
1192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1193 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1194 disp = dseg_add_unique_float(cd, 0.0);
1195 M_IST (s1, REG_PV_CALLEE, disp);
1196 M_FLD (d, REG_PV_CALLEE, disp);
1197 M_CVTIF (d, d); /* rd gets translated to double target register */
1198 emit_store_dst(jd, iptr, d);
1202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1203 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 disp = dseg_add_unique_float(cd, 0.0);
1205 M_IST(s1, REG_PV_CALLEE, disp);
1206 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1207 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1208 emit_store_dst(jd, iptr, d);
1212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1213 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1214 disp = dseg_add_unique_double(cd, 0.0);
1215 M_STX(s1, REG_PV_CALLEE, disp);
1216 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1217 M_CVTLF(REG_FTMP3, d);
1218 emit_store_dst(jd, iptr, d);
1222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1223 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1224 disp = dseg_add_unique_double(cd, 0.0);
1225 M_STX(s1, REG_PV_CALLEE, disp);
1226 M_DLD(d, REG_PV_CALLEE, disp);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1232 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1233 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1234 disp = dseg_add_unique_float(cd, 0.0);
1236 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1239 M_MOV(REG_ZERO, d); /* delay slot */
1241 M_CVTFI(s1, REG_FTMP2);
1242 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1243 M_ILD(d, REG_PV, disp);
1244 emit_store_dst(jd, iptr, d);
1248 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1251 disp = dseg_add_unique_float(cd, 0.0);
1253 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1256 M_MOV(REG_ZERO, d); /* delay slot */
1258 M_CVTDI(s1, REG_FTMP2);
1259 M_FST(REG_FTMP2, REG_PV, disp);
1260 M_ILD(d, REG_PV, disp);
1261 emit_store_dst(jd, iptr, d);
1264 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1267 disp = dseg_add_unique_double(cd, 0.0);
1269 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1272 M_MOV(REG_ZERO, d); /* delay slot */
1274 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1275 M_DST(REG_FTMP2, REG_PV, disp);
1276 M_LDX(d, REG_PV, disp);
1277 emit_store_dst(jd, iptr, d);
1280 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1281 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1282 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1283 disp = dseg_add_unique_double(cd, 0.0);
1285 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1288 M_MOV(REG_ZERO, d); /* delay slot */
1290 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1291 M_DST(REG_FTMP2, REG_PV, disp);
1292 M_LDX(d, REG_PV, disp);
1293 emit_store_dst(jd, iptr, d);
1296 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1298 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1299 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1306 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1307 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1309 emit_store_dst(jd, iptr, d);
1312 /* XXX merge F/D versions? only compare instr. is different */
1313 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1315 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1316 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1317 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1319 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1320 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1321 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1327 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1328 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1329 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1331 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1332 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1333 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1339 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1341 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1343 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1344 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1345 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1351 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1355 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1356 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1357 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1358 emit_store_dst(jd, iptr, d);
1362 /* memory operations **************************************************/
1364 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368 emit_nullpointer_check(cd, iptr, s1);
1369 M_ILD(d, s1, OFFSET(java_array_t, size));
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1375 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1376 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1378 /* implicit null-pointer check */
1379 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1380 M_AADD(s2, s1, REG_ITMP3);
1381 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1382 emit_store_dst(jd, iptr, d);
1385 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1390 /* implicit null-pointer check */
1391 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1392 M_AADD(s2, s1, REG_ITMP3);
1393 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1394 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1395 emit_store_dst(jd, iptr, d);
1398 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1400 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1401 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1403 /* implicit null-pointer check */
1404 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1405 M_AADD(s2, s1, REG_ITMP3);
1406 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1407 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1408 emit_store_dst(jd, iptr, d);
1411 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1416 /* implicit null-pointer check */
1417 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1418 M_ASLL_IMM(s2, 2, REG_ITMP3);
1419 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1420 M_ILD(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1421 emit_store_dst(jd, iptr, d);
1424 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1427 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1429 /* implicit null-pointer check */
1430 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1431 M_ASLL_IMM(s2, 3, REG_ITMP3);
1432 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1433 M_LDX(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1442 /* implicit null-pointer check */
1443 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1444 M_ASLL_IMM(s2, 2, REG_ITMP3);
1445 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1446 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1447 emit_store_dst(jd, iptr, d);
1450 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1452 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1454 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1455 /* implicit null-pointer check */
1456 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1457 M_ASLL_IMM(s2, 3, REG_ITMP3);
1458 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1459 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1460 emit_store_dst(jd, iptr, d);
1463 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1468 /* implicit null-pointer check */
1469 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1470 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1471 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1472 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1473 emit_store_dst(jd, iptr, d);
1477 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1479 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1480 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1481 /* implicit null-pointer check */
1482 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1483 M_AADD(s2, s1, REG_ITMP1);
1484 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1485 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1488 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1489 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1493 /* implicit null-pointer check */
1494 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1495 M_AADD(s2, s1, REG_ITMP1);
1496 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1497 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1498 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1501 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1504 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1505 /* implicit null-pointer check */
1506 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1507 M_ASLL_IMM(s2, 2, REG_ITMP2);
1508 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1509 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1510 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1513 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1517 /* implicit null-pointer check */
1518 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1519 M_ASLL_IMM(s2, 3, REG_ITMP2);
1520 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1521 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1522 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1525 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1529 /* implicit null-pointer check */
1530 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1531 M_ASLL_IMM(s2, 2, REG_ITMP2);
1532 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1533 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1534 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1537 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 /* implicit null-pointer check */
1542 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1543 M_ASLL_IMM(s2, 3, REG_ITMP2);
1544 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1545 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1546 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1550 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1554 /* implicit null-pointer check */
1555 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1556 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1558 M_MOV(s1, REG_OUT0);
1559 M_MOV(s3, REG_OUT1);
1560 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1561 M_ALD(REG_ITMP3, REG_PV, disp);
1562 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1564 emit_arraystore_check(cd, iptr);
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1568 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1569 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1570 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1571 /* implicit null-pointer check */
1572 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1576 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1580 /* implicit null-pointer check */
1581 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1582 M_AADD(s2, s1, REG_ITMP1);
1583 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1586 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1587 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591 /* implicit null-pointer check */
1592 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1593 M_AADD(s2, s1, REG_ITMP1);
1594 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1595 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1598 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1602 /* implicit null-pointer check */
1603 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1604 M_ASLL_IMM(s2, 2, REG_ITMP2);
1605 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1606 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1609 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1612 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1613 /* implicit null-pointer check */
1614 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1615 M_ASLL_IMM(s2, 3, REG_ITMP2);
1616 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1617 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1620 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1624 /* implicit null-pointer check */
1625 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1626 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1627 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1628 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1632 case ICMD_GETSTATIC: /* ... ==> ..., value */
1634 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1635 uf = iptr->sx.s23.s3.uf;
1636 fieldtype = uf->fieldref->parseddesc.fd->type;
1637 disp = dseg_add_unique_address(cd, uf);
1639 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1642 fi = iptr->sx.s23.s3.fmiref->p.field;
1643 fieldtype = fi->type;
1644 disp = dseg_add_address(cd, fi->value);
1646 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1647 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1650 M_ALD(REG_ITMP1, REG_PV, disp);
1652 switch (fieldtype) {
1654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1655 M_ILD_INTERN(d, REG_ITMP1, 0);
1658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1659 M_LDX_INTERN(d, REG_ITMP1, 0);
1662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1663 M_ALD_INTERN(d, REG_ITMP1, 0);
1666 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1667 M_FLD_INTERN(d, REG_ITMP1, 0);
1670 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1671 M_DLD_INTERN(d, REG_ITMP1, 0);
1674 emit_store_dst(jd, iptr, d);
1677 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1679 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1680 uf = iptr->sx.s23.s3.uf;
1681 fieldtype = uf->fieldref->parseddesc.fd->type;
1682 disp = dseg_add_unique_address(cd, uf);
1684 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1687 fi = iptr->sx.s23.s3.fmiref->p.field;
1688 fieldtype = fi->type;
1689 disp = dseg_add_address(cd, fi->value);
1691 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1692 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1695 M_ALD(REG_ITMP1, REG_PV, disp);
1697 switch (fieldtype) {
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1700 M_IST_INTERN(s1, REG_ITMP1, 0);
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1704 M_STX_INTERN(s1, REG_ITMP1, 0);
1707 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1708 M_AST_INTERN(s1, REG_ITMP1, 0);
1711 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1712 M_FST_INTERN(s1, REG_ITMP1, 0);
1715 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1716 M_DST_INTERN(s1, REG_ITMP1, 0);
1721 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1722 /* val = value (in current instruction) */
1723 /* following NOP) */
1725 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1726 uf = iptr->sx.s23.s3.uf;
1727 fieldtype = uf->fieldref->parseddesc.fd->type;
1728 disp = dseg_add_unique_address(cd, uf);
1730 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1733 fi = iptr->sx.s23.s3.fmiref->p.field;
1734 fieldtype = fi->type;
1735 disp = dseg_add_address(cd, fi->value);
1737 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1738 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1741 M_ALD(REG_ITMP1, REG_PV, disp);
1743 switch (fieldtype) {
1745 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1748 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1751 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1754 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1757 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1763 case ICMD_GETFIELD: /* ... ==> ..., value */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 emit_nullpointer_check(cd, iptr, s1);
1768 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1769 uf = iptr->sx.s23.s3.uf;
1771 fieldtype = uf->fieldref->parseddesc.fd->type;
1774 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1777 fi = iptr->sx.s23.s3.fmiref->p.field;
1778 fieldtype = fi->type;
1782 switch (fieldtype) {
1784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1796 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1800 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1807 emit_store_dst(jd, iptr, d);
1810 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1813 emit_nullpointer_check(cd, iptr, s1);
1815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816 uf = iptr->sx.s23.s3.uf;
1817 fieldtype = uf->fieldref->parseddesc.fd->type;
1822 fi = iptr->sx.s23.s3.fmiref->p.field;
1823 fieldtype = fi->type;
1827 if (IS_INT_LNG_TYPE(fieldtype))
1828 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1830 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1832 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1833 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1835 switch (fieldtype) {
1837 M_IST(s2, s1, disp);
1840 M_STX(s2, s1, disp);
1843 M_AST(s2, s1, disp);
1846 M_FST(s2, s1, disp);
1849 M_DST(s2, s1, disp);
1857 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1858 /* val = value (in current instruction) */
1859 /* following NOP) */
1861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1862 emit_nullpointer_check(cd, iptr, s1);
1864 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1865 unresolved_field *uf = iptr->sx.s23.s3.uf;
1867 fieldtype = uf->fieldref->parseddesc.fd->type;
1869 codegen_addpatchref(cd, PATCHER_get_putfield,
1872 if (opt_showdisassemble) {
1880 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1882 fieldtype = fi->type;
1888 switch (fieldtype) {
1890 M_IST(REG_ZERO, s1, disp);
1893 M_STX(REG_ZERO, s1, disp);
1896 M_AST(REG_ZERO, s1, disp);
1899 M_FST(REG_ZERO, s1, disp);
1902 M_DST(REG_ZERO, s1, disp);
1908 /* branch operations **************************************************/
1910 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913 M_INTMOVE(s1, REG_ITMP2_XPTR);
1915 #ifdef ENABLE_VERIFIER
1916 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1917 unresolved_class *uc = iptr->sx.s23.s2.uc;
1919 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1921 #endif /* ENABLE_VERIFIER */
1923 disp = dseg_add_functionptr(cd, asm_handle_exception);
1924 M_ALD(REG_ITMP1, REG_PV, disp);
1925 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1927 M_NOP; /* nop ensures that XPC is less than the end */
1928 /* of basic block */
1932 case ICMD_GOTO: /* ... ==> ... */
1933 case ICMD_RET: /* ... ==> ... */
1935 emit_br(cd, iptr->dst.block);
1939 case ICMD_JSR: /* ... ==> ... */
1941 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1945 case ICMD_IFNULL: /* ..., value ==> ... */
1946 case ICMD_IFNONNULL:
1948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1949 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1952 /* Note: int compares must not branch on the register directly. */
1953 /* Reason is, that register content is not 32-bit clean. */
1955 case ICMD_IFEQ: /* ..., value ==> ... */
1957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1960 M_CMP_IMM(s1, iptr->sx.val.i);
1963 ICONST(REG_ITMP2, iptr->sx.val.i);
1964 M_CMP(s1, REG_ITMP2);
1966 emit_beq(cd, iptr->dst.block);
1969 case ICMD_IFLT: /* ..., value ==> ... */
1971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1973 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1974 M_CMP_IMM(s1, iptr->sx.val.i);
1977 ICONST(REG_ITMP2, iptr->sx.val.i);
1978 M_CMP(s1, REG_ITMP2);
1980 emit_blt(cd, iptr->dst.block);
1983 case ICMD_IFLE: /* ..., value ==> ... */
1985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1988 M_CMP_IMM(s1, iptr->sx.val.i);
1991 ICONST(REG_ITMP2, iptr->sx.val.i);
1992 M_CMP(s1, REG_ITMP2);
1994 emit_ble(cd, iptr->dst.block);
1997 case ICMD_IFNE: /* ..., value ==> ... */
1999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2001 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2002 M_CMP_IMM(s1, iptr->sx.val.i);
2005 ICONST(REG_ITMP2, iptr->sx.val.i);
2006 M_CMP(s1, REG_ITMP2);
2008 emit_bne(cd, iptr->dst.block);
2011 case ICMD_IFGT: /* ..., value ==> ... */
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2015 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2016 M_CMP_IMM(s1, iptr->sx.val.i);
2019 ICONST(REG_ITMP2, iptr->sx.val.i);
2020 M_CMP(s1, REG_ITMP2);
2022 emit_bgt(cd, iptr->dst.block);
2025 case ICMD_IFGE: /* ..., value ==> ... */
2027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2029 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2030 M_CMP_IMM(s1, iptr->sx.val.i);
2033 ICONST(REG_ITMP2, iptr->sx.val.i);
2034 M_CMP(s1, REG_ITMP2);
2036 emit_bge(cd, iptr->dst.block);
2039 case ICMD_IF_LEQ: /* ..., value ==> ... */
2041 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2042 if (iptr->sx.val.l == 0)
2043 emit_beqz(cd, iptr->dst.block, s1);
2045 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2046 M_CMP_IMM(s1, iptr->sx.val.l);
2049 LCONST(REG_ITMP2, iptr->sx.val.l);
2050 M_CMP(s1, REG_ITMP2);
2052 emit_beq_xcc(cd, iptr->dst.block);
2056 case ICMD_IF_LLT: /* ..., value ==> ... */
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2059 if (iptr->sx.val.l == 0)
2060 emit_bltz(cd, iptr->dst.block, s1);
2062 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2063 M_CMP_IMM(s1, iptr->sx.val.l);
2066 LCONST(REG_ITMP2, iptr->sx.val.l);
2067 M_CMP(s1, REG_ITMP2);
2069 emit_blt_xcc(cd, iptr->dst.block);
2073 case ICMD_IF_LLE: /* ..., value ==> ... */
2075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2076 if (iptr->sx.val.l == 0)
2077 emit_blez(cd, iptr->dst.block, s1);
2079 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2080 M_CMP_IMM(s1, iptr->sx.val.l);
2083 LCONST(REG_ITMP2, iptr->sx.val.l);
2084 M_CMP(s1, REG_ITMP2);
2086 emit_ble_xcc(cd, iptr->dst.block);
2090 case ICMD_IF_LNE: /* ..., value ==> ... */
2092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2093 if (iptr->sx.val.l == 0)
2094 emit_bnez(cd, iptr->dst.block, s1);
2096 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2097 M_CMP_IMM(s1, iptr->sx.val.l);
2100 LCONST(REG_ITMP2, iptr->sx.val.l);
2101 M_CMP(s1, REG_ITMP2);
2103 emit_bne_xcc(cd, iptr->dst.block);
2107 case ICMD_IF_LGT: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 if (iptr->sx.val.l == 0)
2111 emit_bgtz(cd, iptr->dst.block, s1);
2113 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2114 M_CMP_IMM(s1, iptr->sx.val.l);
2117 LCONST(REG_ITMP2, iptr->sx.val.l);
2118 M_CMP(s1, REG_ITMP2);
2120 emit_bgt_xcc(cd, iptr->dst.block);
2124 case ICMD_IF_LGE: /* ..., value ==> ... */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 if (iptr->sx.val.l == 0)
2128 emit_bgez(cd, iptr->dst.block, s1);
2130 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2131 M_CMP_IMM(s1, iptr->sx.val.l);
2134 LCONST(REG_ITMP2, iptr->sx.val.l);
2135 M_CMP(s1, REG_ITMP2);
2137 emit_bge_xcc(cd, iptr->dst.block);
2142 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2143 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2146 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2148 emit_beq_xcc(cd, iptr->dst.block);
2151 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2156 emit_beq(cd, iptr->dst.block);
2159 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2160 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2165 emit_bne_xcc(cd, iptr->dst.block);
2168 case ICMD_IF_ICMPNE: /* 32-bit compare */
2170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2173 emit_bne(cd, iptr->dst.block);
2176 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2181 emit_blt_xcc(cd, iptr->dst.block);
2184 case ICMD_IF_ICMPLT: /* 32-bit compare */
2186 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2187 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2189 emit_blt(cd, iptr->dst.block);
2192 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2197 emit_bgt_xcc(cd, iptr->dst.block);
2200 case ICMD_IF_ICMPGT: /* 32-bit compare */
2202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2203 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2205 emit_bgt(cd, iptr->dst.block);
2208 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2211 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2213 emit_ble_xcc(cd, iptr->dst.block);
2216 case ICMD_IF_ICMPLE: /* 32-bit compare */
2218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2219 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2221 emit_ble(cd, iptr->dst.block);
2225 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2227 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2228 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2230 emit_bge_xcc(cd, iptr->dst.block);
2233 case ICMD_IF_ICMPGE: /* 32-bit compare */
2235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2238 emit_bge(cd, iptr->dst.block);
2242 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2245 REPLACEMENT_POINT_RETURN(cd, iptr);
2247 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2248 M_INTMOVE(s1, REG_RESULT_CALLEE);
2249 goto nowperformreturn;
2251 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2253 REPLACEMENT_POINT_RETURN(cd, iptr);
2255 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2256 M_INTMOVE(s1, REG_RESULT_CALLEE);
2258 #ifdef ENABLE_VERIFIER
2259 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2260 unresolved_class *uc = iptr->sx.s23.s2.uc;
2262 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2264 #endif /* ENABLE_VERIFIER */
2265 goto nowperformreturn;
2267 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2270 REPLACEMENT_POINT_RETURN(cd, iptr);
2272 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2273 M_DBLMOVE(s1, REG_FRESULT);
2274 goto nowperformreturn;
2276 case ICMD_RETURN: /* ... ==> ... */
2278 REPLACEMENT_POINT_RETURN(cd, iptr);
2284 p = cd->stackframesize;
2286 #if !defined(NDEBUG)
2287 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2288 emit_verbosecall_exit(jd);
2291 #if defined(ENABLE_THREADS)
2292 if (checksync && code_is_synchronized(code)) {
2293 /* XXX jit-c-call */
2294 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2295 M_ALD(REG_ITMP3, REG_PV, disp);
2297 /* we need to save fp return value (int saved by window) */
2299 switch (iptr->opc) {
2302 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2303 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2304 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2306 /* restore the fp return value */
2308 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2314 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2315 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2326 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2332 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2335 branch_target_t *table;
2337 table = iptr->dst.table;
2339 l = iptr->sx.s23.s2.tablelow;
2340 i = iptr->sx.s23.s3.tablehigh;
2342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2344 M_INTMOVE(s1, REG_ITMP1);
2346 else if (-l >= 4096 && -l <= 4095) {
2347 M_ADD_IMM(s1, -l, REG_ITMP1);
2350 ICONST(REG_ITMP2, l);
2351 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2354 i = i - l + 1; /* number of targets (>0) */
2360 M_CMP_IMM(REG_ITMP1, i - 1);
2363 ICONST(REG_ITMP2, i - 1);
2364 M_CMP(REG_ITMP1, REG_ITMP2);
2366 emit_bugt(cd, table[0].block); /* default target */
2368 /* build jump table top down and use address of lowest entry */
2373 dseg_add_target(cd, table->block);
2378 /* length of dataseg after last dseg_addtarget is used by load */
2380 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2381 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2382 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2383 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2388 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2391 lookup_target_t *lookup;
2393 lookup = iptr->dst.lookup;
2395 i = iptr->sx.s23.s2.lookupcount;
2397 MCODECHECK((i<<2)+8);
2398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2401 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2402 M_CMP_IMM(s1, lookup->value);
2404 ICONST(REG_ITMP2, lookup->value);
2405 M_CMP(s1, REG_ITMP2);
2407 emit_beq(cd, lookup->target.block);
2411 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2417 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2419 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2421 bte = iptr->sx.s23.s3.bte;
2424 /* XXX: builtin calling with stack arguments not implemented */
2425 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2427 s3 = md->paramcount;
2429 MCODECHECK((s3 << 1) + 64);
2431 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2433 /* copy float arguments according to ABI convention */
2435 int num_fltregargs = 0;
2436 int fltregarg_inswap[16];
2438 for (s3 = s3 - 1; s3 >= 0; s3--) {
2439 var = VAR(iptr->sx.s23.s2.args[s3]);
2441 if (IS_FLT_DBL_TYPE(var->type)) {
2442 if (!md->params[s3].inmemory) {
2443 s1 = s3; /*native flt args use argument index directly*/
2444 d = emit_load(jd, iptr, var, REG_FTMP1);
2447 fltregarg_inswap[num_fltregargs] = s1;
2449 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2458 /* move swapped float args to target regs */
2459 for (i = 0; i < num_fltregargs; i++) {
2460 s1 = fltregarg_inswap[i];
2461 M_DMOV(s1 + 16, s1);
2462 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2466 assert(md->argfltreguse == 0);
2471 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2472 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2473 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2474 case ICMD_INVOKEINTERFACE:
2476 REPLACEMENT_POINT_INVOKE(cd, iptr);
2478 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2480 um = iptr->sx.s23.s3.um;
2481 md = um->methodref->parseddesc.md;
2484 lm = iptr->sx.s23.s3.fmiref->p.method;
2486 md = lm->parseddesc;
2490 s3 = md->paramcount;
2492 MCODECHECK((s3 << 1) + 64);
2494 /* copy arguments to registers or stack location */
2496 for (s3 = s3 - 1; s3 >= 0; s3--) {
2497 var = VAR(iptr->sx.s23.s2.args[s3]);
2498 d = md->params[s3].regoff;
2500 if (var->flags & PREALLOC)
2503 if (IS_INT_LNG_TYPE(var->type)) {
2504 if (!md->params[s3].inmemory) {
2505 s1 = emit_load(jd, iptr, var, d);
2509 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2510 M_STX(s1, REG_SP, JITSTACK + d);
2514 #ifdef BUILTIN_FLOAT_ARGS
2515 if (iptr->opc == ICMD_BUILTIN)
2519 if (!md->params[s3].inmemory) {
2520 s1 = emit_load(jd, iptr, var, d);
2521 if (IS_2_WORD_TYPE(var->type))
2527 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2528 M_DST(s1, REG_SP, JITSTACK + d);
2533 switch (iptr->opc) {
2535 if (bte->stub == NULL) {
2536 disp = dseg_add_functionptr(cd, bte->fp);
2539 disp = dseg_add_functionptr(cd, bte->stub);
2542 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2544 /* XXX jit-c-call */
2545 /* generate the actual call */
2547 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2549 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2550 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2551 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2552 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2553 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2555 if (md->returntype.type == TYPE_FLT) {
2556 /* special handling for float return value in %f0 */
2561 case ICMD_INVOKESPECIAL:
2562 emit_nullpointer_check(cd, iptr, REG_OUT0);
2565 case ICMD_INVOKESTATIC:
2567 disp = dseg_add_unique_address(cd, NULL);
2569 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2573 disp = dseg_add_address(cd, lm->stubroutine);
2575 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2577 /* generate the actual call */
2579 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2581 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2582 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2583 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2584 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2587 case ICMD_INVOKEVIRTUAL:
2588 emit_nullpointer_check(cd, iptr, REG_OUT0);
2591 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2596 s1 = OFFSET(vftbl_t, table[0]) +
2597 sizeof(methodptr) * lm->vftblindex;
2599 /* implicit null-pointer check */
2600 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_object_t, vftbl));
2601 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2603 /* generate the actual call */
2605 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2607 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2608 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2609 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2610 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2613 case ICMD_INVOKEINTERFACE:
2614 emit_nullpointer_check(cd, iptr, REG_OUT0);
2617 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2623 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2624 sizeof(methodptr*) * lm->class->index;
2626 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2629 /* implicit null-pointer check */
2630 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_object_t, vftbl));
2631 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2632 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2634 /* generate the actual call */
2636 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2638 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2639 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2640 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2641 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2645 /* store return value */
2647 d = md->returntype.type;
2649 if (d != TYPE_VOID) {
2650 if (IS_INT_LNG_TYPE(d)) {
2651 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2652 M_INTMOVE(REG_RESULT_CALLER, s1);
2655 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2656 if (IS_2_WORD_TYPE(d)) {
2657 M_DBLMOVE(REG_FRESULT, s1);
2659 M_FLTMOVE(REG_FRESULT, s1);
2662 emit_store_dst(jd, iptr, s1);
2667 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2668 /* val.a: (classinfo*) superclass */
2670 /* superclass is an interface:
2672 * OK if ((sub == NULL) ||
2673 * (sub->vftbl->interfacetablelength > super->index) &&
2674 * (sub->vftbl->interfacetable[-super->index] != NULL));
2676 * superclass is a class:
2678 * OK if ((sub == NULL) || (0
2679 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2680 * super->vftbl->diffvall));
2683 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2687 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2692 super = iptr->sx.s23.s3.c.cls;
2693 superindex = super->index;
2696 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2697 CODEGEN_CRITICAL_SECTION_NEW;
2699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2701 /* if class is not resolved, check which code to call */
2703 if (super == NULL) {
2704 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2706 cr = iptr->sx.s23.s3.c.ref;
2707 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2709 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2712 M_ILD(REG_ITMP2, REG_PV, disp);
2713 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2714 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2717 /* interface checkcast code */
2719 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2720 if (super == NULL) {
2721 cr = iptr->sx.s23.s3.c.ref;
2723 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2727 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2730 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2731 M_ILD(REG_ITMP3, REG_ITMP2,
2732 OFFSET(vftbl_t, interfacetablelength));
2733 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2734 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2736 M_ALD(REG_ITMP3, REG_ITMP2,
2737 OFFSET(vftbl_t, interfacetable[0]) -
2738 superindex * sizeof(methodptr*));
2739 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2742 emit_label_br(cd, BRANCH_LABEL_4);
2744 emit_label(cd, BRANCH_LABEL_3);
2747 /* class checkcast code */
2749 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2750 if (super == NULL) {
2751 emit_label(cd, BRANCH_LABEL_2);
2753 cr = iptr->sx.s23.s3.c.ref;
2754 disp = dseg_add_unique_address(cd, NULL);
2756 codegen_add_patch_ref(cd,
2757 PATCHER_checkcast_instanceof_class,
2761 disp = dseg_add_address(cd, super->vftbl);
2763 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2766 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2767 M_ALD(REG_ITMP3, REG_PV, disp);
2769 CODEGEN_CRITICAL_SECTION_START;
2771 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2772 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2773 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2774 M_ALD(REG_ITMP3, REG_PV, disp);
2775 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2777 CODEGEN_CRITICAL_SECTION_END;
2780 M_CMP(REG_ITMP3, REG_ITMP2);
2781 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2784 emit_label(cd, BRANCH_LABEL_5);
2787 if (super == NULL) {
2788 emit_label(cd, BRANCH_LABEL_1);
2789 emit_label(cd, BRANCH_LABEL_4);
2792 d = codegen_reg_of_dst(jd, iptr, s1);
2795 /* array type cast-check */
2797 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2798 M_INTMOVE(s1, REG_OUT0);
2800 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2802 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2803 cr = iptr->sx.s23.s3.c.ref;
2804 disp = dseg_add_unique_address(cd, NULL);
2806 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2810 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2812 M_ALD(REG_OUT1, REG_PV, disp);
2813 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2814 M_ALD(REG_ITMP3, REG_PV, disp);
2815 /* XXX jit-c-call */
2816 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2820 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2822 d = codegen_reg_of_dst(jd, iptr, s1);
2826 emit_store_dst(jd, iptr, d);
2829 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2830 /* val.a: (classinfo*) superclass */
2832 /* superclass is an interface:
2834 * return (sub != NULL) &&
2835 * (sub->vftbl->interfacetablelength > super->index) &&
2836 * (sub->vftbl->interfacetable[-super->index] != NULL);
2838 * superclass is a class:
2840 * return ((sub != NULL) && (0
2841 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2842 * super->vftbl->diffvall));
2847 vftbl_t *supervftbl;
2850 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2856 super = iptr->sx.s23.s3.c.cls;
2857 superindex = super->index;
2858 supervftbl = super->vftbl;
2861 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2862 CODEGEN_CRITICAL_SECTION_NEW;
2864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2867 M_MOV(s1, REG_ITMP1);
2873 /* if class is not resolved, check which code to call */
2875 if (super == NULL) {
2876 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2878 cr = iptr->sx.s23.s3.c.ref;
2879 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2881 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2884 M_ILD(REG_ITMP3, REG_PV, disp);
2885 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2886 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2889 /* interface instanceof code */
2891 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2892 if (super == NULL) {
2893 cr = iptr->sx.s23.s3.c.ref;
2895 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2899 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2902 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2903 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2904 M_CMP_IMM(REG_ITMP3, superindex);
2907 M_ALD(REG_ITMP1, REG_ITMP1,
2908 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2909 superindex * sizeof(methodptr*)));
2910 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2913 emit_label_br(cd, BRANCH_LABEL_4);
2915 emit_label(cd, BRANCH_LABEL_3);
2918 /* class instanceof code */
2920 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2921 if (super == NULL) {
2922 emit_label(cd, BRANCH_LABEL_2);
2924 cr = iptr->sx.s23.s3.c.ref;
2925 disp = dseg_add_unique_address(cd, NULL);
2927 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2931 disp = dseg_add_address(cd, supervftbl);
2933 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2936 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2937 M_ALD(REG_ITMP2, REG_PV, disp);
2939 CODEGEN_CRITICAL_SECTION_START;
2941 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2942 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2943 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2945 CODEGEN_CRITICAL_SECTION_END;
2947 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2948 M_CMP(REG_ITMP1, REG_ITMP2);
2949 M_XCMOVULE_IMM(1, d);
2952 emit_label(cd, BRANCH_LABEL_5);
2955 if (super == NULL) {
2956 emit_label(cd, BRANCH_LABEL_1);
2957 emit_label(cd, BRANCH_LABEL_4);
2960 emit_store_dst(jd, iptr, d);
2964 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2966 /* check for negative sizes and copy sizes to stack if necessary */
2968 MCODECHECK((iptr->s1.argcount << 1) + 64);
2970 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2972 var = VAR(iptr->sx.s23.s2.args[s1]);
2974 /* copy SAVEDVAR sizes to stack */
2976 /* Already Preallocated? */
2978 if (!(var->flags & PREALLOC)) {
2979 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2980 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2984 /* arg 0 = dimension count */
2986 ICONST(REG_OUT0, iptr->s1.argcount);
2988 /* is patcher function set? */
2990 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2991 disp = dseg_add_unique_address(cd, 0);
2993 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2994 iptr->sx.s23.s3.c.ref,
2998 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3000 /* arg 1 = arraydescriptor */
3002 M_ALD(REG_OUT1, REG_PV, disp);
3004 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
3006 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
3008 /* XXX c abi call */
3009 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3010 M_ALD(REG_ITMP3, REG_PV, disp);
3011 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3014 /* check for exception before result assignment */
3016 emit_exception_check(cd, iptr);
3018 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
3019 M_INTMOVE(REG_RESULT_CALLER, d);
3020 emit_store_dst(jd, iptr, d);
3024 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3030 } /* for instruction */
3034 /* At the end of a basic block we may have to append some nops,
3035 because the patcher stub calling code might be longer than the
3036 actual instruction. So codepatching does not change the
3037 following block unintentionally. */
3039 if (cd->mcodeptr < cd->lastmcodeptr) {
3040 while (cd->mcodeptr < cd->lastmcodeptr) {
3045 } /* if (bptr -> flags >= BBREACHED) */
3046 } /* for basic block */
3048 dseg_createlinenumbertable(cd);
3050 /* generate stubs */
3052 emit_patcher_stubs(jd);
3054 /* everything's ok */
3060 /* codegen_emit_stub_compiler **************************************************
3062 Emits a stub routine which calls the compiler.
3064 *******************************************************************************/
3066 void codegen_emit_stub_compiler(jitdata *jd)
3071 /* get required compiler data */
3076 /* code for the stub */
3078 /* no window save yet, user caller's PV */
3079 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3080 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3081 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3086 /* codegen_emit_stub_builtin ***************************************************
3088 Creates a stub routine which calls a builtin function.
3090 *******************************************************************************/
3092 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
3101 /* get required compiler data */
3105 /* set some variables */
3108 /* calculate stack frame size */
3109 cd->stackframesize =
3113 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3114 4; /* 4 arguments or return value */
3117 /* keep stack 16-byte aligned (ABI requirement) */
3119 if (cd->stackframesize & 1)
3120 cd->stackframesize++;
3122 /* create method header */
3123 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3124 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3125 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3126 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3127 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3128 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3129 (void) dseg_addlinenumbertablesize(cd);
3130 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3133 /* generate stub code */
3134 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3136 #if defined(ENABLE_GC_CACAO)
3137 /* Save callee saved integer registers in stackframeinfo (GC may
3138 need to recover them during a collection). */
3140 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3141 OFFSET(stackframeinfo_t, intregs) + BIAS;
3143 for (i = 0; i < INT_SAV_CNT; i++)
3144 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3147 for (i = 0; i < md->paramcount; i++) {
3148 s1 = md->params[i].regoff;
3150 switch (md->paramtypes[i].type) {
3157 M_DST(s1, REG_SP, JITSTACK + i * 8);
3162 /* create dynamic stack info */
3164 M_AADD_IMM(REG_SP, BIAS + cd->stackframesize * 8, REG_OUT0); /* data sp*/
3165 M_MOV(REG_PV_CALLEE, REG_OUT1); /* PV */
3166 M_MOV(REG_FP, REG_OUT2); /* java sp */
3167 M_MOV(REG_RA_CALLEE, REG_OUT3); /* ra */
3169 disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
3170 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3171 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3172 M_NOP; /* XXX fill me! */
3175 /* builtins are allowed to have 5 arguments max */
3177 assert(md->paramcount <= 5);
3179 /* copy arguments into position */
3181 for (i = 0; i < md->paramcount; i++) {
3182 assert(!md->params[i].inmemory);
3184 s1 = md->params[i].regoff;
3186 switch (md->paramtypes[i].type) {
3190 M_MOV(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[i]), s1);
3194 M_DLD(s1, REG_SP, JITSTACK + i * 8);
3200 /* call the builtin function */
3202 disp = dseg_add_functionptr(cd, bte->fp);
3203 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp); /* load adress of builtin */
3204 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call builtin */
3205 M_NOP; /* delay slot */
3208 /* save return value */
3210 if (md->returntype.type != TYPE_VOID) {
3211 if (IS_INT_LNG_TYPE(md->returntype.type))
3212 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3214 M_DST(REG_FRESULT, REG_SP, CSTACK);
3218 /* remove native stackframe info */
3220 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3221 disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
3222 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3223 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3226 /* restore float return value, int return value already in our return reg */
3228 if (md->returntype.type != TYPE_VOID) {
3229 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3230 if (IS_2_WORD_TYPE(md->returntype.type))
3231 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3233 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3238 #if defined(ENABLE_GC_CACAO)
3239 /* Restore callee saved integer registers from stackframeinfo (GC
3240 might have modified them during a collection). */
3242 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3243 OFFSET(stackframeinfo_t, intregs) + BIAS;
3245 for (i = 0; i < INT_SAV_CNT; i++)
3246 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3250 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3257 /* codegen_emit_stub_native ****************************************************
3259 Emits a stub routine which calls a native method.
3261 *******************************************************************************/
3263 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3270 s4 i, j; /* count variables */
3273 s4 funcdisp; /* displacement of the function */
3274 s4 fltregarg_offset[FLT_ARG_CNT];
3276 /* get required compiler data */
3282 /* initialize variables */
3285 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3287 /* calculate stack frame size */
3289 cd->stackframesize =
3290 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3291 sizeof(localref_table) / SIZEOF_VOID_P +
3292 md->paramcount + /* for saving arguments over calls */
3293 nmd->memuse + /* nmd->memuse includes the (6) abi params */
3297 /* keep stack 16-byte aligned (ABI requirement) */
3299 if (cd->stackframesize & 1)
3300 cd->stackframesize++;
3302 /* create method header */
3304 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3305 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3306 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3307 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3308 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3309 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3310 (void) dseg_addlinenumbertablesize(cd);
3311 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3313 /* generate stub code */
3315 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3317 #if !defined(NDEBUG)
3318 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3319 emit_verbosecall_enter(jd);
3322 /* get function address (this must happen before the stackframeinfo) */
3324 funcdisp = dseg_add_functionptr(cd, f);
3327 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3329 /* save float argument registers */
3331 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3333 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3334 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3335 s1 = WINSAVE_CNT + nmd->memuse + j;
3336 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3337 fltregarg_offset[i] = s1; /* remember stack offset */
3342 /* prepare data structures for native function call */
3344 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3345 M_MOV(REG_PV_CALLEE, REG_OUT1);
3346 M_MOV(REG_FP, REG_OUT2); /* java sp */
3347 M_MOV(REG_RA_CALLEE, REG_OUT3);
3348 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3349 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3350 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3351 M_NOP; /* XXX fill me! */
3353 /* remember class argument */
3355 if (m->flags & ACC_STATIC)
3356 M_MOV(REG_RESULT_CALLER, REG_ITMP3);
3358 /* keep float arguments on stack */
3360 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3361 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3362 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3368 /* copy or spill arguments to new locations */
3370 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3371 t = md->paramtypes[i].type;
3373 if (IS_INT_LNG_TYPE(t)) {
3375 /* integral types */
3377 if (!md->params[i].inmemory) {
3378 s1 = md->params[i].regoff;
3379 /* s1 refers to the old window, transpose */
3380 s1 = REG_WINDOW_TRANSPOSE(s1);
3382 if (!nmd->params[j].inmemory) {
3383 s2 = nmd->params[j].regoff;
3386 /* nmd's regoff is relative to the start of the param array */
3387 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3388 M_AST(s1, REG_SP, s2);
3392 if (!nmd->params[j].inmemory) {
3393 /* JIT stack arg -> NAT reg arg */
3395 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3396 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3398 assert(false); /* path never taken */
3401 s1 = md->params[i].regoff + cd->stackframesize * 8;
3402 s2 = BIAS + WINSAVE_CNT * 8 + nmd->params[j].regoff;
3403 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1);
3404 M_AST(REG_ITMP1, REG_SP, s2);
3409 /* floating point types */
3411 if (!md->params[i].inmemory) {
3412 s1 = md->params[i].regoff;
3414 if (!nmd->params[j].inmemory) {
3416 /* no mapping to regs needed, native flt args use regoff */
3417 s2 = nmd->params[j].regoff;
3419 /* JIT float regs are still on the stack */
3420 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3423 /* not supposed to happen with 16 NAT flt args */
3426 s2 = nmd->params[j].regoff;
3427 if (IS_2_WORD_TYPE(t))
3428 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3430 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3436 s1 = md->params[i].regoff;
3438 if (!nmd->params[j].inmemory) {
3440 /* JIT stack -> NAT reg */
3442 s2 = nmd->params[j].regoff;
3443 M_DLD(s2, REG_FP, JITSTACK + s1);
3447 /* JIT stack -> NAT stack */
3449 s2 = WINSAVE_CNT * 8 + nmd->params[j].regoff;
3451 /* The FTMP register may already be loaded with args */
3452 /* we know $f0 is unused because of the env pointer */
3453 M_DLD(REG_F0, REG_FP, JITSTACK + s1);
3454 M_DST(REG_F0, REG_SP, BIAS + s2);
3461 /* put class into second argument register */
3463 if (m->flags & ACC_STATIC)
3464 M_MOV(REG_ITMP3, REG_OUT1);
3466 /* put env into first argument register */
3468 disp = dseg_add_address(cd, _Jv_env);
3469 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3471 /* do the native function call */
3473 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3474 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3475 M_NOP; /* delay slot */
3477 /* save return value */
3479 if (md->returntype.type != TYPE_VOID) {
3480 if (IS_INT_LNG_TYPE(md->returntype.type))
3481 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3483 M_DST(REG_FRESULT, REG_SP, CSTACK);
3486 /* Note: native functions return float values in %f0 (see ABI) */
3487 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3489 #if !defined(NDEBUG)
3490 /* But for the trace function we need to put a flt result into %f1 */
3491 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3492 if (!IS_2_WORD_TYPE(md->returntype.type))
3493 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3494 emit_verbosecall_exit(jd);
3498 /* remove native stackframe info */
3500 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3501 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3502 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3503 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3504 M_NOP; /* XXX fill me! */
3505 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3507 /* restore float return value, int return value already in our return reg */
3509 if (md->returntype.type != TYPE_VOID) {
3510 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3511 if (IS_2_WORD_TYPE(md->returntype.type))
3512 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3514 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3518 /* check for exception */
3519 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3522 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3525 /* handle exception */
3527 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3528 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3529 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3530 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3531 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3533 /* generate patcher stubs */
3535 emit_patcher_stubs(jd);
3539 * These are local overrides for various environment variables in Emacs.
3540 * Please do not remove this and leave it at the end of the file, where
3541 * Emacs will automagically detect them.
3542 * ---------------------------------------------------------------------
3545 * indent-tabs-mode: t
3549 * vim:noexpandtab:sw=4:ts=4: