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"
65 /* XXX use something like this for window control ?
66 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
68 #define REG_PV REG_PV_CALLEE
73 if ((disp < -4096) || (disp > 4095))
74 printf("disp %d\n", disp);
77 return (disp >= -4096) && (disp <= 4095);
80 s4 get_lopart_disp(disp)
85 lodisp = setlo_part(disp);
87 if (setlo_part(disp) == 0)
90 lodisp = setlo_part(disp) | 0x1c00;
97 /* codegen_emit ****************************************************************
99 Generates machine code.
101 *******************************************************************************/
103 bool codegen_emit(jitdata *jd)
109 s4 len, s1, s2, s3, d, disp;
115 constant_classref *cr;
116 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
117 unresolved_method *um;
118 builtintable_entry *bte;
121 unresolved_field *uf;
125 /* get required compiler data */
132 /* prevent compiler warnings */
141 s4 savedregs_num, localbase;
143 #if 0 /* no leaf optimization yet */
144 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
146 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
149 /* space to save used callee saved registers */
151 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
152 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
154 cd->stackframesize = rd->memuse + savedregs_num;
156 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
157 if (checksync && (m->flags & ACC_SYNCHRONIZED))
158 cd->stackframesize++;
161 /* keep stack 16-byte aligned (ABI requirement) */
163 if (cd->stackframesize & 1)
164 cd->stackframesize++;
166 /* create method header */
168 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
169 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
171 #if defined(ENABLE_THREADS)
172 /* IsSync contains the offset relative to the stack pointer for the
173 argument of monitor_exit used in the exception handler. Since the
174 offset could be zero and give a wrong meaning of the flag it is
178 if (checksync && (m->flags & ACC_SYNCHRONIZED))
179 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
182 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
184 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
185 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
186 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
187 dseg_addlinenumbertablesize(cd);
188 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
190 /* create exception table */
192 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
193 dseg_add_target(cd, ex->start);
194 dseg_add_target(cd, ex->end);
195 dseg_add_target(cd, ex->handler);
196 (void) dseg_add_unique_address(cd, ex->catchtype.any);
199 /* save register window and create stack frame (if necessary) */
201 if (cd->stackframesize)
202 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
205 /* save callee saved float registers (none right now) */
207 p = cd->stackframesize;
208 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
209 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
214 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
215 emit_verbosecall_enter(jd);
220 /* take arguments out of register or stack frame */
224 /* when storing locals, use this as base */
225 localbase = JITSTACK;
227 /* since the register allocator does not know about the shifting window
228 * arg regs need to be copied via the stack
230 if (md->argintreguse > 0) {
231 /* allocate scratch space for copying in to save(i&l) regs */
232 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
234 localbase += INT_ARG_CNT * 8;
236 /* XXX could use the param slots on the stack for this! */
237 for (p = 0; p < INT_ARG_CNT; p++)
238 M_STX(REG_WINDOW_TRANSPOSE(abi_registers_integer_argument[p]), REG_SP, JITSTACK + (p * 8));
242 for (p = 0, l = 0; p < md->paramcount; p++) {
243 t = md->paramtypes[p].type;
245 varindex = jd->local_map[l * 5 + t];
248 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
251 if (varindex == UNUSED)
255 s1 = md->params[p].regoff;
257 if (IS_INT_LNG_TYPE(t)) { /* integer args */
259 if (!md->params[p].inmemory) { /* register arguments */
260 /*s2 = rd->argintregs[s1];*/
261 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
263 /* need the argument index here, not the register number */
264 s1 = md->params[p].regoff - abi_registers_integer_argument[0];
266 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
267 /*M_INTMOVE(s2, var->vv.regoff);*/
268 M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 8));
270 } else { /* reg arg -> spilled */
271 /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
273 M_LDX(REG_ITMP1, REG_SP, JITSTACK + (s1 * 8));
274 M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
277 } else { /* stack arguments */
278 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
279 M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
281 } else { /* stack arg -> spilled */
282 /* add the callers window save registers */
283 var->vv.regoff = cd->stackframesize + s1;
287 } else { /* floating args */
288 if (!md->params[p].inmemory) { /* register arguments */
289 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
290 M_FLTMOVE(s1, var->vv.regoff);
292 } else { /* reg arg -> spilled */
293 M_DST(s1, REG_SP, localbase + (var->vv.regoff) * 8);
296 } else { /* stack arguments */
297 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
298 M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
300 } else { /* stack-arg -> spilled */
301 var->vv.regoff = cd->stackframesize + s1;
307 if (md->argintreguse > 0) {
308 /* release scratch space */
309 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
313 /* XXX monitor enter */
320 /* end of header generation */
322 /* create replacement points */
324 REPLACEMENT_POINTS_INIT(cd, jd);
326 /* walk through all basic blocks */
328 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
330 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
332 if (bptr->flags >= BBREACHED) {
334 /* branch resolving */
336 codegen_resolve_branchrefs(cd, bptr);
338 /* handle replacement points */
341 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
342 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
348 /* copy interface registers to their destination */
353 #if defined(ENABLE_LSRA)
354 #error XXX LSRA not tested yet
358 src = bptr->invars[len];
359 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
360 /* d = reg_of_var(m, src, REG_ITMP1); */
361 if (!(src->flags & INMEMORY))
365 M_INTMOVE(REG_ITMP1, d);
366 emit_store(jd, NULL, src, d);
373 var = VAR(bptr->invars[len]);
374 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
375 d = codegen_reg_of_var(0, var, REG_ITMP1);
376 M_INTMOVE(REG_ITMP2_XPTR, d);
377 emit_store(jd, NULL, var, d);
380 assert((var->flags & INOUT));
383 #if defined(ENABLE_LSRA)
386 /* walk through all instructions */
390 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
391 if (iptr->line != currentline) {
392 dseg_addlinenumber(cd, iptr->line);
393 currentline = iptr->line;
396 MCODECHECK(64); /* an instruction usually needs < 64 words */
400 case ICMD_INLINE_START:
401 case ICMD_INLINE_END:
404 case ICMD_NOP: /* ... ==> ... */
407 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
409 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
410 emit_nullpointer_check(cd, iptr, s1);
413 /* constant operations ************************************************/
415 case ICMD_ICONST: /* ... ==> ..., constant */
417 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
418 ICONST(d, iptr->sx.val.i);
419 emit_store_dst(jd, iptr, d);
422 case ICMD_LCONST: /* ... ==> ..., constant */
424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
425 LCONST(d, iptr->sx.val.l);
426 emit_store_dst(jd, iptr, d);
429 case ICMD_FCONST: /* ... ==> ..., constant */
431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
432 disp = dseg_add_float(cd, iptr->sx.val.f);
433 M_FLD(d, REG_PV, disp);
434 emit_store_dst(jd, iptr, d);
437 case ICMD_DCONST: /* ... ==> ..., constant */
439 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
440 disp = dseg_add_double(cd, iptr->sx.val.d);
441 M_DLD(d, REG_PV, disp);
442 emit_store_dst(jd, iptr, d);
445 case ICMD_ACONST: /* ... ==> ..., constant */
447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
449 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
450 cr = iptr->sx.val.c.ref;
451 disp = dseg_add_unique_address(cd, cr);
453 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
455 M_ALD(d, REG_PV, disp);
459 if (iptr->sx.val.anyptr == NULL) {
460 M_INTMOVE(REG_ZERO, d);
463 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
464 M_ALD(d, REG_PV, disp);
467 emit_store_dst(jd, iptr, d);
471 /* load/store/copy/move operations ************************************/
473 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
478 case ICMD_ISTORE: /* ..., value ==> ... */
489 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
494 /* pop/dup/swap operations ********************************************/
496 /* attention: double and longs are only one entry in CACAO ICMDs */
498 case ICMD_POP: /* ..., value ==> ... */
499 case ICMD_POP2: /* ..., value, value ==> ... */
503 /* integer operations *************************************************/
505 case ICMD_INEG: /* ..., value ==> ..., - value */
508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
510 M_SUB(REG_ZERO, s1, d);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_I2L: /* ..., value ==> ..., value */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_L2I: /* ..., value ==> ..., value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
526 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
527 emit_store_dst(jd, iptr, d);
530 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
534 M_SLLX_IMM(s1, 56, d);
535 M_SRAX_IMM( d, 56, d);
536 emit_store_dst(jd, iptr, d);
539 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543 M_SLLX_IMM(s1, 48, d);
544 M_SRLX_IMM( d, 48, d);
545 emit_store_dst(jd, iptr, d);
548 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552 M_SLLX_IMM(s1, 48, d);
553 M_SRAX_IMM( d, 48, d);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 emit_store_dst(jd, iptr, d);
568 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
569 /* sx.val.i = constant */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
574 M_ADD_IMM(s1, iptr->sx.val.i, d);
576 ICONST(REG_ITMP2, iptr->sx.val.i);
577 M_ADD(s1, REG_ITMP2, d);
579 emit_store_dst(jd, iptr, d);
582 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
583 /* sx.val.l = constant */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
588 M_ADD_IMM(s1, iptr->sx.val.l, d);
590 LCONST(REG_ITMP2, iptr->sx.val.l);
591 M_ADD(s1, REG_ITMP2, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
607 /* sx.val.i = constant */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
612 M_SUB_IMM(s1, iptr->sx.val.i, d);
614 ICONST(REG_ITMP2, iptr->sx.val.i);
615 M_SUB(s1, REG_ITMP2, d);
617 emit_store_dst(jd, iptr, d);
620 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
621 /* sx.val.l = constant */
623 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
626 M_SUB_IMM(s1, iptr->sx.val.l, d);
628 LCONST(REG_ITMP2, iptr->sx.val.l);
629 M_SUB(s1, REG_ITMP2, d);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 emit_store_dst(jd, iptr, d);
644 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
645 /* sx.val.i = constant */
647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
650 M_MULX_IMM(s1, iptr->sx.val.i, d);
652 ICONST(REG_ITMP2, iptr->sx.val.i);
653 M_MULX(s1, REG_ITMP2, d);
655 emit_store_dst(jd, iptr, d);
658 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
659 /* sx.val.l = constant */
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
663 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
664 M_MULX_IMM(s1, iptr->sx.val.l, d);
666 LCONST(REG_ITMP2, iptr->sx.val.l);
667 M_MULX(s1, REG_ITMP2, d);
669 emit_store_dst(jd, iptr, d);
672 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
673 /* XXX could also clear Y and use 32bit div */
674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 emit_arithmetic_check(cd, iptr, s2);
679 /* XXX trim s2 like s1 ? */
681 emit_store_dst(jd, iptr, d);
684 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
689 emit_arithmetic_check(cd, iptr, s2);
691 emit_store_dst(jd, iptr, d);
694 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
699 emit_arithmetic_check(cd, iptr, s2);
701 /* XXX trim s2 like s1 ? */
702 M_DIVX(s1, s2, REG_ITMP3);
703 M_MULX(s2, REG_ITMP3, REG_ITMP3);
704 M_SUB(s1, REG_ITMP3, d);
705 emit_store_dst(jd, iptr, d);
708 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
711 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
712 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
713 emit_arithmetic_check(cd, iptr, s2);
714 M_DIVX(s1, s2, REG_ITMP3);
715 M_MULX(s2, REG_ITMP3, REG_ITMP3);
716 M_SUB(s1, REG_ITMP3, d);
717 emit_store_dst(jd, iptr, d);
720 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
721 case ICMD_LDIVPOW2: /* val.i = constant */
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
725 M_SRAX_IMM(s1, 63, REG_ITMP2);
726 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
727 M_ADD(s1, REG_ITMP2, REG_ITMP2);
728 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
729 emit_store_dst(jd, iptr, d);
732 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
738 emit_store_dst(jd, iptr, d);
741 case ICMD_LSHL: /* ..., 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_ITMP2);
747 emit_store_dst(jd, iptr, d);
750 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
751 /* val.i = constant */
753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
755 M_SLL_IMM(s1, iptr->sx.val.i, d);
756 emit_store_dst(jd, iptr, d);
759 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
760 /* val.i = constant */
762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
763 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764 M_SLLX_IMM(s1, iptr->sx.val.i, d);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774 emit_store_dst(jd, iptr, d);
777 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
778 /* sx.val.i = constant */
780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
782 M_SRA_IMM(s1, iptr->sx.val.i, d);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
789 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792 emit_store_dst(jd, iptr, d);
795 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
796 /* sx.val.i = constant */
798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
800 M_SRL_IMM(s1, iptr->sx.val.i, d);
801 emit_store_dst(jd, iptr, d);
804 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
814 /* sx.val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
818 M_SRAX_IMM(s1, iptr->sx.val.i, d);
819 emit_store_dst(jd, iptr, d);
822 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
832 /* sx.val.i = constant */
834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
836 M_SRLX_IMM(s1, iptr->sx.val.i, d);
837 emit_store_dst(jd, iptr, d);
840 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
843 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
844 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
845 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
847 emit_store_dst(jd, iptr, d);
850 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
851 /* sx.val.i = constant */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
856 M_AND_IMM(s1, iptr->sx.val.i, d);
858 ICONST(REG_ITMP2, iptr->sx.val.i);
859 M_AND(s1, REG_ITMP2, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
865 /* sx.val.i = constant */
866 /* constant is actually constant - 1 */
868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 M_MOV(s1, REG_ITMP1);
874 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
875 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
876 M_AND_IMM(s1, iptr->sx.val.i, d);
879 M_SUB(REG_ZERO, s1, d);
880 M_AND_IMM(d, iptr->sx.val.i, d);
882 ICONST(REG_ITMP2, iptr->sx.val.i);
883 M_AND(s1, REG_ITMP2, d);
886 M_SUB(REG_ZERO, s1, d);
887 M_AND(d, REG_ITMP2, d);
889 M_SUB(REG_ZERO, d, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
894 /* sx.val.l = constant */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
899 M_AND_IMM(s1, iptr->sx.val.l, d);
901 LCONST(REG_ITMP2, iptr->sx.val.l);
902 M_AND(s1, REG_ITMP2, d);
904 emit_store_dst(jd, iptr, d);
907 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
908 /* sx.val.l = constant */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913 M_MOV(s1, REG_ITMP1);
916 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
917 M_AND_IMM(s1, iptr->sx.val.l, d);
920 M_SUB(REG_ZERO, s1, d);
921 M_AND_IMM(d, iptr->sx.val.l, d);
923 LCONST(REG_ITMP2, iptr->sx.val.l);
924 M_AND(s1, REG_ITMP2, d);
927 M_SUB(REG_ZERO, s1, d);
928 M_AND(d, REG_ITMP2, d);
930 M_SUB(REG_ZERO, d, d);
931 emit_store_dst(jd, iptr, d);
934 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
938 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
939 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
941 emit_store_dst(jd, iptr, d);
944 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
945 /* sx.val.i = constant */
947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
948 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
949 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
950 M_OR_IMM(s1, iptr->sx.val.i, d);
952 ICONST(REG_ITMP2, iptr->sx.val.i);
953 M_OR(s1, REG_ITMP2, d);
955 emit_store_dst(jd, iptr, d);
958 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
959 /* sx.val.l = constant */
961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
963 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
964 M_OR_IMM(s1, iptr->sx.val.l, d);
966 LCONST(REG_ITMP2, iptr->sx.val.l);
967 M_OR(s1, REG_ITMP2, d);
969 emit_store_dst(jd, iptr, d);
972 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
976 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
977 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
983 /* sx.val.i = constant */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
988 M_XOR_IMM(s1, iptr->sx.val.i, d);
990 ICONST(REG_ITMP2, iptr->sx.val.i);
991 M_XOR(s1, REG_ITMP2, d);
993 emit_store_dst(jd, iptr, d);
996 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
997 /* sx.val.l = constant */
999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1000 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1001 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1002 M_XOR_IMM(s1, iptr->sx.val.l, d);
1004 LCONST(REG_ITMP2, iptr->sx.val.l);
1005 M_XOR(s1, REG_ITMP2, d);
1007 emit_store_dst(jd, iptr, d);
1011 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1014 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1018 M_XCMOVLT_IMM(-1, d);
1019 M_XCMOVGT_IMM(1, d);
1020 emit_store_dst(jd, iptr, d);
1024 /* floating operations ************************************************/
1026 case ICMD_FNEG: /* ..., value ==> ..., - value */
1028 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1029 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1031 emit_store_dst(jd, iptr, d);
1034 case ICMD_DNEG: /* ..., value ==> ..., - value */
1036 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1037 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1039 emit_store_dst(jd, iptr, d);
1042 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1044 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1045 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1046 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1053 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1054 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1055 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1062 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1063 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1064 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1071 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1072 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1073 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1075 emit_store_dst(jd, iptr, d);
1078 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1080 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1081 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1082 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1089 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1090 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1091 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1093 emit_store_dst(jd, iptr, d);
1096 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1098 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1099 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1100 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1107 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1108 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1109 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1111 emit_store_dst(jd, iptr, d);
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1117 disp = dseg_add_float(cd, 0.0);
1118 M_IST (s1, REG_PV_CALLEE, disp);
1119 M_FLD (d, REG_PV_CALLEE, disp);
1120 M_CVTIF (d, d); /* rd gets translated to double target register */
1121 emit_store_dst(jd, iptr, d);
1125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1126 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1127 disp = dseg_add_float(cd, 0.0);
1128 M_IST(s1, REG_PV_CALLEE, disp);
1129 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1130 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1131 emit_store_dst(jd, iptr, d);
1135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1136 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1137 disp = dseg_add_double(cd, 0.0);
1138 M_STX(s1, REG_PV_CALLEE, disp);
1139 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1140 M_CVTLF(REG_FTMP3, d);
1141 emit_store_dst(jd, iptr, d);
1145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1146 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1147 disp = dseg_add_double(cd, 0.0);
1148 M_STX(s1, REG_PV_CALLEE, disp);
1149 M_DLD(d, REG_PV_CALLEE, disp);
1151 emit_store_dst(jd, iptr, d);
1154 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1155 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1156 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1157 disp = dseg_add_float(cd, 0.0);
1158 M_CVTFI(s1, REG_FTMP2);
1159 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1160 M_ILD(d, REG_PV, disp);
1161 emit_store_dst(jd, iptr, d);
1165 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1168 disp = dseg_add_float(cd, 0.0);
1169 M_CVTDI(s1, REG_FTMP2);
1170 M_FST(REG_FTMP2, REG_PV, disp);
1171 M_ILD(d, REG_PV, disp);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1176 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1178 disp = dseg_add_double(cd, 0.0);
1179 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1180 M_DST(REG_FTMP2, REG_PV, disp);
1181 M_LDX(d, REG_PV, disp);
1182 emit_store_dst(jd, iptr, d);
1185 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1186 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1188 disp = dseg_add_double(cd, 0.0);
1189 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1190 M_DST(REG_FTMP2, REG_PV, disp);
1191 M_LDX(d, REG_PV, disp);
1192 emit_store_dst(jd, iptr, d);
1195 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1197 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1198 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1205 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1206 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1208 emit_store_dst(jd, iptr, d);
1211 /* XXX merge F/D versions? only compare instr. is different */
1212 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1214 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1215 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1216 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1218 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1219 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1220 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1221 emit_store_dst(jd, iptr, d);
1224 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1226 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1227 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1228 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1230 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1231 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1232 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1233 emit_store_dst(jd, iptr, d);
1236 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1238 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1239 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1240 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1242 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1243 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1244 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1245 emit_store_dst(jd, iptr, d);
1248 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1250 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1251 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1254 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1255 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1256 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1257 emit_store_dst(jd, iptr, d);
1261 /* memory operations **************************************************/
1263 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1267 emit_nullpointer_check(cd, iptr, s1);
1268 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1274 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1275 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1276 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1277 /* implicit null-pointer check */
1278 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1279 M_AADD(s2, s1, REG_ITMP3);
1280 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1286 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1287 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1288 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1289 /* implicit null-pointer check */
1290 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1291 M_AADD(s2, s1, REG_ITMP3);
1292 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1293 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1294 emit_store_dst(jd, iptr, d);
1297 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1300 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1301 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1302 /* implicit null-pointer check */
1303 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1304 M_AADD(s2, s1, REG_ITMP3);
1305 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1306 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_IALOAD: /* ..., 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_ASLL_IMM(s2, 2, REG_ITMP3);
1318 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1319 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_LALOAD: /* ..., 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_ASLL_IMM(s2, 3, REG_ITMP3);
1331 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1332 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_FALOAD: /* ..., 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_FTMP1);
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_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_DALOAD: /* ..., 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_FTMP1);
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_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_AALOAD: /* ..., 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_ITMP2);
1367 /* implicit null-pointer check */
1368 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1370 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1371 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1372 emit_store_dst(jd, iptr, d);
1376 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1378 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1379 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1380 /* implicit null-pointer check */
1381 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1382 M_AADD(s2, s1, REG_ITMP1);
1383 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1384 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1387 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1388 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1391 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1392 /* implicit null-pointer check */
1393 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1394 M_AADD(s2, s1, REG_ITMP1);
1395 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1396 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1397 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1400 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404 /* implicit null-pointer check */
1405 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1406 M_ASLL_IMM(s2, 2, REG_ITMP2);
1407 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1408 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1409 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1412 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1415 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416 /* implicit null-pointer check */
1417 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1418 M_ASLL_IMM(s2, 3, REG_ITMP2);
1419 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1420 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1421 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1424 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1427 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1428 /* implicit null-pointer check */
1429 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1430 M_ASLL_IMM(s2, 2, REG_ITMP2);
1431 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1432 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1433 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1436 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1440 /* implicit null-pointer check */
1441 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1442 M_ASLL_IMM(s2, 3, REG_ITMP2);
1443 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1444 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1445 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1449 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1451 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1452 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1453 /* implicit null-pointer check */
1454 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1455 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1457 M_MOV(s1, REG_OUT0);
1458 M_MOV(s3, REG_OUT1);
1459 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1460 M_ALD(REG_ITMP3, REG_PV, disp);
1461 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1463 emit_exception_check(cd, iptr);
1465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1468 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1469 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1470 /* implicit null-pointer check */
1471 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1475 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
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 M_AADD(s2, s1, REG_ITMP1);
1482 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1485 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1486 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1489 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1490 /* implicit null-pointer check */
1491 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1492 M_AADD(s2, s1, REG_ITMP1);
1493 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1494 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1497 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1500 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1501 /* implicit null-pointer check */
1502 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1503 M_ASLL_IMM(s2, 2, REG_ITMP2);
1504 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1505 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1508 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512 /* implicit null-pointer check */
1513 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1514 M_ASLL_IMM(s2, 3, REG_ITMP2);
1515 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1516 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1519 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1523 /* implicit null-pointer check */
1524 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1525 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1526 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1527 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1531 case ICMD_GETSTATIC: /* ... ==> ..., value */
1533 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1534 uf = iptr->sx.s23.s3.uf;
1535 fieldtype = uf->fieldref->parseddesc.fd->type;
1536 disp = dseg_add_unique_address(cd, uf);
1538 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1541 fi = iptr->sx.s23.s3.fmiref->p.field;
1542 fieldtype = fi->type;
1543 disp = dseg_add_address(cd, &(fi->value));
1545 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1546 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1549 M_ALD(REG_ITMP1, REG_PV, disp);
1551 switch (fieldtype) {
1553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1554 M_ILD_INTERN(d, REG_ITMP1, 0);
1557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1558 M_LDX_INTERN(d, REG_ITMP1, 0);
1561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1562 M_ALD_INTERN(d, REG_ITMP1, 0);
1565 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1566 M_FLD_INTERN(d, REG_ITMP1, 0);
1569 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1570 M_DLD_INTERN(d, REG_ITMP1, 0);
1573 emit_store_dst(jd, iptr, d);
1576 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1578 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1579 uf = iptr->sx.s23.s3.uf;
1580 fieldtype = uf->fieldref->parseddesc.fd->type;
1581 disp = dseg_add_unique_address(cd, uf);
1583 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1586 fi = iptr->sx.s23.s3.fmiref->p.field;
1587 fieldtype = fi->type;
1588 disp = dseg_add_address(cd, &(fi->value));
1590 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1591 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1594 M_ALD(REG_ITMP1, REG_PV, disp);
1596 switch (fieldtype) {
1598 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1599 M_IST_INTERN(s1, REG_ITMP1, 0);
1602 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1603 M_STX_INTERN(s1, REG_ITMP1, 0);
1606 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1607 M_AST_INTERN(s1, REG_ITMP1, 0);
1610 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1611 M_FST_INTERN(s1, REG_ITMP1, 0);
1614 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1615 M_DST_INTERN(s1, REG_ITMP1, 0);
1620 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1621 /* val = value (in current instruction) */
1622 /* following NOP) */
1624 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1625 uf = iptr->sx.s23.s3.uf;
1626 fieldtype = uf->fieldref->parseddesc.fd->type;
1627 disp = dseg_add_unique_address(cd, uf);
1629 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1632 fi = iptr->sx.s23.s3.fmiref->p.field;
1633 fieldtype = fi->type;
1634 disp = dseg_add_address(cd, &(fi->value));
1636 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1637 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1640 M_ALD(REG_ITMP1, REG_PV, disp);
1642 switch (fieldtype) {
1644 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1647 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1650 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1653 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1656 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1662 case ICMD_GETFIELD: /* ... ==> ..., value */
1664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665 emit_nullpointer_check(cd, iptr, s1);
1667 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1668 uf = iptr->sx.s23.s3.uf;
1670 fieldtype = uf->fieldref->parseddesc.fd->type;
1673 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1676 fi = iptr->sx.s23.s3.fmiref->p.field;
1677 fieldtype = fi->type;
1681 switch (fieldtype) {
1683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1695 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1699 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1706 emit_store_dst(jd, iptr, d);
1709 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 emit_nullpointer_check(cd, iptr, s1);
1714 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1715 uf = iptr->sx.s23.s3.uf;
1716 fieldtype = uf->fieldref->parseddesc.fd->type;
1721 fi = iptr->sx.s23.s3.fmiref->p.field;
1722 fieldtype = fi->type;
1726 if (IS_INT_LNG_TYPE(fieldtype))
1727 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1729 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1731 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1732 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1734 switch (fieldtype) {
1736 M_IST(s2, s1, disp);
1739 M_STX(s2, s1, disp);
1742 M_AST(s2, s1, disp);
1745 M_FST(s2, s1, disp);
1748 M_DST(s2, s1, disp);
1756 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1757 /* val = value (in current instruction) */
1758 /* following NOP) */
1760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1761 emit_nullpointer_check(cd, iptr, s1);
1763 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1764 unresolved_field *uf = iptr->sx.s23.s3.uf;
1766 fieldtype = uf->fieldref->parseddesc.fd->type;
1768 codegen_addpatchref(cd, PATCHER_get_putfield,
1771 if (opt_showdisassemble) {
1779 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1781 fieldtype = fi->type;
1787 switch (fieldtype) {
1789 M_IST(REG_ZERO, s1, disp);
1792 M_STX(REG_ZERO, s1, disp);
1795 M_AST(REG_ZERO, s1, disp);
1798 M_FST(REG_ZERO, s1, disp);
1801 M_DST(REG_ZERO, s1, disp);
1807 /* branch operations **************************************************/
1809 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1812 M_INTMOVE(s1, REG_ITMP2_XPTR);
1814 #ifdef ENABLE_VERIFIER
1815 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1816 unresolved_class *uc = iptr->sx.s23.s2.uc;
1818 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1820 #endif /* ENABLE_VERIFIER */
1822 disp = dseg_add_functionptr(cd, asm_handle_exception);
1823 M_ALD(REG_ITMP1, REG_PV, disp);
1824 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1826 M_NOP; /* nop ensures that XPC is less than the end */
1827 /* of basic block */
1831 case ICMD_GOTO: /* ... ==> ... */
1832 case ICMD_RET: /* ... ==> ... */
1834 emit_br(cd, iptr->dst.block);
1838 case ICMD_JSR: /* ... ==> ... */
1840 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1844 case ICMD_IFNULL: /* ..., value ==> ... */
1845 case ICMD_IFNONNULL:
1847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1851 /* Note: int compares must not branch on the register directly. */
1852 /* Reason is, that register content is not 32-bit clean. */
1854 case ICMD_IFEQ: /* ..., value ==> ... */
1856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1858 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1859 M_CMP_IMM(s1, iptr->sx.val.i);
1862 ICONST(REG_ITMP2, iptr->sx.val.i);
1863 M_CMP(s1, REG_ITMP2);
1865 emit_beq(cd, iptr->dst.block);
1868 case ICMD_IFLT: /* ..., value ==> ... */
1870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1872 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1873 M_CMP_IMM(s1, iptr->sx.val.i);
1876 ICONST(REG_ITMP2, iptr->sx.val.i);
1877 M_CMP(s1, REG_ITMP2);
1879 emit_blt(cd, iptr->dst.block);
1882 case ICMD_IFLE: /* ..., value ==> ... */
1884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1886 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1887 M_CMP_IMM(s1, iptr->sx.val.i);
1890 ICONST(REG_ITMP2, iptr->sx.val.i);
1891 M_CMP(s1, REG_ITMP2);
1893 emit_ble(cd, iptr->dst.block);
1896 case ICMD_IFNE: /* ..., value ==> ... */
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1900 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1901 M_CMP_IMM(s1, iptr->sx.val.i);
1904 ICONST(REG_ITMP2, iptr->sx.val.i);
1905 M_CMP(s1, REG_ITMP2);
1907 emit_bne(cd, iptr->dst.block);
1910 case ICMD_IFGT: /* ..., value ==> ... */
1912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1914 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1915 M_CMP_IMM(s1, iptr->sx.val.i);
1918 ICONST(REG_ITMP2, iptr->sx.val.i);
1919 M_CMP(s1, REG_ITMP2);
1921 emit_bgt(cd, iptr->dst.block);
1924 case ICMD_IFGE: /* ..., value ==> ... */
1926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1928 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1929 M_CMP_IMM(s1, iptr->sx.val.i);
1932 ICONST(REG_ITMP2, iptr->sx.val.i);
1933 M_CMP(s1, REG_ITMP2);
1935 emit_bge(cd, iptr->dst.block);
1938 case ICMD_IF_LEQ: /* ..., value ==> ... */
1940 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1941 if (iptr->sx.val.l == 0)
1942 emit_beqz(cd, iptr->dst.block, s1);
1944 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1945 M_CMP_IMM(s1, iptr->sx.val.l);
1948 LCONST(REG_ITMP2, iptr->sx.val.l);
1949 M_CMP(s1, REG_ITMP2);
1951 emit_beq_xcc(cd, iptr->dst.block);
1955 case ICMD_IF_LLT: /* ..., value ==> ... */
1957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1958 if (iptr->sx.val.l == 0)
1959 emit_bltz(cd, iptr->dst.block, s1);
1961 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1962 M_CMP_IMM(s1, iptr->sx.val.l);
1965 LCONST(REG_ITMP2, iptr->sx.val.l);
1966 M_CMP(s1, REG_ITMP2);
1968 emit_blt_xcc(cd, iptr->dst.block);
1972 case ICMD_IF_LLE: /* ..., value ==> ... */
1974 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975 if (iptr->sx.val.l == 0)
1976 emit_blez(cd, iptr->dst.block, s1);
1978 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1979 M_CMP_IMM(s1, iptr->sx.val.l);
1982 LCONST(REG_ITMP2, iptr->sx.val.l);
1983 M_CMP(s1, REG_ITMP2);
1985 emit_ble_xcc(cd, iptr->dst.block);
1989 case ICMD_IF_LNE: /* ..., value ==> ... */
1991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1992 if (iptr->sx.val.l == 0)
1993 emit_bnez(cd, iptr->dst.block, s1);
1995 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1996 M_CMP_IMM(s1, iptr->sx.val.l);
1999 LCONST(REG_ITMP2, iptr->sx.val.l);
2000 M_CMP(s1, REG_ITMP2);
2002 emit_bne_xcc(cd, iptr->dst.block);
2006 case ICMD_IF_LGT: /* ..., value ==> ... */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009 if (iptr->sx.val.l == 0)
2010 emit_bgtz(cd, iptr->dst.block, s1);
2012 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2013 M_CMP_IMM(s1, iptr->sx.val.l);
2016 LCONST(REG_ITMP2, iptr->sx.val.l);
2017 M_CMP(s1, REG_ITMP2);
2019 emit_bgt_xcc(cd, iptr->dst.block);
2023 case ICMD_IF_LGE: /* ..., value ==> ... */
2025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2026 if (iptr->sx.val.l == 0)
2027 emit_bgez(cd, iptr->dst.block, s1);
2029 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2030 M_CMP_IMM(s1, iptr->sx.val.l);
2033 LCONST(REG_ITMP2, iptr->sx.val.l);
2034 M_CMP(s1, REG_ITMP2);
2036 emit_bge_xcc(cd, iptr->dst.block);
2041 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2042 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2044 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2045 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2047 emit_beq_xcc(cd, iptr->dst.block);
2050 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2055 emit_beq(cd, iptr->dst.block);
2058 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2059 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2061 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2062 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2064 emit_bne_xcc(cd, iptr->dst.block);
2067 case ICMD_IF_ICMPNE: /* 32-bit compare */
2069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2072 emit_bne(cd, iptr->dst.block);
2075 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2078 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2080 emit_blt_xcc(cd, iptr->dst.block);
2083 case ICMD_IF_ICMPLT: /* 32-bit compare */
2085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2086 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2088 emit_blt(cd, iptr->dst.block);
2091 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2096 emit_bgt_xcc(cd, iptr->dst.block);
2099 case ICMD_IF_ICMPGT: /* 32-bit compare */
2101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2102 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2104 emit_bgt(cd, iptr->dst.block);
2107 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2112 emit_ble_xcc(cd, iptr->dst.block);
2115 case ICMD_IF_ICMPLE: /* 32-bit compare */
2117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2118 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2120 emit_ble(cd, iptr->dst.block);
2124 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2129 emit_bge_xcc(cd, iptr->dst.block);
2132 case ICMD_IF_ICMPGE: /* 32-bit compare */
2134 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2135 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2137 emit_bge(cd, iptr->dst.block);
2141 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2144 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2145 M_INTMOVE(s1, REG_RESULT_CALLEE);
2146 goto nowperformreturn;
2148 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2150 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2151 M_INTMOVE(s1, REG_RESULT_CALLEE);
2153 #ifdef ENABLE_VERIFIER
2154 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2155 unresolved_class *uc = iptr->sx.s23.s2.uc;
2157 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2159 #endif /* ENABLE_VERIFIER */
2160 goto nowperformreturn;
2162 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2165 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2166 M_DBLMOVE(s1, REG_FRESULT);
2167 goto nowperformreturn;
2169 case ICMD_RETURN: /* ... ==> ... */
2175 p = cd->stackframesize;
2177 #if !defined(NDEBUG)
2178 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2179 emit_verbosecall_exit(jd);
2182 #if defined(ENABLE_THREADS)
2183 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2184 /* XXX: REG_RESULT is save, but what about FRESULT? */
2185 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2187 switch (iptr->opc) {
2190 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2194 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2195 M_ALD(REG_ITMP3, REG_PV, disp);
2196 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2198 switch (iptr->opc) {
2201 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2209 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2215 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2218 branch_target_t *table;
2220 table = iptr->dst.table;
2222 l = iptr->sx.s23.s2.tablelow;
2223 i = iptr->sx.s23.s3.tablehigh;
2225 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2227 M_INTMOVE(s1, REG_ITMP1);
2229 else if (l <= 4095) {
2230 M_ADD_IMM(s1, -l, REG_ITMP1);
2233 ICONST(REG_ITMP2, l);
2234 /* XXX: do I need to truncate s1 to 32-bit ? */
2235 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2243 M_CMP_IMM(REG_ITMP1, i - 1);
2246 ICONST(REG_ITMP2, i - 1);
2247 M_CMP(REG_ITMP1, REG_ITMP2);
2249 emit_bugt(cd, table[0].block); /* default target */
2251 /* build jump table top down and use address of lowest entry */
2256 dseg_add_target(cd, table->block);
2261 /* length of dataseg after last dseg_addtarget is used by load */
2263 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2264 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2265 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2266 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2271 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2274 lookup_target_t *lookup;
2276 lookup = iptr->dst.lookup;
2278 i = iptr->sx.s23.s2.lookupcount;
2280 MCODECHECK((i<<2)+8);
2281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2284 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2285 M_CMP_IMM(s1, lookup->value);
2287 ICONST(REG_ITMP2, lookup->value);
2288 M_CMP(s1, REG_ITMP2);
2290 emit_beq(cd, lookup->target.block);
2294 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2300 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2302 bte = iptr->sx.s23.s3.bte;
2305 /* XXX: builtin calling with stack arguments not implemented */
2306 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2308 s3 = md->paramcount;
2310 MCODECHECK((s3 << 1) + 64);
2312 /* copy float arguments according to ABI convention */
2314 int num_fltregargs = 0;
2315 int fltregarg_inswap[16];
2317 for (s3 = s3 - 1; s3 >= 0; s3--) {
2318 var = VAR(iptr->sx.s23.s2.args[s3]);
2320 if (IS_FLT_DBL_TYPE(var->type)) {
2321 if (!md->params[s3].inmemory) {
2322 s1 = s3; /*native flt args use argument index directly*/
2323 d = emit_load(jd, iptr, var, REG_FTMP1);
2326 fltregarg_inswap[num_fltregargs] = s1;
2328 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2337 /* move swapped float args to target regs */
2338 for (i = 0; i < num_fltregargs; i++) {
2339 s1 = fltregarg_inswap[i];
2340 M_DMOV(s1 + 16, s1);
2341 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2346 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2348 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2349 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2350 case ICMD_INVOKEINTERFACE:
2352 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2354 um = iptr->sx.s23.s3.um;
2355 md = um->methodref->parseddesc.md;
2358 lm = iptr->sx.s23.s3.fmiref->p.method;
2360 md = lm->parseddesc;
2364 s3 = md->paramcount;
2366 MCODECHECK((s3 << 1) + 64);
2368 /* copy arguments to registers or stack location */
2370 for (s3 = s3 - 1; s3 >= 0; s3--) {
2371 var = VAR(iptr->sx.s23.s2.args[s3]);
2372 d = md->params[s3].regoff;
2374 if (var->flags & PREALLOC)
2377 if (IS_INT_LNG_TYPE(var->type)) {
2378 if (!md->params[s3].inmemory) {
2379 s1 = emit_load(jd, iptr, var, d);
2383 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2384 M_STX(s1, REG_SP, JITSTACK + d * 8);
2388 if (iptr->opc == ICMD_BUILTIN)
2391 if (!md->params[s3].inmemory) {
2392 s1 = emit_load(jd, iptr, var, d);
2393 if (IS_2_WORD_TYPE(var->type))
2399 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2400 if (IS_2_WORD_TYPE(var->type))
2401 M_DST(s1, REG_SP, JITSTACK + d * 8);
2403 M_FST(s1, REG_SP, JITSTACK + d * 8);
2408 switch (iptr->opc) {
2410 disp = dseg_add_functionptr(cd, bte->fp);
2412 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2414 /* XXX jit-c-call */
2415 /* generate the actual call */
2417 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2419 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2420 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2421 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2423 emit_exception_check(cd, iptr);
2424 if (md->returntype.type == TYPE_FLT) {
2425 /* special handling for float return value in %f0 */
2430 case ICMD_INVOKESPECIAL:
2431 emit_nullpointer_check(cd, iptr, REG_OUT0);
2434 case ICMD_INVOKESTATIC:
2436 disp = dseg_add_unique_address(cd, NULL);
2438 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2442 disp = dseg_add_address(cd, lm->stubroutine);
2444 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2446 /* generate the actual call */
2448 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2450 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2451 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2452 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2455 case ICMD_INVOKEVIRTUAL:
2456 emit_nullpointer_check(cd, iptr, REG_OUT0);
2459 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2464 s1 = OFFSET(vftbl_t, table[0]) +
2465 sizeof(methodptr) * lm->vftblindex;
2467 /* implicit null-pointer check */
2468 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2469 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2471 /* generate the actual call */
2473 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2475 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2476 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2477 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2480 case ICMD_INVOKEINTERFACE:
2481 emit_nullpointer_check(cd, iptr, REG_OUT0);
2484 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2490 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2491 sizeof(methodptr*) * lm->class->index;
2493 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2496 /* implicit null-pointer check */
2497 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2498 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2499 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2501 /* generate the actual call */
2503 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2505 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2506 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2507 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2511 /* store return value */
2513 d = md->returntype.type;
2515 if (d != TYPE_VOID) {
2516 if (IS_INT_LNG_TYPE(d)) {
2517 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2518 M_INTMOVE(REG_RESULT_CALLER, s1);
2521 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2522 if (IS_2_WORD_TYPE(d)) {
2523 M_DBLMOVE(REG_FRESULT, s1);
2525 M_FLTMOVE(REG_FRESULT, s1);
2528 emit_store_dst(jd, iptr, s1);
2533 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2534 /* val.a: (classinfo*) superclass */
2536 /* superclass is an interface:
2538 * OK if ((sub == NULL) ||
2539 * (sub->vftbl->interfacetablelength > super->index) &&
2540 * (sub->vftbl->interfacetable[-super->index] != NULL));
2542 * superclass is a class:
2544 * OK if ((sub == NULL) || (0
2545 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2546 * super->vftbl->diffvall));
2549 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2553 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2558 super = iptr->sx.s23.s3.c.cls;
2559 superindex = super->index;
2562 #if defined(ENABLE_THREADS)
2563 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2568 /* if class is not resolved, check which code to call */
2570 if (super == NULL) {
2571 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2573 cr = iptr->sx.s23.s3.c.ref;
2574 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2576 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2579 M_ILD(REG_ITMP2, REG_PV, disp);
2580 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2581 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2584 /* interface checkcast code */
2586 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2587 if (super == NULL) {
2588 cr = iptr->sx.s23.s3.c.ref;
2590 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2594 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2597 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2598 M_ILD(REG_ITMP3, REG_ITMP2,
2599 OFFSET(vftbl_t, interfacetablelength));
2600 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2601 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2603 M_ALD(REG_ITMP3, REG_ITMP2,
2604 OFFSET(vftbl_t, interfacetable[0]) -
2605 superindex * sizeof(methodptr*));
2606 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2609 emit_label_br(cd, BRANCH_LABEL_4);
2611 emit_label(cd, BRANCH_LABEL_3);
2614 /* class checkcast code */
2616 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2617 if (super == NULL) {
2618 emit_label(cd, BRANCH_LABEL_2);
2620 cr = iptr->sx.s23.s3.c.ref;
2621 disp = dseg_add_unique_address(cd, NULL);
2623 codegen_add_patch_ref(cd,
2624 PATCHER_checkcast_instanceof_class,
2628 disp = dseg_add_address(cd, super->vftbl);
2630 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2633 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2634 M_ALD(REG_ITMP3, REG_PV, disp);
2635 #if defined(ENABLE_THREADS)
2636 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2638 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2639 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2640 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2641 M_ALD(REG_ITMP3, REG_PV, disp);
2642 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2643 #if defined(ENABLE_THREADS)
2644 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2647 M_CMP(REG_ITMP3, REG_ITMP2);
2648 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2651 emit_label(cd, BRANCH_LABEL_5);
2654 if (super == NULL) {
2655 emit_label(cd, BRANCH_LABEL_1);
2656 emit_label(cd, BRANCH_LABEL_4);
2659 d = codegen_reg_of_dst(jd, iptr, s1);
2662 /* array type cast-check */
2664 s1 = emit_load_s1(jd, iptr, REG_OUT0);
2665 M_INTMOVE(s1, REG_OUT0);
2667 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2669 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2670 cr = iptr->sx.s23.s3.c.ref;
2671 disp = dseg_add_unique_address(cd, NULL);
2673 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2677 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2679 M_ALD(REG_OUT1, REG_PV, disp);
2680 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2681 M_ALD(REG_ITMP3, REG_PV, disp);
2682 /* XXX jit-c-call */
2683 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2687 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2689 d = codegen_reg_of_dst(jd, iptr, s1);
2693 emit_store_dst(jd, iptr, d);
2696 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2697 /* val.a: (classinfo*) superclass */
2699 /* superclass is an interface:
2701 * return (sub != NULL) &&
2702 * (sub->vftbl->interfacetablelength > super->index) &&
2703 * (sub->vftbl->interfacetable[-super->index] != NULL);
2705 * superclass is a class:
2707 * return ((sub != NULL) && (0
2708 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2709 * super->vftbl->diffvall));
2714 vftbl_t *supervftbl;
2717 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2723 super = iptr->sx.s23.s3.c.cls;
2724 superindex = super->index;
2725 supervftbl = super->vftbl;
2728 #if defined(ENABLE_THREADS)
2729 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2734 M_MOV(s1, REG_ITMP1);
2740 /* if class is not resolved, check which code to call */
2742 if (super == NULL) {
2743 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2745 cr = iptr->sx.s23.s3.c.ref;
2746 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2748 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2751 M_ILD(REG_ITMP3, REG_PV, disp);
2752 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2753 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2756 /* interface instanceof code */
2758 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2759 if (super == NULL) {
2760 cr = iptr->sx.s23.s3.c.ref;
2762 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2766 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2769 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2770 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2771 M_CMP_IMM(REG_ITMP3, superindex);
2774 M_ALD(REG_ITMP1, REG_ITMP1,
2775 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2776 superindex * sizeof(methodptr*)));
2777 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2780 emit_label_br(cd, BRANCH_LABEL_4);
2782 emit_label(cd, BRANCH_LABEL_3);
2785 /* class instanceof code */
2787 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2788 if (super == NULL) {
2789 emit_label(cd, BRANCH_LABEL_2);
2791 cr = iptr->sx.s23.s3.c.ref;
2792 disp = dseg_add_unique_address(cd, NULL);
2794 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2798 disp = dseg_add_address(cd, supervftbl);
2800 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2803 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2804 M_ALD(REG_ITMP2, REG_PV, disp);
2805 #if defined(ENABLE_THREADS)
2806 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2808 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2809 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2810 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2811 #if defined(ENABLE_THREADS)
2812 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2814 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2815 M_CMP(REG_ITMP1, REG_ITMP2);
2816 M_XCMOVULE_IMM(1, d);
2819 emit_label(cd, BRANCH_LABEL_5);
2822 if (super == NULL) {
2823 emit_label(cd, BRANCH_LABEL_1);
2824 emit_label(cd, BRANCH_LABEL_4);
2827 emit_store_dst(jd, iptr, d);
2831 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2833 /* check for negative sizes and copy sizes to stack if necessary */
2835 MCODECHECK((iptr->s1.argcount << 1) + 64);
2837 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2839 var = VAR(iptr->sx.s23.s2.args[s1]);
2841 /* copy SAVEDVAR sizes to stack */
2843 /* Already Preallocated? */
2845 if (!(var->flags & PREALLOC)) {
2846 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2847 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2851 /* arg 0 = dimension count */
2853 ICONST(REG_OUT0, iptr->s1.argcount);
2855 /* is patcher function set? */
2857 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2858 disp = dseg_add_unique_address(cd, 0);
2860 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2861 iptr->sx.s23.s3.c.ref,
2865 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2867 /* arg 1 = arraydescriptor */
2869 M_ALD(REG_OUT1, REG_PV, disp);
2871 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2873 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2875 /* XXX c abi call */
2876 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2877 M_ALD(REG_ITMP3, REG_PV, disp);
2878 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2881 /* check for exception before result assignment */
2883 emit_exception_check(cd, iptr);
2885 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2886 M_INTMOVE(REG_RESULT_CALLER, d);
2887 emit_store_dst(jd, iptr, d);
2891 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2897 } /* for instruction */
2901 } /* if (bptr -> flags >= BBREACHED) */
2902 } /* for basic block */
2904 dseg_createlinenumbertable(cd);
2906 /* generate stubs */
2908 emit_patcher_stubs(jd);
2909 REPLACEMENT_EMIT_STUBS(jd);
2911 /* everything's ok */
2917 /* codegen_emit_stub_compiler **************************************************
2919 Emits a stub routine which calls the compiler.
2921 *******************************************************************************/
2923 void codegen_emit_stub_compiler(jitdata *jd)
2928 /* get required compiler data */
2933 /* code for the stub */
2935 /* no window save yet, user caller's PV */
2936 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2937 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2938 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2943 /* codegen_emit_stub_native ****************************************************
2945 Emits a stub routine which calls a native method.
2947 *******************************************************************************/
2949 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2956 s4 i, j; /* count variables */
2959 s4 funcdisp; /* displacement of the function */
2961 /* get required compiler data */
2967 /* initialize variables */
2970 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2972 /* calculate stack frame size */
2974 cd->stackframesize =
2975 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2976 sizeof(localref_table) / SIZEOF_VOID_P +
2977 md->paramcount + /* for saving arguments over calls */
2978 nmd->memuse + /* nmd knows about the native stackframe layout */
2981 /* create method header */
2983 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2984 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2985 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2986 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2987 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2988 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2989 (void) dseg_addlinenumbertablesize(cd);
2990 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2992 /* generate stub code */
2994 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
2996 #if !defined(NDEBUG)
2997 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2998 emit_verbosecall_enter(jd);
3001 /* get function address (this must happen before the stackframeinfo) */
3003 funcdisp = dseg_add_functionptr(cd, f);
3005 #if !defined(WITH_STATIC_CLASSPATH)
3007 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3011 /* save float argument registers */
3013 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3014 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3015 M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3020 /* prepare data structures for native function call */
3022 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
3023 M_MOV(REG_PV_CALLEE, REG_OUT1);
3024 M_MOV(REG_FP, REG_OUT2); /* java sp */
3025 M_MOV(REG_RA_CALLEE, REG_OUT3);
3026 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3027 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3028 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3029 M_NOP; /* XXX fill me! */
3031 /* restore float argument registers */
3033 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3034 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3035 M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + (j * 8));
3040 /* copy or spill arguments to new locations */
3041 int num_fltregargs = 0;
3042 int fltregarg_inswap[16];
3043 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3044 t = md->paramtypes[i].type;
3046 if (IS_INT_LNG_TYPE(t)) {
3047 if (!md->params[i].inmemory) {
3048 s1 = md->params[i].regoff;
3049 /* s1 refers to the old window, transpose */
3050 s1 = REG_WINDOW_TRANSPOSE(s1);
3052 if (!nmd->params[j].inmemory) {
3053 s2 = nat_argintregs[nmd->params[j].regoff];
3056 s2 = nmd->params[j].regoff - 6;
3057 M_AST(s1, REG_SP, CSTACK + s2 * 8);
3062 s1 = md->params[i].regoff + cd->stackframesize;
3063 s2 = nmd->params[j].regoff - 6;
3064 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3065 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3069 if (!md->params[i].inmemory) {
3070 s1 = md->params[i].regoff;
3072 if (!nmd->params[j].inmemory) {
3073 /* no mapping to regs needed, native flt args use regoff */
3074 s2 = nmd->params[j].regoff;
3076 /* we cannot move flt regs to their native arg locations directly */
3077 M_DMOV(s1, s2 + 16);
3078 fltregarg_inswap[num_fltregargs] = s2;
3080 /*printf("flt arg swap to %d\n", s2 + 16);*/
3083 s2 = nmd->params[j].regoff;
3084 if (IS_2_WORD_TYPE(t))
3085 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3087 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3092 s1 = md->params[i].regoff + cd->stackframesize;
3093 s2 = nmd->params[j].regoff - 6;
3094 if (IS_2_WORD_TYPE(t)) {
3095 M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3096 M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3098 M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3099 M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3105 /* move swapped float args to target regs */
3106 for (i = 0; i < num_fltregargs; i++) {
3107 s1 = fltregarg_inswap[i];
3108 M_DMOV(s1 + 16, s1);
3109 /*printf("float arg to target reg: %d ==> %d\n", s1+16, s1);*/
3113 /* put class into second argument register */
3115 if (m->flags & ACC_STATIC) {
3116 disp = dseg_add_address(cd, m->class);
3117 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3120 /* put env into first argument register */
3122 disp = dseg_add_address(cd, _Jv_env);
3123 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3125 /* do the native function call */
3127 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3128 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3129 M_NOP; /* delay slot */
3131 /* save return value */
3133 if (md->returntype.type != TYPE_VOID) {
3134 if (IS_INT_LNG_TYPE(md->returntype.type))
3135 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3137 M_DST(REG_FRESULT, REG_SP, CSTACK);
3140 /* Note: native functions return float values in %f0 (see ABI) */
3141 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3143 #if !defined(NDEBUG)
3144 /* But for the trace function we need to put a flt result into %f1 */
3145 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3146 if (!IS_2_WORD_TYPE(md->returntype.type))
3147 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3148 emit_verbosecall_exit(jd);
3152 /* remove native stackframe info */
3154 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3155 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3156 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3157 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3158 M_NOP; /* XXX fill me! */
3159 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3161 /* restore float return value, int return value already in our return reg */
3163 if (md->returntype.type != TYPE_VOID) {
3164 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3165 if (IS_2_WORD_TYPE(md->returntype.type))
3166 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3168 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3172 /* check for exception */
3173 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3176 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3179 /* handle exception */
3181 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3182 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3183 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3184 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3185 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3187 /* generate patcher stubs */
3189 emit_patcher_stubs(jd);
3193 * These are local overrides for various environment variables in Emacs.
3194 * Please do not remove this and leave it at the end of the file, where
3195 * Emacs will automagically detect them.
3196 * ---------------------------------------------------------------------
3199 * indent-tabs-mode: t
3203 * vim:noexpandtab:sw=4:ts=4: