1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
39 /* #include "vm/jit/sparc64/arch.h" */
40 #include "vm/jit/sparc64/codegen.h"
42 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
50 #include "vm/jit/abi.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/codegen-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/sparc64/emit.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/patcher.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
66 #define BUILTIN_FLOAT_ARGS 1
68 /* XXX use something like this for window control ?
69 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
71 #define REG_PV REG_PV_CALLEE
76 if ((disp < -4096) || (disp > 4095))
77 printf("disp %d\n", disp);
80 return (disp >= -4096) && (disp <= 4095);
83 s4 get_lopart_disp(disp)
88 lodisp = setlo_part(disp);
90 if (setlo_part(disp) == 0)
93 lodisp = setlo_part(disp) | 0x1c00;
100 /* codegen_emit ****************************************************************
102 Generates machine code.
104 *******************************************************************************/
106 bool codegen_emit(jitdata *jd)
112 s4 len, s1, s2, s3, d, disp;
118 constant_classref *cr;
119 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
120 unresolved_method *um;
121 builtintable_entry *bte;
124 unresolved_field *uf;
128 /* get required compiler data */
135 /* prevent compiler warnings */
144 s4 savedregs_num, localbase;
146 #if 0 /* no leaf optimization yet */
147 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
149 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
152 /* space to save used callee saved registers */
154 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
155 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
157 cd->stackframesize = rd->memuse + savedregs_num;
159 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 cd->stackframesize++;
164 /* keep stack 16-byte aligned (ABI requirement) */
166 if (cd->stackframesize & 1)
167 cd->stackframesize++;
169 /* create method header */
171 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
172 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
174 #if defined(ENABLE_THREADS)
175 /* IsSync contains the offset relative to the stack pointer for the
176 argument of monitor_exit used in the exception handler. Since the
177 offset could be zero and give a wrong meaning of the flag it is
181 if (checksync && (m->flags & ACC_SYNCHRONIZED))
182 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
185 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
187 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
188 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
189 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
190 dseg_addlinenumbertablesize(cd);
191 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
193 /* create exception table */
195 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
196 dseg_add_target(cd, ex->start);
197 dseg_add_target(cd, ex->end);
198 dseg_add_target(cd, ex->handler);
199 (void) dseg_add_unique_address(cd, ex->catchtype.any);
202 /* save register window and create stack frame (if necessary) */
204 if (cd->stackframesize)
205 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
208 /* save callee saved float registers (none right now) */
210 p = cd->stackframesize;
211 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
212 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
217 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
218 emit_verbosecall_enter(jd);
223 /* take arguments out of register or stack frame */
227 /* when storing locals, use this as base */
228 localbase = JITSTACK;
230 /* since the register allocator does not know about the shifting window
231 * arg regs need to be copied via the stack
233 if (md->argintreguse > 0) {
234 /* allocate scratch space for copying in to save(i&l) regs */
235 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
237 localbase += INT_ARG_CNT * 8;
239 /* XXX could use the param slots on the stack for this! */
240 for (p = 0; p < INT_ARG_CNT; p++)
241 M_STX(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[p]), REG_SP, JITSTACK + (p * 8));
245 for (p = 0, l = 0; p < md->paramcount; p++) {
246 t = md->paramtypes[p].type;
248 varindex = jd->local_map[l * 5 + t];
251 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
254 if (varindex == UNUSED)
258 s1 = md->params[p].regoff;
260 if (IS_INT_LNG_TYPE(t)) { /* integer args */
262 if (!md->params[p].inmemory) { /* register arguments */
263 /*s2 = rd->argintregs[s1];*/
264 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
266 /* need the argument index (p) here, not the register number */
268 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
269 /*M_INTMOVE(s2, var->vv.regoff);*/
270 M_LDX(var->vv.regoff, REG_SP, JITSTACK + (p * 8));
272 } else { /* reg arg -> spilled */
273 /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
275 M_LDX(REG_ITMP1, REG_SP, JITSTACK + (p * 8));
276 M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
279 } else { /* stack arguments */
280 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
281 M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
283 } else { /* stack arg -> spilled */
284 /* add the callers window save registers */
285 var->vv.regoff = cd->stackframesize + s1;
289 } else { /* floating args */
290 if (!md->params[p].inmemory) { /* register arguments */
291 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
292 M_FLTMOVE(s1, var->vv.regoff);
294 } else { /* reg arg -> spilled */
295 M_DST(s1, REG_SP, localbase + (var->vv.regoff) * 8);
298 } else { /* stack arguments */
299 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
300 M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
302 } else { /* stack-arg -> spilled */
303 var->vv.regoff = cd->stackframesize + s1;
309 if (md->argintreguse > 0) {
310 /* release scratch space */
311 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
315 /* XXX monitor enter */
322 /* end of header generation */
324 /* create replacement points */
326 REPLACEMENT_POINTS_INIT(cd, jd);
328 /* walk through all basic blocks */
330 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
332 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
334 if (bptr->flags >= BBREACHED) {
336 /* branch resolving */
338 codegen_resolve_branchrefs(cd, bptr);
340 /* handle replacement points */
343 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
344 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
350 /* copy interface registers to their destination */
355 #if defined(ENABLE_LSRA)
356 #error XXX LSRA not tested yet
360 src = bptr->invars[len];
361 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
362 /* d = reg_of_var(m, src, REG_ITMP1); */
363 if (!(src->flags & INMEMORY))
367 M_INTMOVE(REG_ITMP1, d);
368 emit_store(jd, NULL, src, d);
375 var = VAR(bptr->invars[len]);
376 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
377 d = codegen_reg_of_var(0, var, REG_ITMP1);
378 M_INTMOVE(REG_ITMP2_XPTR, d);
379 emit_store(jd, NULL, var, d);
382 assert((var->flags & INOUT));
385 #if defined(ENABLE_LSRA)
388 /* walk through all instructions */
392 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
393 if (iptr->line != currentline) {
394 dseg_addlinenumber(cd, iptr->line);
395 currentline = iptr->line;
398 MCODECHECK(64); /* an instruction usually needs < 64 words */
402 case ICMD_INLINE_START:
403 case ICMD_INLINE_END:
406 case ICMD_NOP: /* ... ==> ... */
409 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
412 emit_nullpointer_check(cd, iptr, s1);
415 /* constant operations ************************************************/
417 case ICMD_ICONST: /* ... ==> ..., constant */
419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
420 ICONST(d, iptr->sx.val.i);
421 emit_store_dst(jd, iptr, d);
424 case ICMD_LCONST: /* ... ==> ..., constant */
426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
427 LCONST(d, iptr->sx.val.l);
428 emit_store_dst(jd, iptr, d);
431 case ICMD_FCONST: /* ... ==> ..., constant */
433 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
434 disp = dseg_add_float(cd, iptr->sx.val.f);
435 M_FLD(d, REG_PV, disp);
436 emit_store_dst(jd, iptr, d);
439 case ICMD_DCONST: /* ... ==> ..., constant */
441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
442 disp = dseg_add_double(cd, iptr->sx.val.d);
443 M_DLD(d, REG_PV, disp);
444 emit_store_dst(jd, iptr, d);
447 case ICMD_ACONST: /* ... ==> ..., constant */
449 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
451 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
452 cr = iptr->sx.val.c.ref;
453 disp = dseg_add_unique_address(cd, cr);
455 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
457 M_ALD(d, REG_PV, disp);
461 if (iptr->sx.val.anyptr == NULL) {
462 M_INTMOVE(REG_ZERO, d);
465 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
466 M_ALD(d, REG_PV, disp);
469 emit_store_dst(jd, iptr, d);
473 /* load/store/copy/move operations ************************************/
475 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
480 case ICMD_ISTORE: /* ..., value ==> ... */
491 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
496 /* pop/dup/swap operations ********************************************/
498 /* attention: double and longs are only one entry in CACAO ICMDs */
500 case ICMD_POP: /* ..., value ==> ... */
501 case ICMD_POP2: /* ..., value, value ==> ... */
505 /* integer operations *************************************************/
507 case ICMD_INEG: /* ..., value ==> ..., - value */
510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
512 M_SUB(REG_ZERO, s1, d);
513 emit_store_dst(jd, iptr, d);
516 case ICMD_I2L: /* ..., value ==> ..., value */
518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_L2I: /* ..., value ==> ..., value */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
529 emit_store_dst(jd, iptr, d);
532 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536 M_SLLX_IMM(s1, 56, d);
537 M_SRAX_IMM( d, 56, d);
538 emit_store_dst(jd, iptr, d);
541 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
545 M_SLLX_IMM(s1, 48, d);
546 M_SRLX_IMM( d, 48, d);
547 emit_store_dst(jd, iptr, d);
550 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
554 M_SLLX_IMM(s1, 48, d);
555 M_SRAX_IMM( d, 48, d);
556 emit_store_dst(jd, iptr, d);
559 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 emit_store_dst(jd, iptr, d);
570 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
571 /* sx.val.i = constant */
573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
575 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
576 M_ADD_IMM(s1, iptr->sx.val.i, d);
578 ICONST(REG_ITMP2, iptr->sx.val.i);
579 M_ADD(s1, REG_ITMP2, d);
581 emit_store_dst(jd, iptr, d);
584 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
585 /* sx.val.l = constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
590 M_ADD_IMM(s1, iptr->sx.val.l, d);
592 LCONST(REG_ITMP2, iptr->sx.val.l);
593 M_ADD(s1, REG_ITMP2, d);
595 emit_store_dst(jd, iptr, d);
598 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 emit_store_dst(jd, iptr, d);
608 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
609 /* sx.val.i = constant */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
613 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
614 M_SUB_IMM(s1, iptr->sx.val.i, d);
616 ICONST(REG_ITMP2, iptr->sx.val.i);
617 M_SUB(s1, REG_ITMP2, d);
619 emit_store_dst(jd, iptr, d);
622 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
623 /* sx.val.l = constant */
625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
628 M_SUB_IMM(s1, iptr->sx.val.l, d);
630 LCONST(REG_ITMP2, iptr->sx.val.l);
631 M_SUB(s1, REG_ITMP2, d);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
643 emit_store_dst(jd, iptr, d);
646 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
647 /* sx.val.i = constant */
649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
650 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
651 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
652 M_MULX_IMM(s1, iptr->sx.val.i, d);
654 ICONST(REG_ITMP2, iptr->sx.val.i);
655 M_MULX(s1, REG_ITMP2, d);
657 emit_store_dst(jd, iptr, d);
660 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
661 /* sx.val.l = constant */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
665 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
666 M_MULX_IMM(s1, iptr->sx.val.l, d);
668 LCONST(REG_ITMP2, iptr->sx.val.l);
669 M_MULX(s1, REG_ITMP2, d);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
675 /* XXX could also clear Y and use 32bit div */
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);
679 emit_arithmetic_check(cd, iptr, s2);
681 /* XXX trim s2 like s1 ? */
683 emit_store_dst(jd, iptr, d);
686 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
691 emit_arithmetic_check(cd, iptr, s2);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
701 emit_arithmetic_check(cd, iptr, s2);
703 /* XXX trim s2 like s1 ? */
704 M_DIVX(s1, s2, REG_ITMP3);
705 M_MULX(s2, REG_ITMP3, REG_ITMP3);
706 M_SUB(s1, REG_ITMP3, d);
707 emit_store_dst(jd, iptr, d);
710 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
715 emit_arithmetic_check(cd, iptr, s2);
716 M_DIVX(s1, s2, REG_ITMP3);
717 M_MULX(s2, REG_ITMP3, REG_ITMP3);
718 M_SUB(s1, REG_ITMP3, d);
719 emit_store_dst(jd, iptr, d);
722 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
723 case ICMD_LDIVPOW2: /* val.i = constant */
725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
727 M_SRAX_IMM(s1, 63, REG_ITMP2);
728 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
729 M_ADD(s1, REG_ITMP2, REG_ITMP2);
730 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
731 emit_store_dst(jd, iptr, d);
734 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
737 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
740 emit_store_dst(jd, iptr, d);
743 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
746 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
747 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
749 emit_store_dst(jd, iptr, d);
752 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
753 /* val.i = constant */
755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
757 M_SLL_IMM(s1, iptr->sx.val.i, d);
758 emit_store_dst(jd, iptr, d);
761 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
762 /* val.i = constant */
764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766 M_SLLX_IMM(s1, iptr->sx.val.i, d);
767 emit_store_dst(jd, iptr, d);
770 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
776 emit_store_dst(jd, iptr, d);
779 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
780 /* sx.val.i = constant */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
784 M_SRA_IMM(s1, iptr->sx.val.i, d);
785 emit_store_dst(jd, iptr, d);
788 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
798 /* sx.val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_SRL_IMM(s1, iptr->sx.val.i, d);
803 emit_store_dst(jd, iptr, d);
806 case ICMD_LSHR: /* ..., 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_LSHRCONST: /* ..., value ==> ..., value >> constant */
816 /* sx.val.i = constant */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
820 M_SRAX_IMM(s1, iptr->sx.val.i, d);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
834 /* sx.val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
838 M_SRLX_IMM(s1, iptr->sx.val.i, d);
839 emit_store_dst(jd, iptr, d);
842 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
849 emit_store_dst(jd, iptr, d);
852 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
853 /* sx.val.i = constant */
855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
856 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
857 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
858 M_AND_IMM(s1, iptr->sx.val.i, d);
860 ICONST(REG_ITMP2, iptr->sx.val.i);
861 M_AND(s1, REG_ITMP2, d);
863 emit_store_dst(jd, iptr, d);
866 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
867 /* sx.val.i = constant */
868 /* constant is actually constant - 1 */
870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
873 M_MOV(s1, REG_ITMP1);
876 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
877 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
878 M_AND_IMM(s1, iptr->sx.val.i, d);
881 M_SUB(REG_ZERO, s1, d);
882 M_AND_IMM(d, iptr->sx.val.i, d);
884 ICONST(REG_ITMP2, iptr->sx.val.i);
885 M_AND(s1, REG_ITMP2, d);
888 M_SUB(REG_ZERO, s1, d);
889 M_AND(d, REG_ITMP2, d);
891 M_SUB(REG_ZERO, d, d);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
896 /* sx.val.l = constant */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
901 M_AND_IMM(s1, iptr->sx.val.l, d);
903 LCONST(REG_ITMP2, iptr->sx.val.l);
904 M_AND(s1, REG_ITMP2, d);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
910 /* sx.val.l = constant */
912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 M_MOV(s1, REG_ITMP1);
918 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
919 M_AND_IMM(s1, iptr->sx.val.l, d);
922 M_SUB(REG_ZERO, s1, d);
923 M_AND_IMM(d, iptr->sx.val.l, d);
925 LCONST(REG_ITMP2, iptr->sx.val.l);
926 M_AND(s1, REG_ITMP2, d);
929 M_SUB(REG_ZERO, s1, d);
930 M_AND(d, REG_ITMP2, d);
932 M_SUB(REG_ZERO, d, d);
933 emit_store_dst(jd, iptr, d);
936 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
940 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
947 /* sx.val.i = constant */
949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
952 M_OR_IMM(s1, iptr->sx.val.i, d);
954 ICONST(REG_ITMP2, iptr->sx.val.i);
955 M_OR(s1, REG_ITMP2, d);
957 emit_store_dst(jd, iptr, d);
960 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
961 /* sx.val.l = constant */
963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
964 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
965 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
966 M_OR_IMM(s1, iptr->sx.val.l, d);
968 LCONST(REG_ITMP2, iptr->sx.val.l);
969 M_OR(s1, REG_ITMP2, d);
971 emit_store_dst(jd, iptr, d);
974 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
978 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
979 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
985 /* sx.val.i = constant */
987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
989 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
990 M_XOR_IMM(s1, iptr->sx.val.i, d);
992 ICONST(REG_ITMP2, iptr->sx.val.i);
993 M_XOR(s1, REG_ITMP2, d);
995 emit_store_dst(jd, iptr, d);
998 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
999 /* sx.val.l = constant */
1001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1004 M_XOR_IMM(s1, iptr->sx.val.l, d);
1006 LCONST(REG_ITMP2, iptr->sx.val.l);
1007 M_XOR(s1, REG_ITMP2, d);
1009 emit_store_dst(jd, iptr, d);
1013 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1016 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1017 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1020 M_XCMOVLT_IMM(-1, d);
1021 M_XCMOVGT_IMM(1, d);
1022 emit_store_dst(jd, iptr, d);
1026 /* floating operations ************************************************/
1028 case ICMD_FNEG: /* ..., value ==> ..., - value */
1030 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1031 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_DNEG: /* ..., value ==> ..., - value */
1038 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1039 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1046 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1047 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1048 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1050 emit_store_dst(jd, iptr, d);
1053 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1055 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1056 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1057 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1064 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1065 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1066 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1068 emit_store_dst(jd, iptr, d);
1071 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1073 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1074 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1075 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1077 emit_store_dst(jd, iptr, d);
1080 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1082 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1083 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1084 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1091 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1092 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1093 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1100 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1101 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1102 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1109 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1113 emit_store_dst(jd, iptr, d);
1117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1119 disp = dseg_add_unique_float(cd, 0.0);
1120 M_IST (s1, REG_PV_CALLEE, disp);
1121 M_FLD (d, REG_PV_CALLEE, disp);
1122 M_CVTIF (d, d); /* rd gets translated to double target register */
1123 emit_store_dst(jd, iptr, d);
1127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1128 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1129 disp = dseg_add_unique_float(cd, 0.0);
1130 M_IST(s1, REG_PV_CALLEE, disp);
1131 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1132 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1133 emit_store_dst(jd, iptr, d);
1137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1139 disp = dseg_add_unique_double(cd, 0.0);
1140 M_STX(s1, REG_PV_CALLEE, disp);
1141 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1142 M_CVTLF(REG_FTMP3, d);
1143 emit_store_dst(jd, iptr, d);
1147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1148 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1149 disp = dseg_add_unique_double(cd, 0.0);
1150 M_STX(s1, REG_PV_CALLEE, disp);
1151 M_DLD(d, REG_PV_CALLEE, disp);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1159 disp = dseg_add_unique_float(cd, 0.0);
1161 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1164 M_MOV(REG_ZERO, d); /* delay slot */
1166 M_CVTFI(s1, REG_FTMP2);
1167 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1168 M_ILD(d, REG_PV, disp);
1169 emit_store_dst(jd, iptr, d);
1173 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1174 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1175 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1176 disp = dseg_add_unique_float(cd, 0.0);
1178 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1181 M_MOV(REG_ZERO, d); /* delay slot */
1183 M_CVTDI(s1, REG_FTMP2);
1184 M_FST(REG_FTMP2, REG_PV, disp);
1185 M_ILD(d, REG_PV, disp);
1186 emit_store_dst(jd, iptr, d);
1189 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1190 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1191 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1192 disp = dseg_add_unique_double(cd, 0.0);
1194 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1197 M_MOV(REG_ZERO, d); /* delay slot */
1199 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1200 M_DST(REG_FTMP2, REG_PV, disp);
1201 M_LDX(d, REG_PV, disp);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1207 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1208 disp = dseg_add_unique_double(cd, 0.0);
1210 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1213 M_MOV(REG_ZERO, d); /* delay slot */
1215 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1216 M_DST(REG_FTMP2, REG_PV, disp);
1217 M_LDX(d, REG_PV, disp);
1218 emit_store_dst(jd, iptr, d);
1221 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1223 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1224 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1231 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1232 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1234 emit_store_dst(jd, iptr, d);
1237 /* XXX merge F/D versions? only compare instr. is different */
1238 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1240 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1241 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1244 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1245 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1246 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1247 emit_store_dst(jd, iptr, d);
1250 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1252 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1253 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1254 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1256 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1257 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1258 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1264 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1265 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1268 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1269 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1270 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1271 emit_store_dst(jd, iptr, d);
1274 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1276 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1277 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1280 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1281 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1282 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1283 emit_store_dst(jd, iptr, d);
1287 /* memory operations **************************************************/
1289 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1293 emit_nullpointer_check(cd, iptr, s1);
1294 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1301 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1303 /* implicit null-pointer check */
1304 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1305 M_AADD(s2, s1, REG_ITMP3);
1306 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1313 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1314 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1315 /* implicit null-pointer check */
1316 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1317 M_AADD(s2, s1, REG_ITMP3);
1318 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1319 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1326 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1328 /* implicit null-pointer check */
1329 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1330 M_AADD(s2, s1, REG_ITMP3);
1331 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1332 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1341 /* implicit null-pointer check */
1342 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1343 M_ASLL_IMM(s2, 2, REG_ITMP3);
1344 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1345 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1354 /* implicit null-pointer check */
1355 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1356 M_ASLL_IMM(s2, 3, REG_ITMP3);
1357 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1358 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1367 /* implicit null-pointer check */
1368 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369 M_ASLL_IMM(s2, 2, REG_ITMP3);
1370 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1371 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1372 emit_store_dst(jd, iptr, d);
1375 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1377 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1378 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1379 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1380 /* implicit null-pointer check */
1381 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1382 M_ASLL_IMM(s2, 3, REG_ITMP3);
1383 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1384 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1385 emit_store_dst(jd, iptr, d);
1388 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1391 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1392 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1393 /* implicit null-pointer check */
1394 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1395 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1396 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1397 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1398 emit_store_dst(jd, iptr, d);
1402 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1405 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1406 /* implicit null-pointer check */
1407 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1408 M_AADD(s2, s1, REG_ITMP1);
1409 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1410 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1413 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1414 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1417 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1418 /* implicit null-pointer check */
1419 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1420 M_AADD(s2, s1, REG_ITMP1);
1421 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1422 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1423 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1426 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 /* implicit null-pointer check */
1431 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1432 M_ASLL_IMM(s2, 2, REG_ITMP2);
1433 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1434 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1435 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1438 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1440 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1441 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1442 /* implicit null-pointer check */
1443 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1444 M_ASLL_IMM(s2, 3, REG_ITMP2);
1445 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1446 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1447 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1450 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1452 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1454 /* implicit null-pointer check */
1455 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1456 M_ASLL_IMM(s2, 2, REG_ITMP2);
1457 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1458 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1459 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1462 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1464 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1465 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1466 /* implicit null-pointer check */
1467 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1468 M_ASLL_IMM(s2, 3, REG_ITMP2);
1469 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1470 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1471 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1475 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1478 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1479 /* implicit null-pointer check */
1480 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1481 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1483 M_MOV(s1, REG_OUT0);
1484 M_MOV(s3, REG_OUT1);
1485 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1486 M_ALD(REG_ITMP3, REG_PV, disp);
1487 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1489 emit_exception_check(cd, iptr);
1491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1493 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1494 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1495 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1496 /* implicit null-pointer check */
1497 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1501 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
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_AADD(s2, s1, REG_ITMP1);
1508 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1511 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1512 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1515 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1516 /* implicit null-pointer check */
1517 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1518 M_AADD(s2, s1, REG_ITMP1);
1519 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1520 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1523 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527 /* implicit null-pointer check */
1528 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1529 M_ASLL_IMM(s2, 2, REG_ITMP2);
1530 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1531 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1534 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
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 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1545 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1548 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1549 /* implicit null-pointer check */
1550 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1551 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1552 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1553 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1557 case ICMD_GETSTATIC: /* ... ==> ..., value */
1559 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1560 uf = iptr->sx.s23.s3.uf;
1561 fieldtype = uf->fieldref->parseddesc.fd->type;
1562 disp = dseg_add_unique_address(cd, uf);
1564 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1567 fi = iptr->sx.s23.s3.fmiref->p.field;
1568 fieldtype = fi->type;
1569 disp = dseg_add_address(cd, &(fi->value));
1571 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1572 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1575 M_ALD(REG_ITMP1, REG_PV, disp);
1577 switch (fieldtype) {
1579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1580 M_ILD_INTERN(d, REG_ITMP1, 0);
1583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1584 M_LDX_INTERN(d, REG_ITMP1, 0);
1587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1588 M_ALD_INTERN(d, REG_ITMP1, 0);
1591 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1592 M_FLD_INTERN(d, REG_ITMP1, 0);
1595 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1596 M_DLD_INTERN(d, REG_ITMP1, 0);
1599 emit_store_dst(jd, iptr, d);
1602 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1604 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1605 uf = iptr->sx.s23.s3.uf;
1606 fieldtype = uf->fieldref->parseddesc.fd->type;
1607 disp = dseg_add_unique_address(cd, uf);
1609 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1612 fi = iptr->sx.s23.s3.fmiref->p.field;
1613 fieldtype = fi->type;
1614 disp = dseg_add_address(cd, &(fi->value));
1616 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1617 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1620 M_ALD(REG_ITMP1, REG_PV, disp);
1622 switch (fieldtype) {
1624 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1625 M_IST_INTERN(s1, REG_ITMP1, 0);
1628 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1629 M_STX_INTERN(s1, REG_ITMP1, 0);
1632 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1633 M_AST_INTERN(s1, REG_ITMP1, 0);
1636 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1637 M_FST_INTERN(s1, REG_ITMP1, 0);
1640 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1641 M_DST_INTERN(s1, REG_ITMP1, 0);
1646 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1647 /* val = value (in current instruction) */
1648 /* following NOP) */
1650 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1651 uf = iptr->sx.s23.s3.uf;
1652 fieldtype = uf->fieldref->parseddesc.fd->type;
1653 disp = dseg_add_unique_address(cd, uf);
1655 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1658 fi = iptr->sx.s23.s3.fmiref->p.field;
1659 fieldtype = fi->type;
1660 disp = dseg_add_address(cd, &(fi->value));
1662 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1663 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1666 M_ALD(REG_ITMP1, REG_PV, disp);
1668 switch (fieldtype) {
1670 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1673 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1676 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1679 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1682 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1688 case ICMD_GETFIELD: /* ... ==> ..., value */
1690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691 emit_nullpointer_check(cd, iptr, s1);
1693 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1694 uf = iptr->sx.s23.s3.uf;
1696 fieldtype = uf->fieldref->parseddesc.fd->type;
1699 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1702 fi = iptr->sx.s23.s3.fmiref->p.field;
1703 fieldtype = fi->type;
1707 switch (fieldtype) {
1709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1717 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1721 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1725 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1732 emit_store_dst(jd, iptr, d);
1735 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1738 emit_nullpointer_check(cd, iptr, s1);
1740 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1741 uf = iptr->sx.s23.s3.uf;
1742 fieldtype = uf->fieldref->parseddesc.fd->type;
1747 fi = iptr->sx.s23.s3.fmiref->p.field;
1748 fieldtype = fi->type;
1752 if (IS_INT_LNG_TYPE(fieldtype))
1753 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1755 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1757 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1758 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1760 switch (fieldtype) {
1762 M_IST(s2, s1, disp);
1765 M_STX(s2, s1, disp);
1768 M_AST(s2, s1, disp);
1771 M_FST(s2, s1, disp);
1774 M_DST(s2, s1, disp);
1782 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1783 /* val = value (in current instruction) */
1784 /* following NOP) */
1786 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1787 emit_nullpointer_check(cd, iptr, s1);
1789 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1790 unresolved_field *uf = iptr->sx.s23.s3.uf;
1792 fieldtype = uf->fieldref->parseddesc.fd->type;
1794 codegen_addpatchref(cd, PATCHER_get_putfield,
1797 if (opt_showdisassemble) {
1805 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1807 fieldtype = fi->type;
1813 switch (fieldtype) {
1815 M_IST(REG_ZERO, s1, disp);
1818 M_STX(REG_ZERO, s1, disp);
1821 M_AST(REG_ZERO, s1, disp);
1824 M_FST(REG_ZERO, s1, disp);
1827 M_DST(REG_ZERO, s1, disp);
1833 /* branch operations **************************************************/
1835 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1838 M_INTMOVE(s1, REG_ITMP2_XPTR);
1840 #ifdef ENABLE_VERIFIER
1841 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1842 unresolved_class *uc = iptr->sx.s23.s2.uc;
1844 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1846 #endif /* ENABLE_VERIFIER */
1848 disp = dseg_add_functionptr(cd, asm_handle_exception);
1849 M_ALD(REG_ITMP1, REG_PV, disp);
1850 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1852 M_NOP; /* nop ensures that XPC is less than the end */
1853 /* of basic block */
1857 case ICMD_GOTO: /* ... ==> ... */
1858 case ICMD_RET: /* ... ==> ... */
1860 emit_br(cd, iptr->dst.block);
1864 case ICMD_JSR: /* ... ==> ... */
1866 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1870 case ICMD_IFNULL: /* ..., value ==> ... */
1871 case ICMD_IFNONNULL:
1873 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1874 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1877 /* Note: int compares must not branch on the register directly. */
1878 /* Reason is, that register content is not 32-bit clean. */
1880 case ICMD_IFEQ: /* ..., value ==> ... */
1882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1884 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1885 M_CMP_IMM(s1, iptr->sx.val.i);
1888 ICONST(REG_ITMP2, iptr->sx.val.i);
1889 M_CMP(s1, REG_ITMP2);
1891 emit_beq(cd, iptr->dst.block);
1894 case ICMD_IFLT: /* ..., value ==> ... */
1896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1898 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1899 M_CMP_IMM(s1, iptr->sx.val.i);
1902 ICONST(REG_ITMP2, iptr->sx.val.i);
1903 M_CMP(s1, REG_ITMP2);
1905 emit_blt(cd, iptr->dst.block);
1908 case ICMD_IFLE: /* ..., value ==> ... */
1910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1912 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1913 M_CMP_IMM(s1, iptr->sx.val.i);
1916 ICONST(REG_ITMP2, iptr->sx.val.i);
1917 M_CMP(s1, REG_ITMP2);
1919 emit_ble(cd, iptr->dst.block);
1922 case ICMD_IFNE: /* ..., value ==> ... */
1924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1926 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1927 M_CMP_IMM(s1, iptr->sx.val.i);
1930 ICONST(REG_ITMP2, iptr->sx.val.i);
1931 M_CMP(s1, REG_ITMP2);
1933 emit_bne(cd, iptr->dst.block);
1936 case ICMD_IFGT: /* ..., value ==> ... */
1938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1940 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1941 M_CMP_IMM(s1, iptr->sx.val.i);
1944 ICONST(REG_ITMP2, iptr->sx.val.i);
1945 M_CMP(s1, REG_ITMP2);
1947 emit_bgt(cd, iptr->dst.block);
1950 case ICMD_IFGE: /* ..., value ==> ... */
1952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1954 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1955 M_CMP_IMM(s1, iptr->sx.val.i);
1958 ICONST(REG_ITMP2, iptr->sx.val.i);
1959 M_CMP(s1, REG_ITMP2);
1961 emit_bge(cd, iptr->dst.block);
1964 case ICMD_IF_LEQ: /* ..., value ==> ... */
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967 if (iptr->sx.val.l == 0)
1968 emit_beqz(cd, iptr->dst.block, s1);
1970 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1971 M_CMP_IMM(s1, iptr->sx.val.l);
1974 LCONST(REG_ITMP2, iptr->sx.val.l);
1975 M_CMP(s1, REG_ITMP2);
1977 emit_beq_xcc(cd, iptr->dst.block);
1981 case ICMD_IF_LLT: /* ..., value ==> ... */
1983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1984 if (iptr->sx.val.l == 0)
1985 emit_bltz(cd, iptr->dst.block, s1);
1987 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1988 M_CMP_IMM(s1, iptr->sx.val.l);
1991 LCONST(REG_ITMP2, iptr->sx.val.l);
1992 M_CMP(s1, REG_ITMP2);
1994 emit_blt_xcc(cd, iptr->dst.block);
1998 case ICMD_IF_LLE: /* ..., value ==> ... */
2000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2001 if (iptr->sx.val.l == 0)
2002 emit_blez(cd, iptr->dst.block, s1);
2004 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2005 M_CMP_IMM(s1, iptr->sx.val.l);
2008 LCONST(REG_ITMP2, iptr->sx.val.l);
2009 M_CMP(s1, REG_ITMP2);
2011 emit_ble_xcc(cd, iptr->dst.block);
2015 case ICMD_IF_LNE: /* ..., value ==> ... */
2017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2018 if (iptr->sx.val.l == 0)
2019 emit_bnez(cd, iptr->dst.block, s1);
2021 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2022 M_CMP_IMM(s1, iptr->sx.val.l);
2025 LCONST(REG_ITMP2, iptr->sx.val.l);
2026 M_CMP(s1, REG_ITMP2);
2028 emit_bne_xcc(cd, iptr->dst.block);
2032 case ICMD_IF_LGT: /* ..., value ==> ... */
2034 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2035 if (iptr->sx.val.l == 0)
2036 emit_bgtz(cd, iptr->dst.block, s1);
2038 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2039 M_CMP_IMM(s1, iptr->sx.val.l);
2042 LCONST(REG_ITMP2, iptr->sx.val.l);
2043 M_CMP(s1, REG_ITMP2);
2045 emit_bgt_xcc(cd, iptr->dst.block);
2049 case ICMD_IF_LGE: /* ..., value ==> ... */
2051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052 if (iptr->sx.val.l == 0)
2053 emit_bgez(cd, iptr->dst.block, s1);
2055 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2056 M_CMP_IMM(s1, iptr->sx.val.l);
2059 LCONST(REG_ITMP2, iptr->sx.val.l);
2060 M_CMP(s1, REG_ITMP2);
2062 emit_bge_xcc(cd, iptr->dst.block);
2067 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2068 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2070 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2071 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2073 emit_beq_xcc(cd, iptr->dst.block);
2076 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2079 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2081 emit_beq(cd, iptr->dst.block);
2084 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2085 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2088 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2090 emit_bne_xcc(cd, iptr->dst.block);
2093 case ICMD_IF_ICMPNE: /* 32-bit compare */
2095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2096 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2098 emit_bne(cd, iptr->dst.block);
2101 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2106 emit_blt_xcc(cd, iptr->dst.block);
2109 case ICMD_IF_ICMPLT: /* 32-bit compare */
2111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2112 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2114 emit_blt(cd, iptr->dst.block);
2117 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2120 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2122 emit_bgt_xcc(cd, iptr->dst.block);
2125 case ICMD_IF_ICMPGT: /* 32-bit compare */
2127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2128 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2130 emit_bgt(cd, iptr->dst.block);
2133 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2136 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2138 emit_ble_xcc(cd, iptr->dst.block);
2141 case ICMD_IF_ICMPLE: /* 32-bit compare */
2143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2146 emit_ble(cd, iptr->dst.block);
2150 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2152 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2153 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2155 emit_bge_xcc(cd, iptr->dst.block);
2158 case ICMD_IF_ICMPGE: /* 32-bit compare */
2160 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2163 emit_bge(cd, iptr->dst.block);
2167 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2170 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2171 M_INTMOVE(s1, REG_RESULT_CALLEE);
2172 goto nowperformreturn;
2174 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2176 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2177 M_INTMOVE(s1, REG_RESULT_CALLEE);
2179 #ifdef ENABLE_VERIFIER
2180 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2181 unresolved_class *uc = iptr->sx.s23.s2.uc;
2183 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2185 #endif /* ENABLE_VERIFIER */
2186 goto nowperformreturn;
2188 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2191 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2192 M_DBLMOVE(s1, REG_FRESULT);
2193 goto nowperformreturn;
2195 case ICMD_RETURN: /* ... ==> ... */
2201 p = cd->stackframesize;
2203 #if !defined(NDEBUG)
2204 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2205 emit_verbosecall_exit(jd);
2208 #if defined(ENABLE_THREADS)
2209 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2210 /* XXX: REG_RESULT is save, but what about FRESULT? */
2211 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2213 switch (iptr->opc) {
2216 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2220 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2221 M_ALD(REG_ITMP3, REG_PV, disp);
2222 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2224 switch (iptr->opc) {
2227 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2235 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2241 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2244 branch_target_t *table;
2246 table = iptr->dst.table;
2248 l = iptr->sx.s23.s2.tablelow;
2249 i = iptr->sx.s23.s3.tablehigh;
2251 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2253 M_INTMOVE(s1, REG_ITMP1);
2255 else if (l <= 4095) {
2256 M_ADD_IMM(s1, -l, REG_ITMP1);
2259 ICONST(REG_ITMP2, l);
2260 /* XXX: do I need to truncate s1 to 32-bit ? */
2261 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2269 M_CMP_IMM(REG_ITMP1, i - 1);
2272 ICONST(REG_ITMP2, i - 1);
2273 M_CMP(REG_ITMP1, REG_ITMP2);
2275 emit_bugt(cd, table[0].block); /* default target */
2277 /* build jump table top down and use address of lowest entry */
2282 dseg_add_target(cd, table->block);
2287 /* length of dataseg after last dseg_addtarget is used by load */
2289 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2290 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2291 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2292 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2297 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2300 lookup_target_t *lookup;
2302 lookup = iptr->dst.lookup;
2304 i = iptr->sx.s23.s2.lookupcount;
2306 MCODECHECK((i<<2)+8);
2307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2311 M_CMP_IMM(s1, lookup->value);
2313 ICONST(REG_ITMP2, lookup->value);
2314 M_CMP(s1, REG_ITMP2);
2316 emit_beq(cd, lookup->target.block);
2320 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2326 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2328 bte = iptr->sx.s23.s3.bte;
2331 /* XXX: builtin calling with stack arguments not implemented */
2332 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2334 s3 = md->paramcount;
2336 MCODECHECK((s3 << 1) + 64);
2338 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2340 /* copy float arguments according to ABI convention */
2342 int num_fltregargs = 0;
2343 int fltregarg_inswap[16];
2345 for (s3 = s3 - 1; s3 >= 0; s3--) {
2346 var = VAR(iptr->sx.s23.s2.args[s3]);
2348 if (IS_FLT_DBL_TYPE(var->type)) {
2349 if (!md->params[s3].inmemory) {
2350 s1 = s3; /*native flt args use argument index directly*/
2351 d = emit_load(jd, iptr, var, REG_FTMP1);
2354 fltregarg_inswap[num_fltregargs] = s1;
2356 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2365 /* move swapped float args to target regs */
2366 for (i = 0; i < num_fltregargs; i++) {
2367 s1 = fltregarg_inswap[i];
2368 M_DMOV(s1 + 16, s1);
2369 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2373 assert(md->argfltreguse == 0);
2378 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2380 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2381 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2382 case ICMD_INVOKEINTERFACE:
2384 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2386 um = iptr->sx.s23.s3.um;
2387 md = um->methodref->parseddesc.md;
2390 lm = iptr->sx.s23.s3.fmiref->p.method;
2392 md = lm->parseddesc;
2396 s3 = md->paramcount;
2398 MCODECHECK((s3 << 1) + 64);
2400 /* copy arguments to registers or stack location */
2402 for (s3 = s3 - 1; s3 >= 0; s3--) {
2403 var = VAR(iptr->sx.s23.s2.args[s3]);
2404 d = md->params[s3].regoff;
2406 if (var->flags & PREALLOC)
2409 if (IS_INT_LNG_TYPE(var->type)) {
2410 if (!md->params[s3].inmemory) {
2411 s1 = emit_load(jd, iptr, var, d);
2415 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2416 M_STX(s1, REG_SP, JITSTACK + d * 8);
2420 #ifdef BUILTIN_FLOAT_ARGS
2421 if (iptr->opc == ICMD_BUILTIN)
2425 if (!md->params[s3].inmemory) {
2426 s1 = emit_load(jd, iptr, var, d);
2427 if (IS_2_WORD_TYPE(var->type))
2433 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2434 if (IS_2_WORD_TYPE(var->type))
2435 M_DST(s1, REG_SP, JITSTACK + d * 8);
2437 M_FST(s1, REG_SP, JITSTACK + d * 8);
2442 switch (iptr->opc) {
2444 disp = dseg_add_functionptr(cd, bte->fp);
2446 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2448 /* XXX jit-c-call */
2449 /* generate the actual call */
2451 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2453 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2454 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2455 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2457 emit_exception_check(cd, iptr);
2458 if (md->returntype.type == TYPE_FLT) {
2459 /* special handling for float return value in %f0 */
2464 case ICMD_INVOKESPECIAL:
2465 emit_nullpointer_check(cd, iptr, REG_OUT0);
2468 case ICMD_INVOKESTATIC:
2470 disp = dseg_add_unique_address(cd, NULL);
2472 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2476 disp = dseg_add_address(cd, lm->stubroutine);
2478 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2480 /* generate the actual call */
2482 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2484 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2485 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2486 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2489 case ICMD_INVOKEVIRTUAL:
2490 emit_nullpointer_check(cd, iptr, REG_OUT0);
2493 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2498 s1 = OFFSET(vftbl_t, table[0]) +
2499 sizeof(methodptr) * lm->vftblindex;
2501 /* implicit null-pointer check */
2502 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2503 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2505 /* generate the actual call */
2507 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2509 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2510 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2511 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2514 case ICMD_INVOKEINTERFACE:
2515 emit_nullpointer_check(cd, iptr, REG_OUT0);
2518 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2524 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2525 sizeof(methodptr*) * lm->class->index;
2527 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2530 /* implicit null-pointer check */
2531 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2532 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2533 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2535 /* generate the actual call */
2537 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2539 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2540 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2541 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2545 /* store return value */
2547 d = md->returntype.type;
2549 if (d != TYPE_VOID) {
2550 if (IS_INT_LNG_TYPE(d)) {
2551 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2552 M_INTMOVE(REG_RESULT_CALLER, s1);
2555 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2556 if (IS_2_WORD_TYPE(d)) {
2557 M_DBLMOVE(REG_FRESULT, s1);
2559 M_FLTMOVE(REG_FRESULT, s1);
2562 emit_store_dst(jd, iptr, s1);
2567 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2568 /* val.a: (classinfo*) superclass */
2570 /* superclass is an interface:
2572 * OK if ((sub == NULL) ||
2573 * (sub->vftbl->interfacetablelength > super->index) &&
2574 * (sub->vftbl->interfacetable[-super->index] != NULL));
2576 * superclass is a class:
2578 * OK if ((sub == NULL) || (0
2579 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2580 * super->vftbl->diffvall));
2583 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2587 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2592 super = iptr->sx.s23.s3.c.cls;
2593 superindex = super->index;
2596 #if defined(ENABLE_THREADS)
2597 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2602 /* if class is not resolved, check which code to call */
2604 if (super == NULL) {
2605 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2607 cr = iptr->sx.s23.s3.c.ref;
2608 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2610 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2613 M_ILD(REG_ITMP2, REG_PV, disp);
2614 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2615 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2618 /* interface checkcast code */
2620 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2621 if (super == NULL) {
2622 cr = iptr->sx.s23.s3.c.ref;
2624 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2628 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2631 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2632 M_ILD(REG_ITMP3, REG_ITMP2,
2633 OFFSET(vftbl_t, interfacetablelength));
2634 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2635 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2637 M_ALD(REG_ITMP3, REG_ITMP2,
2638 OFFSET(vftbl_t, interfacetable[0]) -
2639 superindex * sizeof(methodptr*));
2640 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2643 emit_label_br(cd, BRANCH_LABEL_4);
2645 emit_label(cd, BRANCH_LABEL_3);
2648 /* class checkcast code */
2650 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2651 if (super == NULL) {
2652 emit_label(cd, BRANCH_LABEL_2);
2654 cr = iptr->sx.s23.s3.c.ref;
2655 disp = dseg_add_unique_address(cd, NULL);
2657 codegen_add_patch_ref(cd,
2658 PATCHER_checkcast_instanceof_class,
2662 disp = dseg_add_address(cd, super->vftbl);
2664 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2667 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2668 M_ALD(REG_ITMP3, REG_PV, disp);
2669 #if defined(ENABLE_THREADS)
2670 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2672 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2673 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2674 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2675 M_ALD(REG_ITMP3, REG_PV, disp);
2676 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2677 #if defined(ENABLE_THREADS)
2678 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2681 M_CMP(REG_ITMP3, REG_ITMP2);
2682 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2685 emit_label(cd, BRANCH_LABEL_5);
2688 if (super == NULL) {
2689 emit_label(cd, BRANCH_LABEL_1);
2690 emit_label(cd, BRANCH_LABEL_4);
2693 d = codegen_reg_of_dst(jd, iptr, s1);
2696 /* array type cast-check */
2698 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2699 M_INTMOVE(s1, REG_OUT0);
2701 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2703 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2704 cr = iptr->sx.s23.s3.c.ref;
2705 disp = dseg_add_unique_address(cd, NULL);
2707 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2711 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2713 M_ALD(REG_OUT1, REG_PV, disp);
2714 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2715 M_ALD(REG_ITMP3, REG_PV, disp);
2716 /* XXX jit-c-call */
2717 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2721 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2723 d = codegen_reg_of_dst(jd, iptr, s1);
2727 emit_store_dst(jd, iptr, d);
2730 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2731 /* val.a: (classinfo*) superclass */
2733 /* superclass is an interface:
2735 * return (sub != NULL) &&
2736 * (sub->vftbl->interfacetablelength > super->index) &&
2737 * (sub->vftbl->interfacetable[-super->index] != NULL);
2739 * superclass is a class:
2741 * return ((sub != NULL) && (0
2742 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2743 * super->vftbl->diffvall));
2748 vftbl_t *supervftbl;
2751 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2757 super = iptr->sx.s23.s3.c.cls;
2758 superindex = super->index;
2759 supervftbl = super->vftbl;
2762 #if defined(ENABLE_THREADS)
2763 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2768 M_MOV(s1, REG_ITMP1);
2774 /* if class is not resolved, check which code to call */
2776 if (super == NULL) {
2777 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2779 cr = iptr->sx.s23.s3.c.ref;
2780 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2782 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2785 M_ILD(REG_ITMP3, REG_PV, disp);
2786 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2787 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2790 /* interface instanceof code */
2792 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2793 if (super == NULL) {
2794 cr = iptr->sx.s23.s3.c.ref;
2796 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2800 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2803 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2804 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2805 M_CMP_IMM(REG_ITMP3, superindex);
2808 M_ALD(REG_ITMP1, REG_ITMP1,
2809 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2810 superindex * sizeof(methodptr*)));
2811 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2814 emit_label_br(cd, BRANCH_LABEL_4);
2816 emit_label(cd, BRANCH_LABEL_3);
2819 /* class instanceof code */
2821 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2822 if (super == NULL) {
2823 emit_label(cd, BRANCH_LABEL_2);
2825 cr = iptr->sx.s23.s3.c.ref;
2826 disp = dseg_add_unique_address(cd, NULL);
2828 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2832 disp = dseg_add_address(cd, supervftbl);
2834 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2837 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2838 M_ALD(REG_ITMP2, REG_PV, disp);
2839 #if defined(ENABLE_THREADS)
2840 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2842 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2843 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2844 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2845 #if defined(ENABLE_THREADS)
2846 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2848 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2849 M_CMP(REG_ITMP1, REG_ITMP2);
2850 M_XCMOVULE_IMM(1, d);
2853 emit_label(cd, BRANCH_LABEL_5);
2856 if (super == NULL) {
2857 emit_label(cd, BRANCH_LABEL_1);
2858 emit_label(cd, BRANCH_LABEL_4);
2861 emit_store_dst(jd, iptr, d);
2865 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2867 /* check for negative sizes and copy sizes to stack if necessary */
2869 MCODECHECK((iptr->s1.argcount << 1) + 64);
2871 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2873 var = VAR(iptr->sx.s23.s2.args[s1]);
2875 /* copy SAVEDVAR sizes to stack */
2877 /* Already Preallocated? */
2879 if (!(var->flags & PREALLOC)) {
2880 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2881 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2885 /* arg 0 = dimension count */
2887 ICONST(REG_OUT0, iptr->s1.argcount);
2889 /* is patcher function set? */
2891 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2892 disp = dseg_add_unique_address(cd, 0);
2894 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2895 iptr->sx.s23.s3.c.ref,
2899 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2901 /* arg 1 = arraydescriptor */
2903 M_ALD(REG_OUT1, REG_PV, disp);
2905 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2907 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2909 /* XXX c abi call */
2910 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2911 M_ALD(REG_ITMP3, REG_PV, disp);
2912 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2915 /* check for exception before result assignment */
2917 emit_exception_check(cd, iptr);
2919 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2920 M_INTMOVE(REG_RESULT_CALLER, d);
2921 emit_store_dst(jd, iptr, d);
2925 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2931 } /* for instruction */
2935 } /* if (bptr -> flags >= BBREACHED) */
2936 } /* for basic block */
2938 dseg_createlinenumbertable(cd);
2940 /* generate stubs */
2942 emit_patcher_stubs(jd);
2943 REPLACEMENT_EMIT_STUBS(jd);
2945 /* everything's ok */
2951 /* codegen_emit_stub_compiler **************************************************
2953 Emits a stub routine which calls the compiler.
2955 *******************************************************************************/
2957 void codegen_emit_stub_compiler(jitdata *jd)
2962 /* get required compiler data */
2967 /* code for the stub */
2969 /* no window save yet, user caller's PV */
2970 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2971 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2972 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2977 /* codegen_emit_stub_native ****************************************************
2979 Emits a stub routine which calls a native method.
2981 *******************************************************************************/
2983 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2990 s4 i, j; /* count variables */
2993 s4 funcdisp; /* displacement of the function */
2995 /* get required compiler data */
3001 /* initialize variables */
3004 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3006 /* calculate stack frame size */
3008 cd->stackframesize =
3009 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3010 sizeof(localref_table) / SIZEOF_VOID_P +
3011 md->paramcount + /* for saving arguments over calls */
3012 nmd->memuse + /* nmd knows about the native stackframe layout */
3015 /* create method header */
3017 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3018 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3019 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3020 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3021 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3022 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3023 (void) dseg_addlinenumbertablesize(cd);
3024 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3026 /* generate stub code */
3028 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3030 #if !defined(NDEBUG)
3031 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3032 emit_verbosecall_enter(jd);
3035 /* get function address (this must happen before the stackframeinfo) */
3037 funcdisp = dseg_add_functionptr(cd, f);
3039 #if !defined(WITH_STATIC_CLASSPATH)
3041 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3045 /* save float argument registers */
3047 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3048 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3049 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3054 /* prepare data structures for native function call */
3056 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
3057 M_MOV(REG_PV_CALLEE, REG_OUT1);
3058 M_MOV(REG_FP, REG_OUT2); /* java sp */
3059 M_MOV(REG_RA_CALLEE, REG_OUT3);
3060 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3061 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3062 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3063 M_NOP; /* XXX fill me! */
3065 /* restore float argument registers */
3067 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3068 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3069 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3074 /* copy or spill arguments to new locations */
3075 int num_fltregargs = 0;
3076 int fltregarg_inswap[16];
3077 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3078 t = md->paramtypes[i].type;
3080 if (IS_INT_LNG_TYPE(t)) {
3081 if (!md->params[i].inmemory) {
3082 s1 = md->params[i].regoff;
3083 /* s1 refers to the old window, transpose */
3084 s1 = REG_WINDOW_TRANSPOSE(s1);
3086 if (!nmd->params[j].inmemory) {
3087 s2 = nat_argintregs[nmd->params[j].regoff];
3090 s2 = nmd->params[j].regoff - 6;
3091 M_AST(s1, REG_SP, CSTACK + s2 * 8);
3096 s1 = md->params[i].regoff + cd->stackframesize;
3097 s2 = nmd->params[j].regoff - 6;
3098 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3099 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3103 if (!md->params[i].inmemory) {
3104 s1 = md->params[i].regoff;
3106 if (!nmd->params[j].inmemory) {
3107 /* no mapping to regs needed, native flt args use regoff */
3108 s2 = nmd->params[j].regoff;
3110 /* we cannot move flt regs to their native arg locations directly */
3111 M_DMOV(s1, s2 + 16);
3112 fltregarg_inswap[num_fltregargs] = s2;
3114 /*printf("flt arg swap to %d\n", s2 + 16);*/
3117 s2 = nmd->params[j].regoff;
3118 if (IS_2_WORD_TYPE(t))
3119 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3121 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3126 s1 = md->params[i].regoff + cd->stackframesize;
3127 s2 = nmd->params[j].regoff - 6;
3128 if (IS_2_WORD_TYPE(t)) {
3129 M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3130 M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3132 M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3133 M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3139 /* move swapped float args to target regs */
3140 for (i = 0; i < num_fltregargs; i++) {
3141 s1 = fltregarg_inswap[i];
3142 M_DMOV(s1 + 16, s1);
3143 /*printf("float arg to target reg: %d ==> %d\n", s1+16, s1);*/
3147 /* put class into second argument register */
3149 if (m->flags & ACC_STATIC) {
3150 disp = dseg_add_address(cd, m->class);
3151 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3154 /* put env into first argument register */
3156 disp = dseg_add_address(cd, _Jv_env);
3157 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3159 /* do the native function call */
3161 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3162 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3163 M_NOP; /* delay slot */
3165 /* save return value */
3167 if (md->returntype.type != TYPE_VOID) {
3168 if (IS_INT_LNG_TYPE(md->returntype.type))
3169 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3171 M_DST(REG_FRESULT, REG_SP, CSTACK);
3174 /* Note: native functions return float values in %f0 (see ABI) */
3175 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3177 #if !defined(NDEBUG)
3178 /* But for the trace function we need to put a flt result into %f1 */
3179 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3180 if (!IS_2_WORD_TYPE(md->returntype.type))
3181 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3182 emit_verbosecall_exit(jd);
3186 /* remove native stackframe info */
3188 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3189 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3190 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3191 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3192 M_NOP; /* XXX fill me! */
3193 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3195 /* restore float return value, int return value already in our return reg */
3197 if (md->returntype.type != TYPE_VOID) {
3198 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3199 if (IS_2_WORD_TYPE(md->returntype.type))
3200 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3202 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3206 /* check for exception */
3207 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3210 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3213 /* handle exception */
3215 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3216 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3217 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3218 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3219 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3221 /* generate patcher stubs */
3223 emit_patcher_stubs(jd);
3227 * These are local overrides for various environment variables in Emacs.
3228 * Please do not remove this and leave it at the end of the file, where
3229 * Emacs will automagically detect them.
3230 * ---------------------------------------------------------------------
3233 * indent-tabs-mode: t
3237 * vim:noexpandtab:sw=4:ts=4: