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, slots;
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, JITSTACK + (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);
222 /* call monitorenter function */
223 #if defined(ENABLE_THREADS)
224 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
225 /* stack offset for monitor argument */
229 /* save float argument registers */
233 ALIGN_STACK_SLOTS(slots);
235 M_LDA(REG_SP, REG_SP, -(slots * 8));
236 for (i = 0; i < FLT_ARG_CNT; i++)
237 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
241 /* get correct lock object */
243 if (m->flags & ACC_STATIC) {
244 disp = dseg_add_address(cd, &m->class->object.header);
245 M_ALD(REG_OUT0, REG_PV, disp);
246 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
247 M_ALD(REG_ITMP3, REG_PV, disp);
250 /* copy class pointer: $i0 -> $o0 */
251 M_MOV(REG_RESULT_CALLEE, REG_OUT0);
253 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
254 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
255 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
258 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
259 M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */
261 /* restore float argument registers */
263 for (i = 0; i < FLT_ARG_CNT; i++)
264 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8);
266 M_LDA(REG_SP, REG_SP, slots * 8);
271 /* take arguments out of register or stack frame */
275 /* when storing locals, use this as base */
276 localbase = JITSTACK;
278 /* since the register allocator does not know about the shifting window
279 * arg regs need to be copied via the stack
281 if (md->argintreguse > 0) {
282 /* allocate scratch space for copying in to save(i&l) regs */
283 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
285 localbase += INT_ARG_CNT * 8;
287 /* XXX could use the param slots on the stack for this! */
288 for (p = 0; p < INT_ARG_CNT; p++)
289 M_STX(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[p]), REG_SP, JITSTACK + (p * 8));
293 for (p = 0, l = 0; p < md->paramcount; p++) {
294 t = md->paramtypes[p].type;
296 varindex = jd->local_map[l * 5 + t];
299 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
302 if (varindex == UNUSED)
306 s1 = md->params[p].regoff;
308 if (IS_INT_LNG_TYPE(t)) { /* integer args */
310 if (!md->params[p].inmemory) { /* register arguments */
311 /*s2 = rd->argintregs[s1];*/
312 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
314 /* need the argument index (p) here, not the register number */
316 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
317 /*M_INTMOVE(s2, var->vv.regoff);*/
318 M_LDX(var->vv.regoff, REG_SP, JITSTACK + (p * 8));
320 } else { /* reg arg -> spilled */
321 /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
323 M_LDX(REG_ITMP1, REG_SP, JITSTACK + (p * 8));
324 M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
327 } else { /* stack arguments */
328 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
329 M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
331 } else { /* stack arg -> spilled */
332 /* add the callers window save registers */
333 var->vv.regoff = cd->stackframesize + s1;
337 } else { /* floating args */
338 if (!md->params[p].inmemory) { /* register arguments */
339 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
340 M_FLTMOVE(s1, var->vv.regoff);
342 } else { /* reg arg -> spilled */
343 M_DST(s1, REG_SP, localbase + (var->vv.regoff) * 8);
346 } else { /* stack arguments */
347 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
348 M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
350 } else { /* stack-arg -> spilled */
351 var->vv.regoff = cd->stackframesize + s1;
357 if (md->argintreguse > 0) {
358 /* release scratch space */
359 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
367 /* end of header generation */
369 /* create replacement points */
371 REPLACEMENT_POINTS_INIT(cd, jd);
373 /* walk through all basic blocks */
375 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
377 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
379 if (bptr->flags >= BBREACHED) {
381 /* branch resolving */
383 codegen_resolve_branchrefs(cd, bptr);
385 /* handle replacement points */
388 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
389 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
395 /* copy interface registers to their destination */
400 #if defined(ENABLE_LSRA)
401 #error XXX LSRA not tested yet
405 src = bptr->invars[len];
406 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
407 /* d = reg_of_var(m, src, REG_ITMP1); */
408 if (!(src->flags & INMEMORY))
412 M_INTMOVE(REG_ITMP1, d);
413 emit_store(jd, NULL, src, d);
420 var = VAR(bptr->invars[len]);
421 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
422 d = codegen_reg_of_var(0, var, REG_ITMP1);
423 M_INTMOVE(REG_ITMP2_XPTR, d);
424 emit_store(jd, NULL, var, d);
427 assert((var->flags & INOUT));
430 #if defined(ENABLE_LSRA)
433 /* walk through all instructions */
437 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
438 if (iptr->line != currentline) {
439 dseg_addlinenumber(cd, iptr->line);
440 currentline = iptr->line;
443 MCODECHECK(64); /* an instruction usually needs < 64 words */
447 case ICMD_INLINE_START:
448 case ICMD_INLINE_END:
451 case ICMD_NOP: /* ... ==> ... */
454 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
456 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
457 emit_nullpointer_check(cd, iptr, s1);
460 /* constant operations ************************************************/
462 case ICMD_ICONST: /* ... ==> ..., constant */
464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
465 ICONST(d, iptr->sx.val.i);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_LCONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
472 LCONST(d, iptr->sx.val.l);
473 emit_store_dst(jd, iptr, d);
476 case ICMD_FCONST: /* ... ==> ..., constant */
478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
479 disp = dseg_add_float(cd, iptr->sx.val.f);
480 M_FLD(d, REG_PV, disp);
481 emit_store_dst(jd, iptr, d);
484 case ICMD_DCONST: /* ... ==> ..., constant */
486 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
487 disp = dseg_add_double(cd, iptr->sx.val.d);
488 M_DLD(d, REG_PV, disp);
489 emit_store_dst(jd, iptr, d);
492 case ICMD_ACONST: /* ... ==> ..., constant */
494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
496 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
497 cr = iptr->sx.val.c.ref;
498 disp = dseg_add_unique_address(cd, cr);
500 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
502 M_ALD(d, REG_PV, disp);
506 if (iptr->sx.val.anyptr == NULL) {
507 M_INTMOVE(REG_ZERO, d);
510 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
511 M_ALD(d, REG_PV, disp);
514 emit_store_dst(jd, iptr, d);
518 /* load/store/copy/move operations ************************************/
520 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
525 case ICMD_ISTORE: /* ..., value ==> ... */
536 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
541 /* pop/dup/swap operations ********************************************/
543 /* attention: double and longs are only one entry in CACAO ICMDs */
545 case ICMD_POP: /* ..., value ==> ... */
546 case ICMD_POP2: /* ..., value, value ==> ... */
550 /* integer operations *************************************************/
552 case ICMD_INEG: /* ..., value ==> ..., - value */
555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557 M_SUB(REG_ZERO, s1, d);
558 emit_store_dst(jd, iptr, d);
561 case ICMD_I2L: /* ..., value ==> ..., value */
563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_L2I: /* ..., value ==> ..., value */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
574 emit_store_dst(jd, iptr, d);
577 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
581 M_SLLX_IMM(s1, 56, d);
582 M_SRAX_IMM( d, 56, d);
583 emit_store_dst(jd, iptr, d);
586 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
590 M_SLLX_IMM(s1, 48, d);
591 M_SRLX_IMM( d, 48, d);
592 emit_store_dst(jd, iptr, d);
595 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
597 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
599 M_SLLX_IMM(s1, 48, d);
600 M_SRAX_IMM( d, 48, d);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 emit_store_dst(jd, iptr, d);
615 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
616 /* sx.val.i = constant */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
621 M_ADD_IMM(s1, iptr->sx.val.i, d);
623 ICONST(REG_ITMP2, iptr->sx.val.i);
624 M_ADD(s1, REG_ITMP2, d);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
630 /* sx.val.l = constant */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
635 M_ADD_IMM(s1, iptr->sx.val.l, d);
637 LCONST(REG_ITMP2, iptr->sx.val.l);
638 M_ADD(s1, REG_ITMP2, d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 emit_store_dst(jd, iptr, d);
653 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
654 /* sx.val.i = constant */
656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
659 M_SUB_IMM(s1, iptr->sx.val.i, d);
661 ICONST(REG_ITMP2, iptr->sx.val.i);
662 M_SUB(s1, REG_ITMP2, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
668 /* sx.val.l = constant */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
673 M_SUB_IMM(s1, iptr->sx.val.l, d);
675 LCONST(REG_ITMP2, iptr->sx.val.l);
676 M_SUB(s1, REG_ITMP2, d);
678 emit_store_dst(jd, iptr, d);
681 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688 emit_store_dst(jd, iptr, d);
691 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
692 /* sx.val.i = constant */
694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
696 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
697 M_MULX_IMM(s1, iptr->sx.val.i, d);
699 ICONST(REG_ITMP2, iptr->sx.val.i);
700 M_MULX(s1, REG_ITMP2, d);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
706 /* sx.val.l = constant */
708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
711 M_MULX_IMM(s1, iptr->sx.val.l, d);
713 LCONST(REG_ITMP2, iptr->sx.val.l);
714 M_MULX(s1, REG_ITMP2, d);
716 emit_store_dst(jd, iptr, d);
719 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
720 /* XXX could also clear Y and use 32bit div */
721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
722 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
724 emit_arithmetic_check(cd, iptr, s2);
726 /* XXX trim s2 like s1 ? */
728 emit_store_dst(jd, iptr, d);
731 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736 emit_arithmetic_check(cd, iptr, s2);
738 emit_store_dst(jd, iptr, d);
741 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
743 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
744 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
745 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
746 emit_arithmetic_check(cd, iptr, s2);
748 /* XXX trim s2 like s1 ? */
749 M_DIVX(s1, s2, REG_ITMP3);
750 M_MULX(s2, REG_ITMP3, REG_ITMP3);
751 M_SUB(s1, REG_ITMP3, d);
752 emit_store_dst(jd, iptr, d);
755 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
757 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
758 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
760 emit_arithmetic_check(cd, iptr, s2);
761 M_DIVX(s1, s2, REG_ITMP3);
762 M_MULX(s2, REG_ITMP3, REG_ITMP3);
763 M_SUB(s1, REG_ITMP3, d);
764 emit_store_dst(jd, iptr, d);
767 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
768 case ICMD_LDIVPOW2: /* val.i = constant */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 M_SRAX_IMM(s1, 63, REG_ITMP2);
773 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
774 M_ADD(s1, REG_ITMP2, REG_ITMP2);
775 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
776 emit_store_dst(jd, iptr, d);
779 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
781 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
782 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785 emit_store_dst(jd, iptr, d);
788 case ICMD_LSHL: /* ..., 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_ISHLCONST: /* ..., value ==> ..., value << constant */
798 /* val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_SLL_IMM(s1, iptr->sx.val.i, d);
803 emit_store_dst(jd, iptr, d);
806 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
807 /* val.i = constant */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
811 M_SLLX_IMM(s1, iptr->sx.val.i, d);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
825 /* sx.val.i = constant */
827 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829 M_SRA_IMM(s1, iptr->sx.val.i, d);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
836 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
839 emit_store_dst(jd, iptr, d);
842 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
843 /* sx.val.i = constant */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
847 M_SRL_IMM(s1, iptr->sx.val.i, d);
848 emit_store_dst(jd, iptr, d);
851 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
855 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
857 emit_store_dst(jd, iptr, d);
860 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
861 /* sx.val.i = constant */
863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
864 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
865 M_SRAX_IMM(s1, iptr->sx.val.i, d);
866 emit_store_dst(jd, iptr, d);
869 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
872 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
875 emit_store_dst(jd, iptr, d);
878 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
879 /* sx.val.i = constant */
881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
882 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
883 M_SRLX_IMM(s1, iptr->sx.val.i, d);
884 emit_store_dst(jd, iptr, d);
887 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
891 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
894 emit_store_dst(jd, iptr, d);
897 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
898 /* sx.val.i = constant */
900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
901 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
902 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
903 M_AND_IMM(s1, iptr->sx.val.i, d);
905 ICONST(REG_ITMP2, iptr->sx.val.i);
906 M_AND(s1, REG_ITMP2, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
912 /* sx.val.i = constant */
913 /* constant is actually constant - 1 */
915 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
916 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
918 M_MOV(s1, REG_ITMP1);
921 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
922 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
923 M_AND_IMM(s1, iptr->sx.val.i, d);
926 M_SUB(REG_ZERO, s1, d);
927 M_AND_IMM(d, iptr->sx.val.i, d);
929 ICONST(REG_ITMP2, iptr->sx.val.i);
930 M_AND(s1, REG_ITMP2, d);
933 M_SUB(REG_ZERO, s1, d);
934 M_AND(d, REG_ITMP2, d);
936 M_SUB(REG_ZERO, d, d);
937 emit_store_dst(jd, iptr, d);
940 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
941 /* sx.val.l = constant */
943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
945 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
946 M_AND_IMM(s1, iptr->sx.val.l, d);
948 LCONST(REG_ITMP2, iptr->sx.val.l);
949 M_AND(s1, REG_ITMP2, d);
951 emit_store_dst(jd, iptr, d);
954 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
955 /* sx.val.l = constant */
957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
958 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
960 M_MOV(s1, REG_ITMP1);
963 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
964 M_AND_IMM(s1, iptr->sx.val.l, d);
967 M_SUB(REG_ZERO, s1, d);
968 M_AND_IMM(d, iptr->sx.val.l, d);
970 LCONST(REG_ITMP2, iptr->sx.val.l);
971 M_AND(s1, REG_ITMP2, d);
974 M_SUB(REG_ZERO, s1, d);
975 M_AND(d, REG_ITMP2, d);
977 M_SUB(REG_ZERO, d, d);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
992 /* sx.val.i = constant */
994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
996 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
997 M_OR_IMM(s1, iptr->sx.val.i, d);
999 ICONST(REG_ITMP2, iptr->sx.val.i);
1000 M_OR(s1, REG_ITMP2, d);
1002 emit_store_dst(jd, iptr, d);
1005 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1006 /* sx.val.l = constant */
1008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1009 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1010 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1011 M_OR_IMM(s1, iptr->sx.val.l, d);
1013 LCONST(REG_ITMP2, iptr->sx.val.l);
1014 M_OR(s1, REG_ITMP2, d);
1016 emit_store_dst(jd, iptr, d);
1019 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1024 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1030 /* sx.val.i = constant */
1032 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1033 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1034 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1035 M_XOR_IMM(s1, iptr->sx.val.i, d);
1037 ICONST(REG_ITMP2, iptr->sx.val.i);
1038 M_XOR(s1, REG_ITMP2, d);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1044 /* sx.val.l = constant */
1046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1048 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1049 M_XOR_IMM(s1, iptr->sx.val.l, d);
1051 LCONST(REG_ITMP2, iptr->sx.val.l);
1052 M_XOR(s1, REG_ITMP2, d);
1054 emit_store_dst(jd, iptr, d);
1058 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 M_XCMOVLT_IMM(-1, d);
1066 M_XCMOVGT_IMM(1, d);
1067 emit_store_dst(jd, iptr, d);
1071 /* floating operations ************************************************/
1073 case ICMD_FNEG: /* ..., value ==> ..., - value */
1075 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1076 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_DNEG: /* ..., value ==> ..., - value */
1083 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1084 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_FADD: /* ..., 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_DADD: /* ..., 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_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1109 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1118 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1119 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1120 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1127 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1128 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1129 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1131 emit_store_dst(jd, iptr, d);
1134 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1136 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1137 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1146 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1147 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1154 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1155 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1158 emit_store_dst(jd, iptr, d);
1162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1163 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1164 disp = dseg_add_unique_float(cd, 0.0);
1165 M_IST (s1, REG_PV_CALLEE, disp);
1166 M_FLD (d, REG_PV_CALLEE, disp);
1167 M_CVTIF (d, d); /* rd gets translated to double target register */
1168 emit_store_dst(jd, iptr, d);
1172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1173 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1174 disp = dseg_add_unique_float(cd, 0.0);
1175 M_IST(s1, REG_PV_CALLEE, disp);
1176 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1177 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1178 emit_store_dst(jd, iptr, d);
1182 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1183 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1184 disp = dseg_add_unique_double(cd, 0.0);
1185 M_STX(s1, REG_PV_CALLEE, disp);
1186 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1187 M_CVTLF(REG_FTMP3, d);
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_double(cd, 0.0);
1195 M_STX(s1, REG_PV_CALLEE, disp);
1196 M_DLD(d, REG_PV_CALLEE, disp);
1198 emit_store_dst(jd, iptr, d);
1201 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1202 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1203 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1204 disp = dseg_add_unique_float(cd, 0.0);
1206 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1209 M_MOV(REG_ZERO, d); /* delay slot */
1211 M_CVTFI(s1, REG_FTMP2);
1212 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1213 M_ILD(d, REG_PV, disp);
1214 emit_store_dst(jd, iptr, d);
1218 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1219 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1221 disp = dseg_add_unique_float(cd, 0.0);
1223 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1226 M_MOV(REG_ZERO, d); /* delay slot */
1228 M_CVTDI(s1, REG_FTMP2);
1229 M_FST(REG_FTMP2, REG_PV, disp);
1230 M_ILD(d, REG_PV, disp);
1231 emit_store_dst(jd, iptr, d);
1234 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1237 disp = dseg_add_unique_double(cd, 0.0);
1239 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1242 M_MOV(REG_ZERO, d); /* delay slot */
1244 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1245 M_DST(REG_FTMP2, REG_PV, disp);
1246 M_LDX(d, REG_PV, disp);
1247 emit_store_dst(jd, iptr, d);
1250 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1251 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1252 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1253 disp = dseg_add_unique_double(cd, 0.0);
1255 /* check for NaN, SPARC overflow is noncompliant (see V9 spec B.5) */
1258 M_MOV(REG_ZERO, d); /* delay slot */
1260 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1261 M_DST(REG_FTMP2, REG_PV, disp);
1262 M_LDX(d, REG_PV, disp);
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1268 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1269 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1271 emit_store_dst(jd, iptr, d);
1274 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1276 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1277 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 emit_store_dst(jd, iptr, d);
1282 /* XXX merge F/D versions? only compare instr. is different */
1283 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1285 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1286 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1287 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1289 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1290 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1291 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1292 emit_store_dst(jd, iptr, d);
1295 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1297 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1298 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1299 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1301 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1302 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1303 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1304 emit_store_dst(jd, iptr, d);
1307 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1309 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1310 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1311 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1313 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1314 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1315 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1316 emit_store_dst(jd, iptr, d);
1319 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1321 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1322 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1323 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1325 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1326 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1327 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1328 emit_store_dst(jd, iptr, d);
1332 /* memory operations **************************************************/
1334 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1337 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1338 emit_nullpointer_check(cd, iptr, s1);
1339 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1340 emit_store_dst(jd, iptr, d);
1343 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1346 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1347 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1348 /* implicit null-pointer check */
1349 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1350 M_AADD(s2, s1, REG_ITMP3);
1351 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1352 emit_store_dst(jd, iptr, d);
1355 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1357 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1358 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1359 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1360 /* implicit null-pointer check */
1361 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1362 M_AADD(s2, s1, REG_ITMP3);
1363 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1364 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1365 emit_store_dst(jd, iptr, d);
1368 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1370 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1371 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1373 /* implicit null-pointer check */
1374 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1375 M_AADD(s2, s1, REG_ITMP3);
1376 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1377 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1378 emit_store_dst(jd, iptr, d);
1381 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1384 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1386 /* implicit null-pointer check */
1387 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1388 M_ASLL_IMM(s2, 2, REG_ITMP3);
1389 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1390 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1391 emit_store_dst(jd, iptr, d);
1394 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1396 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1399 /* implicit null-pointer check */
1400 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1401 M_ASLL_IMM(s2, 3, REG_ITMP3);
1402 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1403 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1404 emit_store_dst(jd, iptr, d);
1407 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1409 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1410 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1411 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1412 /* implicit null-pointer check */
1413 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1414 M_ASLL_IMM(s2, 2, REG_ITMP3);
1415 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1416 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1417 emit_store_dst(jd, iptr, d);
1420 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1422 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1423 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1424 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1425 /* implicit null-pointer check */
1426 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1427 M_ASLL_IMM(s2, 3, REG_ITMP3);
1428 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1429 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1435 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1436 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1437 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1438 /* implicit null-pointer check */
1439 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1440 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1441 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1442 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1443 emit_store_dst(jd, iptr, d);
1447 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1451 /* implicit null-pointer check */
1452 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1453 M_AADD(s2, s1, REG_ITMP1);
1454 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1455 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1458 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1459 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1462 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1463 /* implicit null-pointer check */
1464 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1465 M_AADD(s2, s1, REG_ITMP1);
1466 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1467 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1468 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1471 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1473 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1475 /* implicit null-pointer check */
1476 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1477 M_ASLL_IMM(s2, 2, REG_ITMP2);
1478 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1479 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1480 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1483 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1485 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1486 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1487 /* implicit null-pointer check */
1488 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1489 M_ASLL_IMM(s2, 3, REG_ITMP2);
1490 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1491 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1492 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1495 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1498 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1499 /* implicit null-pointer check */
1500 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501 M_ASLL_IMM(s2, 2, REG_ITMP2);
1502 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1503 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1504 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1507 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1510 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1511 /* implicit null-pointer check */
1512 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1513 M_ASLL_IMM(s2, 3, REG_ITMP2);
1514 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1515 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1516 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1520 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1523 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1524 /* implicit null-pointer check */
1525 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1526 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1528 M_MOV(s1, REG_OUT0);
1529 M_MOV(s3, REG_OUT1);
1530 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1531 M_ALD(REG_ITMP3, REG_PV, disp);
1532 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1534 emit_exception_check(cd, iptr);
1536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1537 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1538 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1539 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1540 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1541 /* implicit null-pointer check */
1542 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1546 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 /* implicit null-pointer check */
1551 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1552 M_AADD(s2, s1, REG_ITMP1);
1553 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1556 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1557 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561 /* implicit null-pointer check */
1562 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1563 M_AADD(s2, s1, REG_ITMP1);
1564 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1565 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1568 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1571 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1572 /* implicit null-pointer check */
1573 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1574 M_ASLL_IMM(s2, 2, REG_ITMP2);
1575 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1576 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1579 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1583 /* implicit null-pointer check */
1584 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1585 M_ASLL_IMM(s2, 3, REG_ITMP2);
1586 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1587 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1590 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1594 /* implicit null-pointer check */
1595 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1596 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1597 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1598 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1602 case ICMD_GETSTATIC: /* ... ==> ..., 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 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1625 M_ILD_INTERN(d, REG_ITMP1, 0);
1628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1629 M_LDX_INTERN(d, REG_ITMP1, 0);
1632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1633 M_ALD_INTERN(d, REG_ITMP1, 0);
1636 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1637 M_FLD_INTERN(d, REG_ITMP1, 0);
1640 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1641 M_DLD_INTERN(d, REG_ITMP1, 0);
1644 emit_store_dst(jd, iptr, d);
1647 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1649 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1650 uf = iptr->sx.s23.s3.uf;
1651 fieldtype = uf->fieldref->parseddesc.fd->type;
1652 disp = dseg_add_unique_address(cd, uf);
1654 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1657 fi = iptr->sx.s23.s3.fmiref->p.field;
1658 fieldtype = fi->type;
1659 disp = dseg_add_address(cd, &(fi->value));
1661 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1662 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1665 M_ALD(REG_ITMP1, REG_PV, disp);
1667 switch (fieldtype) {
1669 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1670 M_IST_INTERN(s1, REG_ITMP1, 0);
1673 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1674 M_STX_INTERN(s1, REG_ITMP1, 0);
1677 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1678 M_AST_INTERN(s1, REG_ITMP1, 0);
1681 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1682 M_FST_INTERN(s1, REG_ITMP1, 0);
1685 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1686 M_DST_INTERN(s1, REG_ITMP1, 0);
1691 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1692 /* val = value (in current instruction) */
1693 /* following NOP) */
1695 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1696 uf = iptr->sx.s23.s3.uf;
1697 fieldtype = uf->fieldref->parseddesc.fd->type;
1698 disp = dseg_add_unique_address(cd, uf);
1700 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1703 fi = iptr->sx.s23.s3.fmiref->p.field;
1704 fieldtype = fi->type;
1705 disp = dseg_add_address(cd, &(fi->value));
1707 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1708 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1711 M_ALD(REG_ITMP1, REG_PV, disp);
1713 switch (fieldtype) {
1715 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1718 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1721 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1724 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1727 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1733 case ICMD_GETFIELD: /* ... ==> ..., value */
1735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1736 emit_nullpointer_check(cd, iptr, s1);
1738 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1739 uf = iptr->sx.s23.s3.uf;
1741 fieldtype = uf->fieldref->parseddesc.fd->type;
1744 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1747 fi = iptr->sx.s23.s3.fmiref->p.field;
1748 fieldtype = fi->type;
1752 switch (fieldtype) {
1754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1766 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1770 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1777 emit_store_dst(jd, iptr, d);
1780 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783 emit_nullpointer_check(cd, iptr, s1);
1785 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1786 uf = iptr->sx.s23.s3.uf;
1787 fieldtype = uf->fieldref->parseddesc.fd->type;
1792 fi = iptr->sx.s23.s3.fmiref->p.field;
1793 fieldtype = fi->type;
1797 if (IS_INT_LNG_TYPE(fieldtype))
1798 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1800 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1802 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1803 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1805 switch (fieldtype) {
1807 M_IST(s2, s1, disp);
1810 M_STX(s2, s1, disp);
1813 M_AST(s2, s1, disp);
1816 M_FST(s2, s1, disp);
1819 M_DST(s2, s1, disp);
1827 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1828 /* val = value (in current instruction) */
1829 /* following NOP) */
1831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1832 emit_nullpointer_check(cd, iptr, s1);
1834 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1835 unresolved_field *uf = iptr->sx.s23.s3.uf;
1837 fieldtype = uf->fieldref->parseddesc.fd->type;
1839 codegen_addpatchref(cd, PATCHER_get_putfield,
1842 if (opt_showdisassemble) {
1850 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1852 fieldtype = fi->type;
1858 switch (fieldtype) {
1860 M_IST(REG_ZERO, s1, disp);
1863 M_STX(REG_ZERO, s1, disp);
1866 M_AST(REG_ZERO, s1, disp);
1869 M_FST(REG_ZERO, s1, disp);
1872 M_DST(REG_ZERO, s1, disp);
1878 /* branch operations **************************************************/
1880 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1883 M_INTMOVE(s1, REG_ITMP2_XPTR);
1885 #ifdef ENABLE_VERIFIER
1886 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1887 unresolved_class *uc = iptr->sx.s23.s2.uc;
1889 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1891 #endif /* ENABLE_VERIFIER */
1893 disp = dseg_add_functionptr(cd, asm_handle_exception);
1894 M_ALD(REG_ITMP1, REG_PV, disp);
1895 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1897 M_NOP; /* nop ensures that XPC is less than the end */
1898 /* of basic block */
1902 case ICMD_GOTO: /* ... ==> ... */
1903 case ICMD_RET: /* ... ==> ... */
1905 emit_br(cd, iptr->dst.block);
1909 case ICMD_JSR: /* ... ==> ... */
1911 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1915 case ICMD_IFNULL: /* ..., value ==> ... */
1916 case ICMD_IFNONNULL:
1918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1922 /* Note: int compares must not branch on the register directly. */
1923 /* Reason is, that register content is not 32-bit clean. */
1925 case ICMD_IFEQ: /* ..., value ==> ... */
1927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1929 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1930 M_CMP_IMM(s1, iptr->sx.val.i);
1933 ICONST(REG_ITMP2, iptr->sx.val.i);
1934 M_CMP(s1, REG_ITMP2);
1936 emit_beq(cd, iptr->dst.block);
1939 case ICMD_IFLT: /* ..., value ==> ... */
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1943 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1944 M_CMP_IMM(s1, iptr->sx.val.i);
1947 ICONST(REG_ITMP2, iptr->sx.val.i);
1948 M_CMP(s1, REG_ITMP2);
1950 emit_blt(cd, iptr->dst.block);
1953 case ICMD_IFLE: /* ..., value ==> ... */
1955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1957 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1958 M_CMP_IMM(s1, iptr->sx.val.i);
1961 ICONST(REG_ITMP2, iptr->sx.val.i);
1962 M_CMP(s1, REG_ITMP2);
1964 emit_ble(cd, iptr->dst.block);
1967 case ICMD_IFNE: /* ..., value ==> ... */
1969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1971 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1972 M_CMP_IMM(s1, iptr->sx.val.i);
1975 ICONST(REG_ITMP2, iptr->sx.val.i);
1976 M_CMP(s1, REG_ITMP2);
1978 emit_bne(cd, iptr->dst.block);
1981 case ICMD_IFGT: /* ..., value ==> ... */
1983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1985 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1986 M_CMP_IMM(s1, iptr->sx.val.i);
1989 ICONST(REG_ITMP2, iptr->sx.val.i);
1990 M_CMP(s1, REG_ITMP2);
1992 emit_bgt(cd, iptr->dst.block);
1995 case ICMD_IFGE: /* ..., value ==> ... */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1999 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2000 M_CMP_IMM(s1, iptr->sx.val.i);
2003 ICONST(REG_ITMP2, iptr->sx.val.i);
2004 M_CMP(s1, REG_ITMP2);
2006 emit_bge(cd, iptr->dst.block);
2009 case ICMD_IF_LEQ: /* ..., value ==> ... */
2011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2012 if (iptr->sx.val.l == 0)
2013 emit_beqz(cd, iptr->dst.block, s1);
2015 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2016 M_CMP_IMM(s1, iptr->sx.val.l);
2019 LCONST(REG_ITMP2, iptr->sx.val.l);
2020 M_CMP(s1, REG_ITMP2);
2022 emit_beq_xcc(cd, iptr->dst.block);
2026 case ICMD_IF_LLT: /* ..., value ==> ... */
2028 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2029 if (iptr->sx.val.l == 0)
2030 emit_bltz(cd, iptr->dst.block, s1);
2032 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2033 M_CMP_IMM(s1, iptr->sx.val.l);
2036 LCONST(REG_ITMP2, iptr->sx.val.l);
2037 M_CMP(s1, REG_ITMP2);
2039 emit_blt_xcc(cd, iptr->dst.block);
2043 case ICMD_IF_LLE: /* ..., value ==> ... */
2045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2046 if (iptr->sx.val.l == 0)
2047 emit_blez(cd, iptr->dst.block, s1);
2049 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2050 M_CMP_IMM(s1, iptr->sx.val.l);
2053 LCONST(REG_ITMP2, iptr->sx.val.l);
2054 M_CMP(s1, REG_ITMP2);
2056 emit_ble_xcc(cd, iptr->dst.block);
2060 case ICMD_IF_LNE: /* ..., value ==> ... */
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063 if (iptr->sx.val.l == 0)
2064 emit_bnez(cd, iptr->dst.block, s1);
2066 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2067 M_CMP_IMM(s1, iptr->sx.val.l);
2070 LCONST(REG_ITMP2, iptr->sx.val.l);
2071 M_CMP(s1, REG_ITMP2);
2073 emit_bne_xcc(cd, iptr->dst.block);
2077 case ICMD_IF_LGT: /* ..., value ==> ... */
2079 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2080 if (iptr->sx.val.l == 0)
2081 emit_bgtz(cd, iptr->dst.block, s1);
2083 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2084 M_CMP_IMM(s1, iptr->sx.val.l);
2087 LCONST(REG_ITMP2, iptr->sx.val.l);
2088 M_CMP(s1, REG_ITMP2);
2090 emit_bgt_xcc(cd, iptr->dst.block);
2094 case ICMD_IF_LGE: /* ..., value ==> ... */
2096 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2097 if (iptr->sx.val.l == 0)
2098 emit_bgez(cd, iptr->dst.block, s1);
2100 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2101 M_CMP_IMM(s1, iptr->sx.val.l);
2104 LCONST(REG_ITMP2, iptr->sx.val.l);
2105 M_CMP(s1, REG_ITMP2);
2107 emit_bge_xcc(cd, iptr->dst.block);
2112 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2113 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2118 emit_beq_xcc(cd, iptr->dst.block);
2121 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2126 emit_beq(cd, iptr->dst.block);
2129 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2130 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2133 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2135 emit_bne_xcc(cd, iptr->dst.block);
2138 case ICMD_IF_ICMPNE: /* 32-bit compare */
2140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2143 emit_bne(cd, iptr->dst.block);
2146 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2148 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2149 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2151 emit_blt_xcc(cd, iptr->dst.block);
2154 case ICMD_IF_ICMPLT: /* 32-bit compare */
2156 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2157 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2159 emit_blt(cd, iptr->dst.block);
2162 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2167 emit_bgt_xcc(cd, iptr->dst.block);
2170 case ICMD_IF_ICMPGT: /* 32-bit compare */
2172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2173 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2175 emit_bgt(cd, iptr->dst.block);
2178 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2181 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2183 emit_ble_xcc(cd, iptr->dst.block);
2186 case ICMD_IF_ICMPLE: /* 32-bit compare */
2188 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2189 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2191 emit_ble(cd, iptr->dst.block);
2195 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2197 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2198 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2200 emit_bge_xcc(cd, iptr->dst.block);
2203 case ICMD_IF_ICMPGE: /* 32-bit compare */
2205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2208 emit_bge(cd, iptr->dst.block);
2212 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2215 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2216 M_INTMOVE(s1, REG_RESULT_CALLEE);
2217 goto nowperformreturn;
2219 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2221 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2222 M_INTMOVE(s1, REG_RESULT_CALLEE);
2224 #ifdef ENABLE_VERIFIER
2225 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2226 unresolved_class *uc = iptr->sx.s23.s2.uc;
2228 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2230 #endif /* ENABLE_VERIFIER */
2231 goto nowperformreturn;
2233 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2236 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2237 M_DBLMOVE(s1, REG_FRESULT);
2238 goto nowperformreturn;
2240 case ICMD_RETURN: /* ... ==> ... */
2246 p = cd->stackframesize;
2248 #if !defined(NDEBUG)
2249 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2250 emit_verbosecall_exit(jd);
2253 #if defined(ENABLE_THREADS)
2254 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2255 /* XXX jit-c-call */
2256 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2257 M_ALD(REG_ITMP3, REG_PV, disp);
2259 /* we need to save fp return value (int saved by window) */
2261 switch (iptr->opc) {
2264 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8);
2265 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2266 M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2268 /* restore the fp return value */
2270 M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8);
2276 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2277 M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */
2288 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2294 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2297 branch_target_t *table;
2299 table = iptr->dst.table;
2301 l = iptr->sx.s23.s2.tablelow;
2302 i = iptr->sx.s23.s3.tablehigh;
2304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2306 M_INTMOVE(s1, REG_ITMP1);
2308 else if (l <= 4095) {
2309 M_ADD_IMM(s1, -l, REG_ITMP1);
2312 ICONST(REG_ITMP2, l);
2313 /* XXX: do I need to truncate s1 to 32-bit ? */
2314 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2322 M_CMP_IMM(REG_ITMP1, i - 1);
2325 ICONST(REG_ITMP2, i - 1);
2326 M_CMP(REG_ITMP1, REG_ITMP2);
2328 emit_bugt(cd, table[0].block); /* default target */
2330 /* build jump table top down and use address of lowest entry */
2335 dseg_add_target(cd, table->block);
2340 /* length of dataseg after last dseg_addtarget is used by load */
2342 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2343 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2344 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2345 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2350 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2353 lookup_target_t *lookup;
2355 lookup = iptr->dst.lookup;
2357 i = iptr->sx.s23.s2.lookupcount;
2359 MCODECHECK((i<<2)+8);
2360 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2363 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2364 M_CMP_IMM(s1, lookup->value);
2366 ICONST(REG_ITMP2, lookup->value);
2367 M_CMP(s1, REG_ITMP2);
2369 emit_beq(cd, lookup->target.block);
2373 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2379 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2381 bte = iptr->sx.s23.s3.bte;
2384 /* XXX: builtin calling with stack arguments not implemented */
2385 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2387 s3 = md->paramcount;
2389 MCODECHECK((s3 << 1) + 64);
2391 #ifdef BUILTIN_FLOAT_ARGS /* float args for builtins disabled */
2393 /* copy float arguments according to ABI convention */
2395 int num_fltregargs = 0;
2396 int fltregarg_inswap[16];
2398 for (s3 = s3 - 1; s3 >= 0; s3--) {
2399 var = VAR(iptr->sx.s23.s2.args[s3]);
2401 if (IS_FLT_DBL_TYPE(var->type)) {
2402 if (!md->params[s3].inmemory) {
2403 s1 = s3; /*native flt args use argument index directly*/
2404 d = emit_load(jd, iptr, var, REG_FTMP1);
2407 fltregarg_inswap[num_fltregargs] = s1;
2409 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2418 /* move swapped float args to target regs */
2419 for (i = 0; i < num_fltregargs; i++) {
2420 s1 = fltregarg_inswap[i];
2421 M_DMOV(s1 + 16, s1);
2422 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2426 assert(md->argfltreguse == 0);
2431 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2433 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2434 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2435 case ICMD_INVOKEINTERFACE:
2437 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2439 um = iptr->sx.s23.s3.um;
2440 md = um->methodref->parseddesc.md;
2443 lm = iptr->sx.s23.s3.fmiref->p.method;
2445 md = lm->parseddesc;
2449 s3 = md->paramcount;
2451 MCODECHECK((s3 << 1) + 64);
2453 /* copy arguments to registers or stack location */
2455 for (s3 = s3 - 1; s3 >= 0; s3--) {
2456 var = VAR(iptr->sx.s23.s2.args[s3]);
2457 d = md->params[s3].regoff;
2459 if (var->flags & PREALLOC)
2462 if (IS_INT_LNG_TYPE(var->type)) {
2463 if (!md->params[s3].inmemory) {
2464 s1 = emit_load(jd, iptr, var, d);
2468 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2469 M_STX(s1, REG_SP, JITSTACK + d * 8);
2473 #ifdef BUILTIN_FLOAT_ARGS
2474 if (iptr->opc == ICMD_BUILTIN)
2478 if (!md->params[s3].inmemory) {
2479 s1 = emit_load(jd, iptr, var, d);
2480 if (IS_2_WORD_TYPE(var->type))
2486 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2487 M_DST(s1, REG_SP, JITSTACK + d * 8);
2492 switch (iptr->opc) {
2494 disp = dseg_add_functionptr(cd, bte->fp);
2496 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2498 /* XXX jit-c-call */
2499 /* generate the actual call */
2501 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2503 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2504 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2505 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2507 emit_exception_check(cd, iptr);
2508 if (md->returntype.type == TYPE_FLT) {
2509 /* special handling for float return value in %f0 */
2514 case ICMD_INVOKESPECIAL:
2515 emit_nullpointer_check(cd, iptr, REG_OUT0);
2518 case ICMD_INVOKESTATIC:
2520 disp = dseg_add_unique_address(cd, NULL);
2522 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2526 disp = dseg_add_address(cd, lm->stubroutine);
2528 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2530 /* generate the actual call */
2532 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2534 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2535 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2536 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2539 case ICMD_INVOKEVIRTUAL:
2540 emit_nullpointer_check(cd, iptr, REG_OUT0);
2543 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2548 s1 = OFFSET(vftbl_t, table[0]) +
2549 sizeof(methodptr) * lm->vftblindex;
2551 /* implicit null-pointer check */
2552 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2553 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2555 /* generate the actual call */
2557 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2559 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2560 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2561 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2564 case ICMD_INVOKEINTERFACE:
2565 emit_nullpointer_check(cd, iptr, REG_OUT0);
2568 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2574 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2575 sizeof(methodptr*) * lm->class->index;
2577 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2580 /* implicit null-pointer check */
2581 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2582 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2583 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2585 /* generate the actual call */
2587 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2589 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2590 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2591 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2595 /* store return value */
2597 d = md->returntype.type;
2599 if (d != TYPE_VOID) {
2600 if (IS_INT_LNG_TYPE(d)) {
2601 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2602 M_INTMOVE(REG_RESULT_CALLER, s1);
2605 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2606 if (IS_2_WORD_TYPE(d)) {
2607 M_DBLMOVE(REG_FRESULT, s1);
2609 M_FLTMOVE(REG_FRESULT, s1);
2612 emit_store_dst(jd, iptr, s1);
2617 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2618 /* val.a: (classinfo*) superclass */
2620 /* superclass is an interface:
2622 * OK if ((sub == NULL) ||
2623 * (sub->vftbl->interfacetablelength > super->index) &&
2624 * (sub->vftbl->interfacetable[-super->index] != NULL));
2626 * superclass is a class:
2628 * OK if ((sub == NULL) || (0
2629 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2630 * super->vftbl->diffvall));
2633 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2637 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2642 super = iptr->sx.s23.s3.c.cls;
2643 superindex = super->index;
2646 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2647 CODEGEN_CRITICAL_SECTION_NEW;
2649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2651 /* if class is not resolved, check which code to call */
2653 if (super == NULL) {
2654 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2656 cr = iptr->sx.s23.s3.c.ref;
2657 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2659 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2662 M_ILD(REG_ITMP2, REG_PV, disp);
2663 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2664 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2667 /* interface checkcast code */
2669 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2670 if (super == NULL) {
2671 cr = iptr->sx.s23.s3.c.ref;
2673 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2677 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2680 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2681 M_ILD(REG_ITMP3, REG_ITMP2,
2682 OFFSET(vftbl_t, interfacetablelength));
2683 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2684 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2686 M_ALD(REG_ITMP3, REG_ITMP2,
2687 OFFSET(vftbl_t, interfacetable[0]) -
2688 superindex * sizeof(methodptr*));
2689 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2692 emit_label_br(cd, BRANCH_LABEL_4);
2694 emit_label(cd, BRANCH_LABEL_3);
2697 /* class checkcast code */
2699 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2700 if (super == NULL) {
2701 emit_label(cd, BRANCH_LABEL_2);
2703 cr = iptr->sx.s23.s3.c.ref;
2704 disp = dseg_add_unique_address(cd, NULL);
2706 codegen_add_patch_ref(cd,
2707 PATCHER_checkcast_instanceof_class,
2711 disp = dseg_add_address(cd, super->vftbl);
2713 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2716 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2717 M_ALD(REG_ITMP3, REG_PV, disp);
2719 CODEGEN_CRITICAL_SECTION_START;
2721 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2722 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2723 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2724 M_ALD(REG_ITMP3, REG_PV, disp);
2725 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2727 CODEGEN_CRITICAL_SECTION_END;
2730 M_CMP(REG_ITMP3, REG_ITMP2);
2731 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2734 emit_label(cd, BRANCH_LABEL_5);
2737 if (super == NULL) {
2738 emit_label(cd, BRANCH_LABEL_1);
2739 emit_label(cd, BRANCH_LABEL_4);
2742 d = codegen_reg_of_dst(jd, iptr, s1);
2745 /* array type cast-check */
2747 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2748 M_INTMOVE(s1, REG_OUT0);
2750 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2752 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2753 cr = iptr->sx.s23.s3.c.ref;
2754 disp = dseg_add_unique_address(cd, NULL);
2756 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2760 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2762 M_ALD(REG_OUT1, REG_PV, disp);
2763 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2764 M_ALD(REG_ITMP3, REG_PV, disp);
2765 /* XXX jit-c-call */
2766 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2769 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2770 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2772 d = codegen_reg_of_dst(jd, iptr, s1);
2776 emit_store_dst(jd, iptr, d);
2779 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2780 /* val.a: (classinfo*) superclass */
2782 /* superclass is an interface:
2784 * return (sub != NULL) &&
2785 * (sub->vftbl->interfacetablelength > super->index) &&
2786 * (sub->vftbl->interfacetable[-super->index] != NULL);
2788 * superclass is a class:
2790 * return ((sub != NULL) && (0
2791 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2792 * super->vftbl->diffvall));
2797 vftbl_t *supervftbl;
2800 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2806 super = iptr->sx.s23.s3.c.cls;
2807 superindex = super->index;
2808 supervftbl = super->vftbl;
2811 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2812 CODEGEN_CRITICAL_SECTION_NEW;
2814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2817 M_MOV(s1, REG_ITMP1);
2823 /* if class is not resolved, check which code to call */
2825 if (super == NULL) {
2826 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2828 cr = iptr->sx.s23.s3.c.ref;
2829 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2831 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2834 M_ILD(REG_ITMP3, REG_PV, disp);
2835 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2836 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2839 /* interface instanceof code */
2841 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2842 if (super == NULL) {
2843 cr = iptr->sx.s23.s3.c.ref;
2845 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2849 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2852 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2853 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2854 M_CMP_IMM(REG_ITMP3, superindex);
2857 M_ALD(REG_ITMP1, REG_ITMP1,
2858 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2859 superindex * sizeof(methodptr*)));
2860 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2863 emit_label_br(cd, BRANCH_LABEL_4);
2865 emit_label(cd, BRANCH_LABEL_3);
2868 /* class instanceof code */
2870 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2871 if (super == NULL) {
2872 emit_label(cd, BRANCH_LABEL_2);
2874 cr = iptr->sx.s23.s3.c.ref;
2875 disp = dseg_add_unique_address(cd, NULL);
2877 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2881 disp = dseg_add_address(cd, supervftbl);
2883 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2886 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2887 M_ALD(REG_ITMP2, REG_PV, disp);
2889 CODEGEN_CRITICAL_SECTION_START;
2891 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2892 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2893 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2895 CODEGEN_CRITICAL_SECTION_END;
2897 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2898 M_CMP(REG_ITMP1, REG_ITMP2);
2899 M_XCMOVULE_IMM(1, d);
2902 emit_label(cd, BRANCH_LABEL_5);
2905 if (super == NULL) {
2906 emit_label(cd, BRANCH_LABEL_1);
2907 emit_label(cd, BRANCH_LABEL_4);
2910 emit_store_dst(jd, iptr, d);
2914 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2916 /* check for negative sizes and copy sizes to stack if necessary */
2918 MCODECHECK((iptr->s1.argcount << 1) + 64);
2920 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2922 var = VAR(iptr->sx.s23.s2.args[s1]);
2924 /* copy SAVEDVAR sizes to stack */
2926 /* Already Preallocated? */
2928 if (!(var->flags & PREALLOC)) {
2929 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2930 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2934 /* arg 0 = dimension count */
2936 ICONST(REG_OUT0, iptr->s1.argcount);
2938 /* is patcher function set? */
2940 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2941 disp = dseg_add_unique_address(cd, 0);
2943 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2944 iptr->sx.s23.s3.c.ref,
2948 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2950 /* arg 1 = arraydescriptor */
2952 M_ALD(REG_OUT1, REG_PV, disp);
2954 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2956 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2958 /* XXX c abi call */
2959 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2960 M_ALD(REG_ITMP3, REG_PV, disp);
2961 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2964 /* check for exception before result assignment */
2966 emit_exception_check(cd, iptr);
2968 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2969 M_INTMOVE(REG_RESULT_CALLER, d);
2970 emit_store_dst(jd, iptr, d);
2974 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2980 } /* for instruction */
2984 /* At the end of a basic block we may have to append some nops,
2985 because the patcher stub calling code might be longer than the
2986 actual instruction. So codepatching does not change the
2987 following block unintentionally. */
2989 if (cd->mcodeptr < cd->lastmcodeptr) {
2990 while (cd->mcodeptr < cd->lastmcodeptr) {
2995 } /* if (bptr -> flags >= BBREACHED) */
2996 } /* for basic block */
2998 dseg_createlinenumbertable(cd);
3000 /* generate stubs */
3002 emit_patcher_stubs(jd);
3003 REPLACEMENT_EMIT_STUBS(jd);
3005 /* everything's ok */
3011 /* codegen_emit_stub_compiler **************************************************
3013 Emits a stub routine which calls the compiler.
3015 *******************************************************************************/
3017 void codegen_emit_stub_compiler(jitdata *jd)
3022 /* get required compiler data */
3027 /* code for the stub */
3029 /* no window save yet, user caller's PV */
3030 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3031 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3032 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3037 /* codegen_emit_stub_native ****************************************************
3039 Emits a stub routine which calls a native method.
3041 *******************************************************************************/
3043 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3050 s4 i, j; /* count variables */
3053 s4 funcdisp; /* displacement of the function */
3054 s4 fltregarg_offset[FLT_ARG_CNT];
3056 /* get required compiler data */
3062 /* initialize variables */
3065 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3067 /* calculate stack frame size */
3069 cd->stackframesize =
3070 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3071 sizeof(localref_table) / SIZEOF_VOID_P +
3072 md->paramcount + /* for saving arguments over calls */
3073 nmd->memuse + /* nmd knows about the native stackframe layout */
3077 /* keep stack 16-byte aligned (ABI requirement) */
3079 if (cd->stackframesize & 1)
3080 cd->stackframesize++;
3082 /* create method header */
3084 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3085 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3086 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3087 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3088 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3089 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3090 (void) dseg_addlinenumbertablesize(cd);
3091 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3093 /* generate stub code */
3095 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3097 #if !defined(NDEBUG)
3098 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3099 emit_verbosecall_enter(jd);
3102 /* get function address (this must happen before the stackframeinfo) */
3104 funcdisp = dseg_add_functionptr(cd, f);
3106 #if !defined(WITH_STATIC_CLASSPATH)
3108 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3112 /* save float argument registers (into abi parameter slots) */
3114 assert(ABIPARAMS_CNT >= FLT_ARG_CNT);
3116 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3117 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3118 s1 = WINSAVE_CNT + nmd->memuse + j;
3119 M_DST(abi_registers_float_argument[i], REG_SP, BIAS + (s1*8));
3120 fltregarg_offset[i] = s1; /* remember stack offset */
3125 /* prepare data structures for native function call */
3127 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute, ie. + BIAS) */
3128 M_MOV(REG_PV_CALLEE, REG_OUT1);
3129 M_MOV(REG_FP, REG_OUT2); /* java sp */
3130 M_MOV(REG_RA_CALLEE, REG_OUT3);
3131 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3132 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3133 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3134 M_NOP; /* XXX fill me! */
3136 /* keep float arguments on stack */
3138 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3139 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3140 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3146 /* copy or spill arguments to new locations */
3148 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3149 t = md->paramtypes[i].type;
3151 if (IS_INT_LNG_TYPE(t)) {
3153 /* integral types */
3155 if (!md->params[i].inmemory) {
3156 s1 = md->params[i].regoff;
3157 /* s1 refers to the old window, transpose */
3158 s1 = REG_WINDOW_TRANSPOSE(s1);
3160 if (!nmd->params[j].inmemory) {
3161 s2 = nat_argintregs[nmd->params[j].regoff];
3164 s2 = nmd->params[j].regoff - 6;
3165 M_AST(s1, REG_SP, CSTACK + s2 * 8);
3169 if (!nmd->params[j].inmemory) {
3170 /* JIT stack arg -> NAT reg arg */
3172 /* Due to the Env pointer that is always passed, the 6th JIT arg */
3173 /* is the 7th (or 8th w/ class ptr) NAT arg, and goes to the stack */
3175 assert(false); /* path never taken */
3178 s1 = md->params[i].regoff + cd->stackframesize;
3179 s2 = nmd->params[j].regoff - 6;
3180 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3181 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3186 /* floating point types */
3188 if (!md->params[i].inmemory) {
3189 s1 = md->params[i].regoff;
3191 if (!nmd->params[j].inmemory) {
3193 /* no mapping to regs needed, native flt args use regoff */
3194 s2 = nmd->params[j].regoff;
3196 /* JIT float regs are still on the stack */
3197 M_DLD(s2, REG_SP, BIAS + (fltregarg_offset[i] * 8));
3200 /* not supposed to happen with 16 NAT flt args */
3203 s2 = nmd->params[j].regoff;
3204 if (IS_2_WORD_TYPE(t))
3205 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3207 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3213 s1 = md->params[i].regoff + cd->stackframesize;
3215 if (!nmd->params[j].inmemory) {
3217 /* JIT stack -> NAT reg */
3219 s2 = nmd->params[j].regoff;
3220 M_DLD(s2, REG_SP, CSTACK + s1 * 8);
3224 /* JIT stack -> NAT stack */
3226 s2 = nmd->params[j].regoff - 6;
3228 /* The FTMP register may already be loaded with args */
3229 /* we know $f0 is unused because of the env pointer */
3230 M_DLD(REG_F0, REG_SP, CSTACK + s1 * 8);
3231 M_DST(REG_F0, REG_SP, CSTACK + s2 * 8);
3238 /* put class into second argument register */
3240 if (m->flags & ACC_STATIC) {
3241 disp = dseg_add_address(cd, m->class);
3242 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3245 /* put env into first argument register */
3247 disp = dseg_add_address(cd, _Jv_env);
3248 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3250 /* do the native function call */
3252 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3253 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3254 M_NOP; /* delay slot */
3256 /* save return value */
3258 if (md->returntype.type != TYPE_VOID) {
3259 if (IS_INT_LNG_TYPE(md->returntype.type))
3260 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3262 M_DST(REG_FRESULT, REG_SP, CSTACK);
3265 /* Note: native functions return float values in %f0 (see ABI) */
3266 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3268 #if !defined(NDEBUG)
3269 /* But for the trace function we need to put a flt result into %f1 */
3270 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3271 if (!IS_2_WORD_TYPE(md->returntype.type))
3272 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3273 emit_verbosecall_exit(jd);
3277 /* remove native stackframe info */
3279 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3280 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3281 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3282 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3283 M_NOP; /* XXX fill me! */
3284 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3286 /* restore float return value, int return value already in our return reg */
3288 if (md->returntype.type != TYPE_VOID) {
3289 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3290 if (IS_2_WORD_TYPE(md->returntype.type))
3291 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3293 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3297 /* check for exception */
3298 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3301 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3304 /* handle exception */
3306 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3307 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3308 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3309 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3310 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3312 /* generate patcher stubs */
3314 emit_patcher_stubs(jd);
3318 * These are local overrides for various environment variables in Emacs.
3319 * Please do not remove this and leave it at the end of the file, where
3320 * Emacs will automagically detect them.
3321 * ---------------------------------------------------------------------
3324 * indent-tabs-mode: t
3328 * vim:noexpandtab:sw=4:ts=4: