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/asmpart.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/dseg.h"
53 #include "vm/jit/emit-common.h"
54 #include "vm/jit/sparc64/emit.h"
55 #include "vm/jit/jit.h"
56 #include "vm/jit/parse.h"
57 #include "vm/jit/patcher.h"
58 #include "vm/jit/reg.h"
59 #include "vm/jit/replace.h"
60 #include "vm/jit/stacktrace.h"
61 #include "vmcore/loader.h"
62 #include "vmcore/options.h"
64 /* XXX use something like this for window control ?
65 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
67 #define REG_PV REG_PV_CALLEE
72 if ((disp < -4096) || (disp > 4095))
73 printf("disp %d\n", disp);
76 return (disp >= -4096) && (disp <= 4095);
79 s4 get_lopart_disp(disp)
84 lodisp = setlo_part(disp);
86 if (setlo_part(disp) == 0)
89 lodisp = setlo_part(disp) | 0x1c00;
96 /* codegen_emit ****************************************************************
98 Generates machine code.
100 *******************************************************************************/
102 bool codegen_emit(jitdata *jd)
108 s4 len, s1, s2, s3, d, disp;
114 constant_classref *cr;
115 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
116 unresolved_method *um;
117 builtintable_entry *bte;
120 unresolved_field *uf;
124 /* get required compiler data */
131 /* prevent compiler warnings */
140 s4 savedregs_num, localbase;
142 #if 0 /* no leaf optimization yet */
143 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
145 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
148 /* space to save used callee saved registers */
150 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
151 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
153 cd->stackframesize = rd->memuse + savedregs_num;
155 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
156 if (checksync && (m->flags & ACC_SYNCHRONIZED))
157 cd->stackframesize++;
160 /* keep stack 16-byte aligned (ABI requirement) */
162 if (cd->stackframesize & 1)
163 cd->stackframesize++;
165 /* create method header */
167 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
168 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
170 #if defined(ENABLE_THREADS)
171 /* IsSync contains the offset relative to the stack pointer for the
172 argument of monitor_exit used in the exception handler. Since the
173 offset could be zero and give a wrong meaning of the flag it is
177 if (checksync && (m->flags & ACC_SYNCHRONIZED))
178 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
181 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
183 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
184 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
185 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
186 dseg_addlinenumbertablesize(cd);
187 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
189 /* create exception table */
191 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
192 dseg_add_target(cd, ex->start);
193 dseg_add_target(cd, ex->end);
194 dseg_add_target(cd, ex->handler);
195 (void) dseg_add_unique_address(cd, ex->catchtype.any);
198 /* save register window and create stack frame (if necessary) */
200 if (cd->stackframesize)
201 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
204 /* save callee saved float registers (none right now) */
206 p = cd->stackframesize;
207 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
208 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
213 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
214 emit_verbosecall_enter(jd);
219 /* take arguments out of register or stack frame */
223 /* when storing locals, use this as base */
224 localbase = JITSTACK;
226 /* since the register allocator does not know about the shifting window
227 * arg regs need to be copied via the stack
229 if (md->argintreguse > 0) {
230 /* allocate scratch space for copying in to save(i&l) regs */
231 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
233 localbase += INT_ARG_CNT * 8;
235 /* XXX could use the param slots on the stack for this! */
236 for (p = 0; p < INT_ARG_CNT; p++)
237 M_STX(REG_WINDOW_TRANSPOSE(rd->argintregs[p]), REG_SP, JITSTACK + (p * 8));
241 for (p = 0, l = 0; p < md->paramcount; p++) {
242 t = md->paramtypes[p].type;
244 varindex = jd->local_map[l * 5 + t];
247 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
250 if (varindex == UNUSED)
255 s1 = md->params[p].regoff;
256 if (IS_INT_LNG_TYPE(t)) { /* integer args */
257 if (!md->params[p].inmemory) { /* register arguments */
258 /*s2 = rd->argintregs[s1];*/
259 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
260 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
261 /*M_INTMOVE(s2, var->vv.regoff);*/
262 M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 8));
264 } else { /* reg arg -> spilled */
265 /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
267 M_LDX(REG_ITMP1, REG_SP, JITSTACK + (s1 * 8));
268 M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
271 } else { /* stack arguments */
272 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
273 M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
275 } else { /* stack arg -> spilled */
276 /* add the callers window save registers */
277 var->vv.regoff = cd->stackframesize + s1;
281 } else { /* floating args */
282 if (!md->params[p].inmemory) { /* register arguments */
283 s2 = rd->argfltregs[s1];
284 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
285 M_FLTMOVE(s2, var->vv.regoff);
287 } else { /* reg arg -> spilled */
288 M_DST(s2, REG_SP, localbase + (var->vv.regoff) * 8);
291 } else { /* stack arguments */
292 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
293 M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
295 } else { /* stack-arg -> spilled */
296 var->vv.regoff = cd->stackframesize + s1;
302 if (md->argintreguse > 0) {
303 /* release scratch space */
304 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
308 /* XXX monitor enter */
315 /* end of header generation */
317 /* create replacement points */
319 REPLACEMENT_POINTS_INIT(cd, jd);
321 /* walk through all basic blocks */
323 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
325 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
327 if (bptr->flags >= BBREACHED) {
329 /* branch resolving */
331 codegen_resolve_branchrefs(cd, bptr);
333 /* handle replacement points */
336 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
337 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
343 /* copy interface registers to their destination */
348 #if defined(ENABLE_LSRA)
349 #error XXX LSRA not tested yet
353 src = bptr->invars[len];
354 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
355 /* d = reg_of_var(m, src, REG_ITMP1); */
356 if (!(src->flags & INMEMORY))
360 M_INTMOVE(REG_ITMP1, d);
361 emit_store(jd, NULL, src, d);
368 var = VAR(bptr->invars[len]);
369 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
370 d = codegen_reg_of_var(0, var, REG_ITMP1);
371 M_INTMOVE(REG_ITMP2_XPTR, d);
372 emit_store(jd, NULL, var, d);
375 assert((var->flags & INOUT));
378 #if defined(ENABLE_LSRA)
381 /* walk through all instructions */
385 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
386 if (iptr->line != currentline) {
387 dseg_addlinenumber(cd, iptr->line);
388 currentline = iptr->line;
391 MCODECHECK(64); /* an instruction usually needs < 64 words */
395 case ICMD_INLINE_START:
396 case ICMD_INLINE_END:
399 case ICMD_NOP: /* ... ==> ... */
402 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
405 emit_nullpointer_check(cd, iptr, s1);
408 /* constant operations ************************************************/
410 case ICMD_ICONST: /* ... ==> ..., constant */
412 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
413 ICONST(d, iptr->sx.val.i);
414 emit_store_dst(jd, iptr, d);
417 case ICMD_LCONST: /* ... ==> ..., constant */
419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
420 LCONST(d, iptr->sx.val.l);
421 emit_store_dst(jd, iptr, d);
424 case ICMD_FCONST: /* ... ==> ..., constant */
426 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
427 disp = dseg_add_float(cd, iptr->sx.val.f);
428 M_FLD(d, REG_PV, disp);
429 emit_store_dst(jd, iptr, d);
432 case ICMD_DCONST: /* ... ==> ..., constant */
434 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
435 disp = dseg_add_double(cd, iptr->sx.val.d);
436 M_DLD(d, REG_PV, disp);
437 emit_store_dst(jd, iptr, d);
440 case ICMD_ACONST: /* ... ==> ..., constant */
442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
444 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
445 cr = iptr->sx.val.c.ref;
446 disp = dseg_add_unique_address(cd, cr);
448 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
450 M_ALD(d, REG_PV, disp);
454 if (iptr->sx.val.anyptr == NULL) {
455 M_INTMOVE(REG_ZERO, d);
458 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
459 M_ALD(d, REG_PV, disp);
462 emit_store_dst(jd, iptr, d);
466 /* load/store/copy/move operations ************************************/
468 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
469 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
470 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
471 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
472 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
473 case ICMD_ISTORE: /* ..., value ==> ... */
474 case ICMD_LSTORE: /* ..., value ==> ... */
475 case ICMD_FSTORE: /* ..., value ==> ... */
476 case ICMD_DSTORE: /* ..., value ==> ... */
480 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
484 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
485 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
489 /* pop/dup/swap operations ********************************************/
491 /* attention: double and longs are only one entry in CACAO ICMDs */
493 case ICMD_POP: /* ..., value ==> ... */
494 case ICMD_POP2: /* ..., value, value ==> ... */
498 /* integer operations *************************************************/
500 case ICMD_INEG: /* ..., value ==> ..., - value */
503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
504 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
505 M_SUB(REG_ZERO, s1, d);
506 emit_store_dst(jd, iptr, d);
509 case ICMD_I2L: /* ..., value ==> ..., value */
511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
514 emit_store_dst(jd, iptr, d);
517 case ICMD_L2I: /* ..., value ==> ..., value */
519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
520 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
521 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
522 emit_store_dst(jd, iptr, d);
525 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
528 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
529 M_SLLX_IMM(s1, 56, d);
530 M_SRAX_IMM( d, 56, d);
531 emit_store_dst(jd, iptr, d);
534 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
538 M_SLLX_IMM(s1, 48, d);
539 M_SRLX_IMM( d, 48, d);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
547 M_SLLX_IMM(s1, 48, d);
548 M_SRAX_IMM( d, 48, d);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 emit_store_dst(jd, iptr, d);
563 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
564 /* sx.val.i = constant */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
568 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
569 M_ADD_IMM(s1, iptr->sx.val.i, d);
571 ICONST(REG_ITMP2, iptr->sx.val.i);
572 M_ADD(s1, REG_ITMP2, d);
574 emit_store_dst(jd, iptr, d);
577 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
578 /* sx.val.l = constant */
580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
582 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
583 M_ADD_IMM(s1, iptr->sx.val.l, d);
585 LCONST(REG_ITMP2, iptr->sx.val.l);
586 M_ADD(s1, REG_ITMP2, d);
588 emit_store_dst(jd, iptr, d);
591 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
602 /* sx.val.i = constant */
604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
606 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
607 M_SUB_IMM(s1, iptr->sx.val.i, d);
609 ICONST(REG_ITMP2, iptr->sx.val.i);
610 M_SUB(s1, REG_ITMP2, d);
612 emit_store_dst(jd, iptr, d);
615 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
616 /* sx.val.l = 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.l >= -4096) && (iptr->sx.val.l <= 4095)) {
621 M_SUB_IMM(s1, iptr->sx.val.l, d);
623 LCONST(REG_ITMP2, iptr->sx.val.l);
624 M_SUB(s1, REG_ITMP2, d);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
636 emit_store_dst(jd, iptr, d);
639 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
640 /* sx.val.i = constant */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
645 M_MULX_IMM(s1, iptr->sx.val.i, d);
647 ICONST(REG_ITMP2, iptr->sx.val.i);
648 M_MULX(s1, REG_ITMP2, d);
650 emit_store_dst(jd, iptr, d);
653 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
654 /* sx.val.l = 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.l >= -4096) && (iptr->sx.val.l <= 4095)) {
659 M_MULX_IMM(s1, iptr->sx.val.l, d);
661 LCONST(REG_ITMP2, iptr->sx.val.l);
662 M_MULX(s1, REG_ITMP2, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
668 /* XXX could also clear Y and use 32bit div */
669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672 emit_arithmetic_check(cd, iptr, s2);
674 /* XXX trim s2 like s1 ? */
676 emit_store_dst(jd, iptr, d);
679 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
681 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
682 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 emit_arithmetic_check(cd, iptr, s2);
686 emit_store_dst(jd, iptr, d);
689 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
692 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
693 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
694 emit_arithmetic_check(cd, iptr, s2);
696 /* XXX trim s2 like s1 ? */
697 M_DIVX(s1, s2, REG_ITMP3);
698 M_MULX(s2, REG_ITMP3, REG_ITMP3);
699 M_SUB(s1, REG_ITMP3, d);
700 emit_store_dst(jd, iptr, d);
703 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
706 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
708 emit_arithmetic_check(cd, iptr, s2);
709 M_DIVX(s1, s2, REG_ITMP3);
710 M_MULX(s2, REG_ITMP3, REG_ITMP3);
711 M_SUB(s1, REG_ITMP3, d);
712 emit_store_dst(jd, iptr, d);
715 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
716 case ICMD_LDIVPOW2: /* val.i = constant */
718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
719 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
720 M_SRAX_IMM(s1, 63, REG_ITMP2);
721 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
722 M_ADD(s1, REG_ITMP2, REG_ITMP2);
723 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
724 emit_store_dst(jd, iptr, d);
727 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
733 emit_store_dst(jd, iptr, d);
736 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
739 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
742 emit_store_dst(jd, iptr, d);
745 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
746 /* val.i = constant */
748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
749 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
750 M_SLL_IMM(s1, iptr->sx.val.i, d);
751 emit_store_dst(jd, iptr, d);
754 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
755 /* val.i = constant */
757 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
759 M_SLLX_IMM(s1, iptr->sx.val.i, d);
760 emit_store_dst(jd, iptr, d);
763 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
769 emit_store_dst(jd, iptr, d);
772 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
773 /* sx.val.i = constant */
775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
776 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
777 M_SRA_IMM(s1, iptr->sx.val.i, d);
778 emit_store_dst(jd, iptr, d);
781 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
787 emit_store_dst(jd, iptr, d);
790 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
791 /* sx.val.i = constant */
793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
795 M_SRL_IMM(s1, iptr->sx.val.i, d);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
802 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
809 /* sx.val.i = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 M_SRAX_IMM(s1, iptr->sx.val.i, d);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 emit_store_dst(jd, iptr, d);
826 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
827 /* sx.val.i = constant */
829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
830 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
831 M_SRLX_IMM(s1, iptr->sx.val.i, d);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
846 /* sx.val.i = constant */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
851 M_AND_IMM(s1, iptr->sx.val.i, d);
853 ICONST(REG_ITMP2, iptr->sx.val.i);
854 M_AND(s1, REG_ITMP2, d);
856 emit_store_dst(jd, iptr, d);
859 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
860 /* sx.val.i = constant */
862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
863 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
864 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
866 M_MOV(s1, REG_ITMP1);
869 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
870 M_AND_IMM(s1, iptr->sx.val.i, d);
873 M_SUB(REG_ZERO, s1, d);
874 M_AND_IMM(d, iptr->sx.val.i, d);
876 ICONST(REG_ITMP2, iptr->sx.val.i);
877 M_AND(s1, REG_ITMP2, d);
880 M_SUB(REG_ZERO, s1, d);
881 M_AND(d, REG_ITMP2, d);
883 M_SUB(REG_ZERO, d, d);
884 emit_store_dst(jd, iptr, d);
887 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
888 /* sx.val.l = constant */
890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
891 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
892 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
893 M_AND_IMM(s1, iptr->sx.val.l, d);
895 LCONST(REG_ITMP2, iptr->sx.val.l);
896 M_AND(s1, REG_ITMP2, d);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
902 /* sx.val.l = constant */
904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 M_MOV(s1, REG_ITMP1);
910 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
911 M_AND_IMM(s1, iptr->sx.val.l, d);
914 M_SUB(REG_ZERO, s1, d);
915 M_AND_IMM(d, iptr->sx.val.l, d);
917 LCONST(REG_ITMP2, iptr->sx.val.l);
918 M_AND(s1, REG_ITMP2, d);
921 M_SUB(REG_ZERO, s1, d);
922 M_AND(d, REG_ITMP2, d);
924 M_SUB(REG_ZERO, d, d);
925 emit_store_dst(jd, iptr, d);
928 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
932 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
935 emit_store_dst(jd, iptr, d);
938 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
939 /* sx.val.i = constant */
941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
942 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
943 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
944 M_OR_IMM(s1, iptr->sx.val.i, d);
946 ICONST(REG_ITMP2, iptr->sx.val.i);
947 M_OR(s1, REG_ITMP2, d);
949 emit_store_dst(jd, iptr, d);
952 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
953 /* sx.val.l = constant */
955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
956 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
957 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
958 M_OR_IMM(s1, iptr->sx.val.l, d);
960 LCONST(REG_ITMP2, iptr->sx.val.l);
961 M_OR(s1, REG_ITMP2, d);
963 emit_store_dst(jd, iptr, d);
966 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
970 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973 emit_store_dst(jd, iptr, d);
976 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
977 /* sx.val.i = constant */
979 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
980 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
981 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
982 M_XOR_IMM(s1, iptr->sx.val.i, d);
984 ICONST(REG_ITMP2, iptr->sx.val.i);
985 M_XOR(s1, REG_ITMP2, d);
987 emit_store_dst(jd, iptr, d);
990 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
991 /* sx.val.l = constant */
993 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
994 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
995 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
996 M_XOR_IMM(s1, iptr->sx.val.l, d);
998 LCONST(REG_ITMP2, iptr->sx.val.l);
999 M_XOR(s1, REG_ITMP2, d);
1001 emit_store_dst(jd, iptr, d);
1005 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1008 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1009 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1012 M_XCMOVLT_IMM(-1, d);
1013 M_XCMOVGT_IMM(1, d);
1014 emit_store_dst(jd, iptr, d);
1018 /* floating operations ************************************************/
1020 case ICMD_FNEG: /* ..., value ==> ..., - value */
1022 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1023 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1025 emit_store_dst(jd, iptr, d);
1028 case ICMD_DNEG: /* ..., value ==> ..., - value */
1030 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1031 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1038 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1039 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1040 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1047 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1048 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1049 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1051 emit_store_dst(jd, iptr, d);
1054 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1056 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1057 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1058 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1065 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1066 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1067 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1074 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1075 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1076 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1083 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1084 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1085 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1092 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1093 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1094 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1101 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1102 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1103 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1105 emit_store_dst(jd, iptr, d);
1109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1110 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1111 disp = dseg_add_float(cd, 0.0);
1112 M_IST (s1, REG_PV_CALLEE, disp);
1113 M_FLD (d, REG_PV_CALLEE, disp);
1114 M_CVTIF (d, d); /* rd gets translated to double target register */
1115 emit_store_dst(jd, iptr, d);
1119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1120 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1121 disp = dseg_add_float(cd, 0.0);
1122 M_IST (s1, REG_PV_CALLEE, disp);
1123 M_FLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1124 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1129 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1131 disp = dseg_add_float(cd, 0.0);
1132 M_CVTFI(s1, REG_FTMP2);
1133 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1134 M_ILD(d, REG_PV, disp);
1135 emit_store_dst(jd, iptr, d);
1139 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1140 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1142 disp = dseg_add_float(cd, 0.0);
1143 M_CVTDI(s1, REG_FTMP2);
1144 M_FST(REG_FTMP2, REG_PV, disp);
1145 M_ILD(d, REG_PV, disp);
1146 emit_store_dst(jd, iptr, d);
1149 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1150 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1152 disp = dseg_add_double(cd, 0.0);
1153 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1154 M_DST(REG_FTMP2, REG_PV, disp);
1155 M_LDX(d, REG_PV, disp);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1160 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1162 disp = dseg_add_double(cd, 0.0);
1163 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1164 M_DST(REG_FTMP2, REG_PV, disp);
1165 M_LDX(d, REG_PV, disp);
1166 emit_store_dst(jd, iptr, d);
1169 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1171 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1172 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1179 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1180 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1182 emit_store_dst(jd, iptr, d);
1185 /* XXX merge F/D versions? only compare instr. is different */
1186 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1188 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1189 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1190 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1192 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1193 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1194 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1195 emit_store_dst(jd, iptr, d);
1198 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1200 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1201 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1202 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1204 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1205 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1206 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1207 emit_store_dst(jd, iptr, d);
1210 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1212 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1213 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1214 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1216 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1217 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1218 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1219 emit_store_dst(jd, iptr, d);
1222 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1224 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1225 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1228 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1229 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1230 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1231 emit_store_dst(jd, iptr, d);
1235 /* memory operations **************************************************/
1237 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1239 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1240 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1241 emit_nullpointer_check(cd, iptr, s1);
1242 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1243 emit_store_dst(jd, iptr, d);
1246 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1249 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1250 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1251 /* implicit null-pointer check */
1252 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1253 M_AADD(s2, s1, REG_ITMP3);
1254 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1255 emit_store_dst(jd, iptr, d);
1258 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1260 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1261 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1262 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1263 /* implicit null-pointer check */
1264 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1265 M_AADD(s2, s1, REG_ITMP3);
1266 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1267 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1273 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1274 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1275 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1276 /* implicit null-pointer check */
1277 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1278 M_AADD(s2, s1, REG_ITMP3);
1279 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1280 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_IALOAD: /* ..., 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_ASLL_IMM(s2, 2, REG_ITMP3);
1292 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1293 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1294 emit_store_dst(jd, iptr, d);
1297 case ICMD_LALOAD: /* ..., 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_ASLL_IMM(s2, 3, REG_ITMP3);
1305 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1306 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_FALOAD: /* ..., 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_FTMP1);
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_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_DALOAD: /* ..., 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_FTMP1);
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_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1341 /* implicit null-pointer check */
1342 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1343 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1344 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1345 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1346 emit_store_dst(jd, iptr, d);
1350 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1353 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1354 /* implicit null-pointer check */
1355 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1356 M_AADD(s2, s1, REG_ITMP1);
1357 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1358 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1361 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1362 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 /* implicit null-pointer check */
1367 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1368 M_AADD(s2, s1, REG_ITMP1);
1369 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1370 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1371 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1374 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1377 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1378 /* implicit null-pointer check */
1379 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1380 M_ASLL_IMM(s2, 2, REG_ITMP2);
1381 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1382 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1383 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1386 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1388 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1389 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1390 /* implicit null-pointer check */
1391 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1392 M_ASLL_IMM(s2, 3, REG_ITMP2);
1393 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1394 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1395 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1398 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1400 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1401 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1402 /* implicit null-pointer check */
1403 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1404 M_ASLL_IMM(s2, 2, REG_ITMP2);
1405 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1406 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1407 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1410 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1412 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1413 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1414 /* implicit null-pointer check */
1415 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1416 M_ASLL_IMM(s2, 3, REG_ITMP2);
1417 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1418 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1419 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1423 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1425 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1426 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1427 /* implicit null-pointer check */
1428 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1429 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1431 M_MOV(s1, rd->argintregs[0]);
1432 M_MOV(s3, rd->argintregs[1]);
1433 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1434 M_ALD(REG_ITMP3, REG_PV, disp);
1435 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1437 emit_exception_check(cd, iptr);
1439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1441 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1442 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1443 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1444 /* implicit null-pointer check */
1445 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1449 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
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 M_AADD(s2, s1, REG_ITMP1);
1456 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1459 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1460 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464 /* implicit null-pointer check */
1465 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1466 M_AADD(s2, s1, REG_ITMP1);
1467 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1468 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1471 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
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 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1482 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486 /* implicit null-pointer check */
1487 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1488 M_ASLL_IMM(s2, 3, REG_ITMP2);
1489 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1490 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1493 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1497 /* implicit null-pointer check */
1498 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1499 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1500 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1501 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1505 case ICMD_GETSTATIC: /* ... ==> ..., value */
1507 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1508 uf = iptr->sx.s23.s3.uf;
1509 fieldtype = uf->fieldref->parseddesc.fd->type;
1510 disp = dseg_add_unique_address(cd, uf);
1512 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1515 fi = iptr->sx.s23.s3.fmiref->p.field;
1516 fieldtype = fi->type;
1517 disp = dseg_add_address(cd, &(fi->value));
1519 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1520 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1523 M_ALD(REG_ITMP1, REG_PV, disp);
1525 switch (fieldtype) {
1527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1528 M_ILD_INTERN(d, REG_ITMP1, 0);
1531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1532 M_LDX_INTERN(d, REG_ITMP1, 0);
1535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1536 M_ALD_INTERN(d, REG_ITMP1, 0);
1539 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1540 M_FLD_INTERN(d, REG_ITMP1, 0);
1543 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1544 M_DLD_INTERN(d, REG_ITMP1, 0);
1547 emit_store_dst(jd, iptr, d);
1550 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1552 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1553 uf = iptr->sx.s23.s3.uf;
1554 fieldtype = uf->fieldref->parseddesc.fd->type;
1555 disp = dseg_add_unique_address(cd, uf);
1557 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1560 fi = iptr->sx.s23.s3.fmiref->p.field;
1561 fieldtype = fi->type;
1562 disp = dseg_add_address(cd, &(fi->value));
1564 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1565 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1568 M_ALD(REG_ITMP1, REG_PV, disp);
1570 switch (fieldtype) {
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1573 M_IST_INTERN(s1, REG_ITMP1, 0);
1576 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1577 M_STX_INTERN(s1, REG_ITMP1, 0);
1580 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1581 M_AST_INTERN(s1, REG_ITMP1, 0);
1584 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1585 M_FST_INTERN(s1, REG_ITMP1, 0);
1588 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1589 M_DST_INTERN(s1, REG_ITMP1, 0);
1594 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1595 /* val = value (in current instruction) */
1596 /* following NOP) */
1598 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1599 uf = iptr->sx.s23.s3.uf;
1600 fieldtype = uf->fieldref->parseddesc.fd->type;
1601 disp = dseg_add_unique_address(cd, uf);
1603 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1606 fi = iptr->sx.s23.s3.fmiref->p.field;
1607 fieldtype = fi->type;
1608 disp = dseg_add_address(cd, &(fi->value));
1610 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1611 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1614 M_ALD(REG_ITMP1, REG_PV, disp);
1616 switch (fieldtype) {
1618 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1621 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1624 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1627 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1630 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1636 case ICMD_GETFIELD: /* ... ==> ..., value */
1638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1639 emit_nullpointer_check(cd, iptr, s1);
1641 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1642 uf = iptr->sx.s23.s3.uf;
1644 fieldtype = uf->fieldref->parseddesc.fd->type;
1647 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1650 fi = iptr->sx.s23.s3.fmiref->p.field;
1651 fieldtype = fi->type;
1655 switch (fieldtype) {
1657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1661 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1669 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1673 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1680 emit_store_dst(jd, iptr, d);
1683 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1686 emit_nullpointer_check(cd, iptr, s1);
1688 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1689 uf = iptr->sx.s23.s3.uf;
1690 fieldtype = uf->fieldref->parseddesc.fd->type;
1695 fi = iptr->sx.s23.s3.fmiref->p.field;
1696 fieldtype = fi->type;
1700 if (IS_INT_LNG_TYPE(fieldtype))
1701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1703 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1705 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1706 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1708 switch (fieldtype) {
1710 M_IST(s2, s1, disp);
1713 M_STX(s2, s1, disp);
1716 M_AST(s2, s1, disp);
1719 M_FST(s2, s1, disp);
1722 M_DST(s2, s1, disp);
1730 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1731 /* val = value (in current instruction) */
1732 /* following NOP) */
1734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1735 emit_nullpointer_check(cd, iptr, s1);
1737 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1738 unresolved_field *uf = iptr->sx.s23.s3.uf;
1740 fieldtype = uf->fieldref->parseddesc.fd->type;
1742 codegen_addpatchref(cd, PATCHER_get_putfield,
1745 if (opt_showdisassemble) {
1753 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1755 fieldtype = fi->type;
1761 switch (fieldtype) {
1763 M_IST(REG_ZERO, s1, disp);
1766 M_STX(REG_ZERO, s1, disp);
1769 M_AST(REG_ZERO, s1, disp);
1772 M_FST(REG_ZERO, s1, disp);
1775 M_DST(REG_ZERO, s1, disp);
1781 /* branch operations **************************************************/
1783 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1786 M_INTMOVE(s1, REG_ITMP2_XPTR);
1788 #ifdef ENABLE_VERIFIER
1789 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1790 unresolved_class *uc = iptr->sx.s23.s2.uc;
1792 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1794 #endif /* ENABLE_VERIFIER */
1796 disp = dseg_add_functionptr(cd, asm_handle_exception);
1797 M_ALD(REG_ITMP1, REG_PV, disp);
1798 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1800 M_NOP; /* nop ensures that XPC is less than the end */
1801 /* of basic block */
1805 case ICMD_GOTO: /* ... ==> ... */
1806 case ICMD_RET: /* ... ==> ... */
1808 emit_br(cd, iptr->dst.block);
1812 case ICMD_JSR: /* ... ==> ... */
1814 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1818 case ICMD_IFNULL: /* ..., value ==> ... */
1819 case ICMD_IFNONNULL:
1821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1822 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1825 /* Note: int compares must not branch on the register directly. */
1826 /* Reason is, that register content is not 32-bit clean. */
1828 case ICMD_IFEQ: /* ..., value ==> ... */
1830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1832 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1833 M_CMP_IMM(s1, iptr->sx.val.i);
1836 ICONST(REG_ITMP2, iptr->sx.val.i);
1837 M_CMP(s1, REG_ITMP2);
1839 emit_beq(cd, iptr->dst.block);
1842 case ICMD_IFLT: /* ..., value ==> ... */
1844 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1846 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1847 M_CMP_IMM(s1, iptr->sx.val.i);
1850 ICONST(REG_ITMP2, iptr->sx.val.i);
1851 M_CMP(s1, REG_ITMP2);
1853 emit_blt(cd, iptr->dst.block);
1856 case ICMD_IFLE: /* ..., value ==> ... */
1858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1861 M_CMP_IMM(s1, iptr->sx.val.i);
1864 ICONST(REG_ITMP2, iptr->sx.val.i);
1865 M_CMP(s1, REG_ITMP2);
1867 emit_ble(cd, iptr->dst.block);
1870 case ICMD_IFNE: /* ..., value ==> ... */
1872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1874 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1875 M_CMP_IMM(s1, iptr->sx.val.i);
1878 ICONST(REG_ITMP2, iptr->sx.val.i);
1879 M_CMP(s1, REG_ITMP2);
1881 emit_bne(cd, iptr->dst.block);
1884 case ICMD_IFGT: /* ..., value ==> ... */
1886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1888 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1889 M_CMP_IMM(s1, iptr->sx.val.i);
1892 ICONST(REG_ITMP2, iptr->sx.val.i);
1893 M_CMP(s1, REG_ITMP2);
1895 emit_bgt(cd, iptr->dst.block);
1898 case ICMD_IFGE: /* ..., value ==> ... */
1900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1902 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1903 M_CMP_IMM(s1, iptr->sx.val.i);
1906 ICONST(REG_ITMP2, iptr->sx.val.i);
1907 M_CMP(s1, REG_ITMP2);
1909 emit_bge(cd, iptr->dst.block);
1912 case ICMD_IF_LEQ: /* ..., value ==> ... */
1914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1915 if (iptr->sx.val.l == 0)
1916 emit_beqz(cd, iptr->dst.block, s1);
1918 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1919 M_CMP_IMM(s1, iptr->sx.val.l);
1922 LCONST(REG_ITMP2, iptr->sx.val.l);
1923 M_CMP(s1, REG_ITMP2);
1925 emit_beq_xcc(cd, iptr->dst.block);
1929 case ICMD_IF_LLT: /* ..., value ==> ... */
1931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932 if (iptr->sx.val.l == 0)
1933 emit_bltz(cd, iptr->dst.block, s1);
1935 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1936 M_CMP_IMM(s1, iptr->sx.val.l);
1939 ICONST(REG_ITMP2, iptr->sx.val.l);
1940 M_CMP(s1, REG_ITMP2);
1942 emit_blt_xcc(cd, iptr->dst.block);
1946 case ICMD_IF_LLE: /* ..., value ==> ... */
1948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1949 if (iptr->sx.val.l == 0)
1950 emit_blez(cd, iptr->dst.block, s1);
1952 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1953 M_CMP_IMM(s1, iptr->sx.val.l);
1956 ICONST(REG_ITMP2, iptr->sx.val.l);
1957 M_CMP(s1, REG_ITMP2);
1959 emit_ble_xcc(cd, iptr->dst.block);
1963 case ICMD_IF_LNE: /* ..., value ==> ... */
1965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1966 if (iptr->sx.val.l == 0)
1967 emit_bnez(cd, iptr->dst.block, s1);
1969 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1970 M_CMP_IMM(s1, iptr->sx.val.l);
1973 ICONST(REG_ITMP2, iptr->sx.val.l);
1974 M_CMP(s1, REG_ITMP2);
1976 emit_bne_xcc(cd, iptr->dst.block);
1980 case ICMD_IF_LGT: /* ..., value ==> ... */
1982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1983 if (iptr->sx.val.l == 0)
1984 emit_bgtz(cd, iptr->dst.block, s1);
1986 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1987 M_CMP_IMM(s1, iptr->sx.val.l);
1990 ICONST(REG_ITMP2, iptr->sx.val.l);
1991 M_CMP(s1, REG_ITMP2);
1993 emit_bgt_xcc(cd, iptr->dst.block);
1997 case ICMD_IF_LGE: /* ..., value ==> ... */
1999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2000 if (iptr->sx.val.l == 0)
2001 emit_bgez(cd, iptr->dst.block, s1);
2003 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2004 M_CMP_IMM(s1, iptr->sx.val.l);
2007 ICONST(REG_ITMP2, iptr->sx.val.l);
2008 M_CMP(s1, REG_ITMP2);
2010 emit_bge_xcc(cd, iptr->dst.block);
2015 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2016 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2021 emit_beq_xcc(cd, iptr->dst.block);
2024 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2029 emit_beq(cd, iptr->dst.block);
2032 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2033 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2036 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2038 emit_bne_xcc(cd, iptr->dst.block);
2041 case ICMD_IF_ICMPNE: /* 32-bit compare */
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2044 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2046 emit_bne(cd, iptr->dst.block);
2049 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2054 emit_blt_xcc(cd, iptr->dst.block);
2057 case ICMD_IF_ICMPLT: /* 32-bit compare */
2059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2060 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2062 emit_blt(cd, iptr->dst.block);
2065 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2068 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2070 emit_bgt_xcc(cd, iptr->dst.block);
2073 case ICMD_IF_ICMPGT: /* 32-bit compare */
2075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2076 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2078 emit_bgt(cd, iptr->dst.block);
2081 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2084 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2086 emit_ble_xcc(cd, iptr->dst.block);
2089 case ICMD_IF_ICMPLE: /* 32-bit compare */
2091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2092 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2094 emit_ble(cd, iptr->dst.block);
2098 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2101 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2103 emit_bge_xcc(cd, iptr->dst.block);
2106 case ICMD_IF_ICMPGE: /* 32-bit compare */
2108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2109 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2111 emit_bge(cd, iptr->dst.block);
2115 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2118 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2119 M_INTMOVE(s1, REG_RESULT_CALLEE);
2120 goto nowperformreturn;
2122 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2124 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2125 M_INTMOVE(s1, REG_RESULT_CALLEE);
2127 #ifdef ENABLE_VERIFIER
2128 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2129 unresolved_class *uc = iptr->sx.s23.s2.uc;
2131 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2133 #endif /* ENABLE_VERIFIER */
2134 goto nowperformreturn;
2136 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2139 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2140 M_DBLMOVE(s1, REG_FRESULT);
2141 goto nowperformreturn;
2143 case ICMD_RETURN: /* ... ==> ... */
2149 p = cd->stackframesize;
2151 #if !defined(NDEBUG)
2152 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2153 emit_verbosecall_exit(jd);
2156 #if defined(ENABLE_THREADS)
2157 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2158 /* XXX: REG_RESULT is save, but what about FRESULT? */
2159 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2161 switch (iptr->opc) {
2164 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2168 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2169 M_ALD(REG_ITMP3, REG_PV, disp);
2170 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2172 switch (iptr->opc) {
2175 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2183 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2189 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2192 branch_target_t *table;
2194 table = iptr->dst.table;
2196 l = iptr->sx.s23.s2.tablelow;
2197 i = iptr->sx.s23.s3.tablehigh;
2199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2201 M_INTMOVE(s1, REG_ITMP1);
2203 else if (l <= 4095) {
2204 M_ADD_IMM(s1, -l, REG_ITMP1);
2207 ICONST(REG_ITMP2, l);
2208 /* XXX: do I need to truncate s1 to 32-bit ? */
2209 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2217 M_CMP_IMM(REG_ITMP1, i - 1);
2220 ICONST(REG_ITMP2, i - 1);
2221 M_CMP(REG_ITMP1, REG_ITMP2);
2223 emit_bugt(cd, table[0].block); /* default target */
2225 /* build jump table top down and use address of lowest entry */
2230 dseg_add_target(cd, table->block);
2235 /* length of dataseg after last dseg_addtarget is used by load */
2237 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2238 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2239 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2240 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2245 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2248 lookup_target_t *lookup;
2250 lookup = iptr->dst.lookup;
2252 i = iptr->sx.s23.s2.lookupcount;
2254 MCODECHECK((i<<2)+8);
2255 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2258 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2259 M_CMP_IMM(s1, lookup->value);
2261 ICONST(REG_ITMP2, lookup->value);
2262 M_CMP(s1, REG_ITMP2);
2264 emit_beq(cd, lookup->target.block);
2268 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2274 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2276 bte = iptr->sx.s23.s3.bte;
2279 /* XXX: proper builtin calling and float args are so not implemented */
2280 assert(md->paramcount <= 5 && md->argfltreguse < 1);
2284 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2286 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2287 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2288 case ICMD_INVOKEINTERFACE:
2290 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2292 um = iptr->sx.s23.s3.um;
2293 md = um->methodref->parseddesc.md;
2296 lm = iptr->sx.s23.s3.fmiref->p.method;
2298 md = lm->parseddesc;
2302 s3 = md->paramcount;
2304 MCODECHECK((s3 << 1) + 64);
2306 /* copy arguments to registers or stack location */
2308 for (s3 = s3 - 1; s3 >= 0; s3--) {
2309 var = VAR(iptr->sx.s23.s2.args[s3]);
2311 if (var->flags & PREALLOC)
2314 if (IS_INT_LNG_TYPE(var->type)) {
2315 if (!md->params[s3].inmemory) {
2316 s1 = rd->argintregs[md->params[s3].regoff];
2317 d = emit_load(jd, iptr, var, s1);
2321 d = emit_load(jd, iptr, var, REG_ITMP1);
2322 M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2326 if (!md->params[s3].inmemory) {
2327 s1 = rd->argfltregs[md->params[s3].regoff];
2328 d = emit_load(jd, iptr, var, s1);
2329 if (IS_2_WORD_TYPE(var->type))
2335 d = emit_load(jd, iptr, var, REG_FTMP1);
2336 if (IS_2_WORD_TYPE(var->type))
2337 M_DST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2339 M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2344 switch (iptr->opc) {
2346 disp = dseg_add_functionptr(cd, bte->fp);
2348 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2350 /* XXX jit-c-call */
2351 /* generate the actual call */
2353 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2355 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2356 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2357 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2359 emit_exception_check(cd, iptr);
2362 case ICMD_INVOKESPECIAL:
2363 emit_nullpointer_check(cd, iptr, REG_OUT0);
2366 case ICMD_INVOKESTATIC:
2368 disp = dseg_add_unique_address(cd, NULL);
2370 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2374 disp = dseg_add_address(cd, lm->stubroutine);
2376 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2378 /* generate the actual call */
2380 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2382 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2383 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2384 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2387 case ICMD_INVOKEVIRTUAL:
2388 emit_nullpointer_check(cd, iptr, REG_OUT0);
2391 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2396 s1 = OFFSET(vftbl_t, table[0]) +
2397 sizeof(methodptr) * lm->vftblindex;
2399 /* implicit null-pointer check */
2400 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2401 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2403 /* generate the actual call */
2405 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2407 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2408 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2409 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2412 case ICMD_INVOKEINTERFACE:
2413 emit_nullpointer_check(cd, iptr, REG_OUT0);
2416 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2422 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2423 sizeof(methodptr*) * lm->class->index;
2425 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2428 /* implicit null-pointer check */
2429 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2430 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2431 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2433 /* generate the actual call */
2435 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2437 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2438 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2439 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2443 /* store return value */
2445 d = md->returntype.type;
2447 if (d != TYPE_VOID) {
2448 if (IS_INT_LNG_TYPE(d)) {
2449 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2450 M_INTMOVE(REG_RESULT_CALLER, s1);
2453 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2454 if (IS_2_WORD_TYPE(d)) {
2455 M_DBLMOVE(REG_FRESULT, s1);
2457 M_FLTMOVE(REG_FRESULT, s1);
2460 emit_store_dst(jd, iptr, s1);
2465 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2466 /* val.a: (classinfo*) superclass */
2468 /* superclass is an interface:
2470 * OK if ((sub == NULL) ||
2471 * (sub->vftbl->interfacetablelength > super->index) &&
2472 * (sub->vftbl->interfacetable[-super->index] != NULL));
2474 * superclass is a class:
2476 * OK if ((sub == NULL) || (0
2477 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2478 * super->vftbl->diffvall));
2481 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2485 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2490 super = iptr->sx.s23.s3.c.cls;
2491 superindex = super->index;
2494 #if defined(ENABLE_THREADS)
2495 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2500 /* if class is not resolved, check which code to call */
2502 if (super == NULL) {
2503 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2505 cr = iptr->sx.s23.s3.c.ref;
2506 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2508 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2511 M_ILD(REG_ITMP2, REG_PV, disp);
2512 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2513 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2516 /* interface checkcast code */
2518 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2519 if (super == NULL) {
2520 cr = iptr->sx.s23.s3.c.ref;
2522 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2526 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2529 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2530 M_ILD(REG_ITMP3, REG_ITMP2,
2531 OFFSET(vftbl_t, interfacetablelength));
2532 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2533 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2535 M_ALD(REG_ITMP3, REG_ITMP2,
2536 OFFSET(vftbl_t, interfacetable[0]) -
2537 superindex * sizeof(methodptr*));
2538 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2541 emit_label_br(cd, BRANCH_LABEL_4);
2543 emit_label(cd, BRANCH_LABEL_3);
2546 /* class checkcast code */
2548 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2549 if (super == NULL) {
2550 emit_label(cd, BRANCH_LABEL_2);
2552 cr = iptr->sx.s23.s3.c.ref;
2553 disp = dseg_add_unique_address(cd, NULL);
2555 codegen_add_patch_ref(cd,
2556 PATCHER_checkcast_instanceof_class,
2560 disp = dseg_add_address(cd, super->vftbl);
2562 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2565 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2566 M_ALD(REG_ITMP3, REG_PV, disp);
2567 #if defined(ENABLE_THREADS)
2568 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2570 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2571 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2572 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2573 M_ALD(REG_ITMP3, REG_PV, disp);
2574 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2575 #if defined(ENABLE_THREADS)
2576 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2579 M_CMP(REG_ITMP3, REG_ITMP2);
2580 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2583 emit_label(cd, BRANCH_LABEL_5);
2586 if (super == NULL) {
2587 emit_label(cd, BRANCH_LABEL_1);
2588 emit_label(cd, BRANCH_LABEL_4);
2591 d = codegen_reg_of_dst(jd, iptr, s1);
2594 /* array type cast-check */
2596 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
2597 M_INTMOVE(s1, rd->argintregs[0]);
2599 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2601 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2602 cr = iptr->sx.s23.s3.c.ref;
2603 disp = dseg_add_unique_address(cd, NULL);
2605 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2609 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2611 M_ALD(rd->argintregs[1], REG_PV, disp);
2612 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2613 M_ALD(REG_ITMP3, REG_PV, disp);
2614 /* XXX jit-c-call */
2615 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2619 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2621 d = codegen_reg_of_dst(jd, iptr, s1);
2625 emit_store_dst(jd, iptr, d);
2628 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2629 /* val.a: (classinfo*) superclass */
2631 /* superclass is an interface:
2633 * return (sub != NULL) &&
2634 * (sub->vftbl->interfacetablelength > super->index) &&
2635 * (sub->vftbl->interfacetable[-super->index] != NULL);
2637 * superclass is a class:
2639 * return ((sub != NULL) && (0
2640 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2641 * super->vftbl->diffvall));
2646 vftbl_t *supervftbl;
2649 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2655 super = iptr->sx.s23.s3.c.cls;
2656 superindex = super->index;
2657 supervftbl = super->vftbl;
2660 #if defined(ENABLE_THREADS)
2661 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2666 M_MOV(s1, REG_ITMP1);
2672 /* if class is not resolved, check which code to call */
2674 if (super == NULL) {
2675 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2677 cr = iptr->sx.s23.s3.c.ref;
2678 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2680 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2683 M_ILD(REG_ITMP3, REG_PV, disp);
2684 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2685 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2688 /* interface instanceof code */
2690 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2691 if (super == NULL) {
2692 cr = iptr->sx.s23.s3.c.ref;
2694 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2698 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2701 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2702 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2703 M_CMP_IMM(REG_ITMP3, superindex);
2706 M_ALD(REG_ITMP1, REG_ITMP1,
2707 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2708 superindex * sizeof(methodptr*)));
2709 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2712 emit_label_br(cd, BRANCH_LABEL_4);
2714 emit_label(cd, BRANCH_LABEL_3);
2717 /* class instanceof code */
2719 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2720 if (super == NULL) {
2721 emit_label(cd, BRANCH_LABEL_2);
2723 cr = iptr->sx.s23.s3.c.ref;
2724 disp = dseg_add_unique_address(cd, NULL);
2726 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2730 disp = dseg_add_address(cd, supervftbl);
2732 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2735 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2736 M_ALD(REG_ITMP2, REG_PV, disp);
2737 #if defined(ENABLE_THREADS)
2738 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2740 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2741 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2742 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2743 #if defined(ENABLE_THREADS)
2744 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2746 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2747 M_CMP(REG_ITMP1, REG_ITMP2);
2748 M_XCMOVULE_IMM(1, d);
2751 emit_label(cd, BRANCH_LABEL_5);
2754 if (super == NULL) {
2755 emit_label(cd, BRANCH_LABEL_1);
2756 emit_label(cd, BRANCH_LABEL_4);
2759 emit_store_dst(jd, iptr, d);
2763 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2765 /* check for negative sizes and copy sizes to stack if necessary */
2767 MCODECHECK((iptr->s1.argcount << 1) + 64);
2769 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2771 var = VAR(iptr->sx.s23.s2.args[s1]);
2773 /* copy SAVEDVAR sizes to stack */
2775 /* Already Preallocated? */
2777 if (!(var->flags & PREALLOC)) {
2778 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2779 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2783 /* arg 0 = dimension count */
2785 ICONST(REG_OUT0, iptr->s1.argcount);
2787 /* is patcher function set? */
2789 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2790 disp = dseg_add_unique_address(cd, 0);
2792 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2793 iptr->sx.s23.s3.c.ref,
2797 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2799 /* arg 1 = arraydescriptor */
2801 M_ALD(REG_OUT1, REG_PV, disp);
2803 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2805 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2807 /* XXX c abi call */
2808 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2809 M_ALD(REG_ITMP3, REG_PV, disp);
2810 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2813 /* check for exception before result assignment */
2815 emit_exception_check(cd, iptr);
2817 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2818 M_INTMOVE(REG_RESULT_CALLER, d);
2819 emit_store_dst(jd, iptr, d);
2823 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2829 } /* for instruction */
2833 } /* if (bptr -> flags >= BBREACHED) */
2834 } /* for basic block */
2836 dseg_createlinenumbertable(cd);
2838 /* generate stubs */
2840 emit_patcher_stubs(jd);
2841 REPLACEMENT_EMIT_STUBS(jd);
2843 /* everything's ok */
2849 /* createcompilerstub **********************************************************
2851 Creates a stub routine which calls the compiler.
2853 *******************************************************************************/
2855 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
2856 #define COMPILERSTUB_CODESIZE 4 * 4
2858 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2861 u1 *createcompilerstub(methodinfo *m)
2863 u1 *s; /* memory to hold the stub */
2869 s = CNEW(u1, COMPILERSTUB_SIZE);
2871 /* set data pointer and code pointer */
2874 s = s + COMPILERSTUB_DATASIZE;
2876 /* mark start of dump memory area */
2878 dumpsize = dump_size();
2880 cd = DNEW(codegendata);
2883 /* Store the codeinfo pointer in the same place as in the
2884 methodheader for compiled methods. */
2886 code = code_codeinfo_new(m);
2888 d[0] = (ptrint) asm_call_jit_compiler;
2890 d[2] = (ptrint) code;
2892 /* code for the stub */
2893 /* no window save yet, user caller's PV */
2894 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2895 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2896 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2899 #if defined(ENABLE_STATISTICS)
2901 count_cstub_len += COMPILERSTUB_SIZE;
2904 /* release dump area */
2906 dump_release(dumpsize);
2913 /* createnativestub ************************************************************
2915 Creates a stub routine which calls a native method.
2917 *******************************************************************************/
2919 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2927 s4 i, j; /* count variables */
2930 s4 funcdisp; /* displacement of the function */
2932 /* get required compiler data */
2939 /* initialize variables */
2942 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2944 /* calculate stack frame size */
2946 cd->stackframesize =
2947 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2948 sizeof(localref_table) / SIZEOF_VOID_P +
2949 md->paramcount + /* for saving arguments over calls */
2950 nmd->memuse + /* nmd knows about the native stackframe layout */
2953 /* create method header */
2955 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2956 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2957 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2958 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2959 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2960 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2961 (void) dseg_addlinenumbertablesize(cd);
2962 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2964 /* generate stub code */
2966 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
2968 #if !defined(NDEBUG)
2969 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2970 emit_verbosecall_enter(jd);
2973 /* get function address (this must happen before the stackframeinfo) */
2975 funcdisp = dseg_add_functionptr(cd, f);
2977 #if !defined(WITH_STATIC_CLASSPATH)
2979 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
2983 /* save float argument registers */
2985 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2986 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2987 M_DST(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
2992 /* prepare data structures for native function call */
2994 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
2995 M_MOV(REG_PV_CALLEE, REG_OUT1);
2996 M_MOV(REG_FP, REG_OUT2); /* java sp */
2997 M_MOV(REG_RA_CALLEE, REG_OUT3);
2998 disp = dseg_add_functionptr(cd, codegen_start_native_call);
2999 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3000 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3001 M_NOP; /* XXX fill me! */
3003 /* restore float argument registers */
3005 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3006 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3007 M_DLD(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
3012 /* copy or spill arguments to new locations */
3013 int num_fltregargs = 0;
3014 int fltregarg_inswap[16];
3015 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3016 t = md->paramtypes[i].type;
3018 if (IS_INT_LNG_TYPE(t)) {
3019 if (!md->params[i].inmemory) {
3020 s1 = rd->argintregs[md->params[i].regoff];
3021 /* s1 refers to the old window, transpose */
3022 s1 = REG_WINDOW_TRANSPOSE(s1);
3024 if (!nmd->params[j].inmemory) {
3025 s2 = nat_argintregs[nmd->params[j].regoff];
3028 s2 = nmd->params[j].regoff - 6;
3029 M_AST(s1, REG_SP, CSTACK + s2 * 8);
3033 s1 = md->params[i].regoff + cd->stackframesize;
3034 s2 = nmd->params[j].regoff - 6;
3035 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3036 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3040 if (!md->params[i].inmemory) {
3041 s1 = rd->argfltregs[md->params[i].regoff];
3043 if (!nmd->params[j].inmemory) {
3044 /* no mapping to regs needed, native flt args use regoff */
3045 s2 = nmd->params[j].regoff;
3047 /* we cannot move flt regs to their native arg locations directly */
3048 M_DMOV(s1, s2 + 16);
3049 fltregarg_inswap[num_fltregargs] = s2;
3051 printf("flt arg swap to %d\n", s2 + 16);
3054 s2 = nmd->params[j].regoff;
3055 if (IS_2_WORD_TYPE(t))
3056 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3058 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3062 s1 = md->params[i].regoff + cd->stackframesize;
3063 s2 = nmd->params[j].regoff - 6;
3064 if (IS_2_WORD_TYPE(t)) {
3065 M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3066 M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3068 M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3069 M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3075 /* move swapped float args to target regs */
3076 for (i = 0; i < num_fltregargs; i++) {
3077 s1 = fltregarg_inswap[i];
3078 M_DMOV(s1 + 16, s1);
3079 printf("float arg to target reg: %d ==> %d\n", s1+16, s1);
3083 /* put class into second argument register */
3085 if (m->flags & ACC_STATIC) {
3086 disp = dseg_add_address(cd, m->class);
3087 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3090 /* put env into first argument register */
3092 disp = dseg_add_address(cd, _Jv_env);
3093 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3095 /* do the native function call */
3097 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3098 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3099 M_NOP; /* delay slot */
3101 /* save return value */
3103 if (md->returntype.type != TYPE_VOID) {
3104 if (IS_INT_LNG_TYPE(md->returntype.type))
3105 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3107 M_DST(REG_FRESULT, REG_SP, CSTACK);
3110 /* Note: native functions return float values in %f0 (see ABI) */
3111 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3113 #if !defined(NDEBUG)
3114 /* But for the trace function we need to put a flt result into %f1 */
3115 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3116 if (!IS_2_WORD_TYPE(md->returntype.type))
3117 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3118 emit_verbosecall_exit(jd);
3122 /* remove native stackframe info */
3124 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3125 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3126 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3127 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3128 M_NOP; /* XXX fill me! */
3129 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3131 /* restore float return value, int return value already in our return reg */
3133 if (md->returntype.type != TYPE_VOID) {
3134 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3135 if (IS_2_WORD_TYPE(md->returntype.type))
3136 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3138 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3142 /* check for exception */
3144 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3147 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3150 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3152 M_RET(REG_RA_CALLER, 8); /* return to caller */
3153 M_NOP; /* DELAY SLOT */
3156 /* handle exception */
3158 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3159 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3160 M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);/* jump to asm exception handler */
3161 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address (DELAY) */
3163 /* generate patcher stubs */
3165 emit_patcher_stubs(jd);
3169 return code->entrypoint;
3173 * These are local overrides for various environment variables in Emacs.
3174 * Please do not remove this and leave it at the end of the file, where
3175 * Emacs will automagically detect them.
3176 * ---------------------------------------------------------------------
3179 * indent-tabs-mode: t
3183 * vim:noexpandtab:sw=4:ts=4: