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 */
861 /* constant is actually constant - 1 */
863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
864 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 M_MOV(s1, REG_ITMP1);
869 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
870 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 4095)) {
871 M_AND_IMM(s1, iptr->sx.val.i, d);
874 M_SUB(REG_ZERO, s1, d);
875 M_AND_IMM(d, iptr->sx.val.i, d);
877 ICONST(REG_ITMP2, iptr->sx.val.i);
878 M_AND(s1, REG_ITMP2, d);
881 M_SUB(REG_ZERO, s1, d);
882 M_AND(d, REG_ITMP2, d);
884 M_SUB(REG_ZERO, d, d);
885 emit_store_dst(jd, iptr, d);
888 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
889 /* sx.val.l = constant */
891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
893 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
894 M_AND_IMM(s1, iptr->sx.val.l, d);
896 LCONST(REG_ITMP2, iptr->sx.val.l);
897 M_AND(s1, REG_ITMP2, d);
899 emit_store_dst(jd, iptr, d);
902 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
903 /* sx.val.l = constant */
905 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
906 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
908 M_MOV(s1, REG_ITMP1);
911 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
912 M_AND_IMM(s1, iptr->sx.val.l, d);
915 M_SUB(REG_ZERO, s1, d);
916 M_AND_IMM(d, iptr->sx.val.l, d);
918 LCONST(REG_ITMP2, iptr->sx.val.l);
919 M_AND(s1, REG_ITMP2, d);
922 M_SUB(REG_ZERO, s1, d);
923 M_AND(d, REG_ITMP2, d);
925 M_SUB(REG_ZERO, d, d);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
933 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
934 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
936 emit_store_dst(jd, iptr, d);
939 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
940 /* sx.val.i = constant */
942 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
943 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
944 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
945 M_OR_IMM(s1, iptr->sx.val.i, d);
947 ICONST(REG_ITMP2, iptr->sx.val.i);
948 M_OR(s1, REG_ITMP2, d);
950 emit_store_dst(jd, iptr, d);
953 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
954 /* sx.val.l = constant */
956 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
958 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
959 M_OR_IMM(s1, iptr->sx.val.l, d);
961 LCONST(REG_ITMP2, iptr->sx.val.l);
962 M_OR(s1, REG_ITMP2, d);
964 emit_store_dst(jd, iptr, d);
967 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
972 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974 emit_store_dst(jd, iptr, d);
977 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
978 /* sx.val.i = constant */
980 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
981 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
982 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
983 M_XOR_IMM(s1, iptr->sx.val.i, d);
985 ICONST(REG_ITMP2, iptr->sx.val.i);
986 M_XOR(s1, REG_ITMP2, d);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
992 /* sx.val.l = constant */
994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
996 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
997 M_XOR_IMM(s1, iptr->sx.val.l, d);
999 LCONST(REG_ITMP2, iptr->sx.val.l);
1000 M_XOR(s1, REG_ITMP2, d);
1002 emit_store_dst(jd, iptr, d);
1006 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1009 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013 M_XCMOVLT_IMM(-1, d);
1014 M_XCMOVGT_IMM(1, d);
1015 emit_store_dst(jd, iptr, d);
1019 /* floating operations ************************************************/
1021 case ICMD_FNEG: /* ..., value ==> ..., - value */
1023 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1024 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_DNEG: /* ..., value ==> ..., - value */
1031 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1032 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1034 emit_store_dst(jd, iptr, d);
1037 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1039 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1040 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1041 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1048 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1049 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1050 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1052 emit_store_dst(jd, iptr, d);
1055 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1057 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1058 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1059 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1061 emit_store_dst(jd, iptr, d);
1064 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1066 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1067 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1068 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1075 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1076 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1077 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1084 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1085 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1086 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1093 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1094 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1095 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1097 emit_store_dst(jd, iptr, d);
1100 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1102 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1103 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1104 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1106 emit_store_dst(jd, iptr, d);
1110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1112 disp = dseg_add_float(cd, 0.0);
1113 M_IST (s1, REG_PV_CALLEE, disp);
1114 M_FLD (d, REG_PV_CALLEE, disp);
1115 M_CVTIF (d, d); /* rd gets translated to double target register */
1116 emit_store_dst(jd, iptr, d);
1120 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1121 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1122 disp = dseg_add_float(cd, 0.0);
1123 M_IST(s1, REG_PV_CALLEE, disp);
1124 M_FLD(REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1125 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1126 emit_store_dst(jd, iptr, d);
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1132 disp = dseg_add_double(cd, 0.0);
1133 M_STX(s1, REG_PV_CALLEE, disp);
1134 M_DLD(REG_FTMP3, REG_PV_CALLEE, disp);
1135 M_CVTLF(REG_FTMP3, d);
1136 emit_store_dst(jd, iptr, d);
1140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1142 disp = dseg_add_double(cd, 0.0);
1143 M_STX(s1, REG_PV_CALLEE, disp);
1144 M_DLD(d, REG_PV_CALLEE, disp);
1146 emit_store_dst(jd, iptr, d);
1149 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1150 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1152 disp = dseg_add_float(cd, 0.0);
1153 M_CVTFI(s1, REG_FTMP2);
1154 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1155 M_ILD(d, REG_PV, disp);
1156 emit_store_dst(jd, iptr, d);
1160 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1161 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1162 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1163 disp = dseg_add_float(cd, 0.0);
1164 M_CVTDI(s1, REG_FTMP2);
1165 M_FST(REG_FTMP2, REG_PV, disp);
1166 M_ILD(d, REG_PV, disp);
1167 emit_store_dst(jd, iptr, d);
1170 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1171 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1172 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1173 disp = dseg_add_double(cd, 0.0);
1174 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1175 M_DST(REG_FTMP2, REG_PV, disp);
1176 M_LDX(d, REG_PV, disp);
1177 emit_store_dst(jd, iptr, d);
1180 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1181 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1182 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1183 disp = dseg_add_double(cd, 0.0);
1184 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1185 M_DST(REG_FTMP2, REG_PV, disp);
1186 M_LDX(d, REG_PV, disp);
1187 emit_store_dst(jd, iptr, d);
1190 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1192 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1193 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1195 emit_store_dst(jd, iptr, d);
1198 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1200 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1201 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1203 emit_store_dst(jd, iptr, d);
1206 /* XXX merge F/D versions? only compare instr. is different */
1207 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1209 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1210 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1211 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1213 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1214 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1215 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1221 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1222 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1223 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1225 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1226 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1227 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1233 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1237 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1238 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1239 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1240 emit_store_dst(jd, iptr, d);
1243 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1245 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1246 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1249 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1250 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1251 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1252 emit_store_dst(jd, iptr, d);
1256 /* memory operations **************************************************/
1258 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1260 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1261 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1262 emit_nullpointer_check(cd, iptr, s1);
1263 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1264 emit_store_dst(jd, iptr, d);
1267 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1269 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1270 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1271 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1272 /* implicit null-pointer check */
1273 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1274 M_AADD(s2, s1, REG_ITMP3);
1275 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1276 emit_store_dst(jd, iptr, d);
1279 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1282 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1283 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1284 /* implicit null-pointer check */
1285 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1286 M_AADD(s2, s1, REG_ITMP3);
1287 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1288 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1289 emit_store_dst(jd, iptr, d);
1292 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1295 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1296 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1297 /* implicit null-pointer check */
1298 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1299 M_AADD(s2, s1, REG_ITMP3);
1300 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1301 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1302 emit_store_dst(jd, iptr, d);
1305 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1308 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1309 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1310 /* implicit null-pointer check */
1311 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1312 M_ASLL_IMM(s2, 2, REG_ITMP3);
1313 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1314 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1315 emit_store_dst(jd, iptr, d);
1318 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1321 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1322 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1323 /* implicit null-pointer check */
1324 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1325 M_ASLL_IMM(s2, 3, REG_ITMP3);
1326 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1327 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1328 emit_store_dst(jd, iptr, d);
1331 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1334 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1335 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1336 /* implicit null-pointer check */
1337 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1338 M_ASLL_IMM(s2, 2, REG_ITMP3);
1339 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1340 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1341 emit_store_dst(jd, iptr, d);
1344 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1347 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1348 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1349 /* implicit null-pointer check */
1350 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1351 M_ASLL_IMM(s2, 3, REG_ITMP3);
1352 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1353 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1354 emit_store_dst(jd, iptr, d);
1357 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1360 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1361 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1362 /* implicit null-pointer check */
1363 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1364 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1365 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1366 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1367 emit_store_dst(jd, iptr, d);
1371 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1373 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1374 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1375 /* implicit null-pointer check */
1376 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1377 M_AADD(s2, s1, REG_ITMP1);
1378 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1379 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1382 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1383 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1385 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1386 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1387 /* implicit null-pointer check */
1388 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1389 M_AADD(s2, s1, REG_ITMP1);
1390 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1391 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1392 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1395 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1397 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1398 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1399 /* implicit null-pointer check */
1400 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1401 M_ASLL_IMM(s2, 2, REG_ITMP2);
1402 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1403 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1404 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1407 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1409 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1410 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1411 /* implicit null-pointer check */
1412 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1413 M_ASLL_IMM(s2, 3, REG_ITMP2);
1414 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1415 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1416 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1419 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1421 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1422 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1423 /* implicit null-pointer check */
1424 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1425 M_ASLL_IMM(s2, 2, REG_ITMP2);
1426 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1427 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1428 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1431 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1433 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1434 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1435 /* implicit null-pointer check */
1436 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1437 M_ASLL_IMM(s2, 3, REG_ITMP2);
1438 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1439 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1440 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1444 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1447 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1448 /* implicit null-pointer check */
1449 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1450 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1452 M_MOV(s1, rd->argintregs[0]);
1453 M_MOV(s3, rd->argintregs[1]);
1454 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1455 M_ALD(REG_ITMP3, REG_PV, disp);
1456 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1458 emit_exception_check(cd, iptr);
1460 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1461 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1462 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1463 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1464 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1465 /* implicit null-pointer check */
1466 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1470 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1473 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1474 /* implicit null-pointer check */
1475 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1476 M_AADD(s2, s1, REG_ITMP1);
1477 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1480 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1481 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1485 /* implicit null-pointer check */
1486 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487 M_AADD(s2, s1, REG_ITMP1);
1488 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1489 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1492 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1494 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1495 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1496 /* implicit null-pointer check */
1497 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1498 M_ASLL_IMM(s2, 2, REG_ITMP2);
1499 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1500 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1503 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1507 /* implicit null-pointer check */
1508 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1509 M_ASLL_IMM(s2, 3, REG_ITMP2);
1510 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1511 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1514 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1517 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1518 /* implicit null-pointer check */
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1521 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1522 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1526 case ICMD_GETSTATIC: /* ... ==> ..., value */
1528 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1529 uf = iptr->sx.s23.s3.uf;
1530 fieldtype = uf->fieldref->parseddesc.fd->type;
1531 disp = dseg_add_unique_address(cd, uf);
1533 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1536 fi = iptr->sx.s23.s3.fmiref->p.field;
1537 fieldtype = fi->type;
1538 disp = dseg_add_address(cd, &(fi->value));
1540 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1541 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1544 M_ALD(REG_ITMP1, REG_PV, disp);
1546 switch (fieldtype) {
1548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1549 M_ILD_INTERN(d, REG_ITMP1, 0);
1552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1553 M_LDX_INTERN(d, REG_ITMP1, 0);
1556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1557 M_ALD_INTERN(d, REG_ITMP1, 0);
1560 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1561 M_FLD_INTERN(d, REG_ITMP1, 0);
1564 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1565 M_DLD_INTERN(d, REG_ITMP1, 0);
1568 emit_store_dst(jd, iptr, d);
1571 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1573 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1574 uf = iptr->sx.s23.s3.uf;
1575 fieldtype = uf->fieldref->parseddesc.fd->type;
1576 disp = dseg_add_unique_address(cd, uf);
1578 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1581 fi = iptr->sx.s23.s3.fmiref->p.field;
1582 fieldtype = fi->type;
1583 disp = dseg_add_address(cd, &(fi->value));
1585 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1586 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1589 M_ALD(REG_ITMP1, REG_PV, disp);
1591 switch (fieldtype) {
1593 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1594 M_IST_INTERN(s1, REG_ITMP1, 0);
1597 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1598 M_STX_INTERN(s1, REG_ITMP1, 0);
1601 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1602 M_AST_INTERN(s1, REG_ITMP1, 0);
1605 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1606 M_FST_INTERN(s1, REG_ITMP1, 0);
1609 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1610 M_DST_INTERN(s1, REG_ITMP1, 0);
1615 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1616 /* val = value (in current instruction) */
1617 /* following NOP) */
1619 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1620 uf = iptr->sx.s23.s3.uf;
1621 fieldtype = uf->fieldref->parseddesc.fd->type;
1622 disp = dseg_add_unique_address(cd, uf);
1624 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1627 fi = iptr->sx.s23.s3.fmiref->p.field;
1628 fieldtype = fi->type;
1629 disp = dseg_add_address(cd, &(fi->value));
1631 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1632 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1635 M_ALD(REG_ITMP1, REG_PV, disp);
1637 switch (fieldtype) {
1639 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1642 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1645 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1648 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1651 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1657 case ICMD_GETFIELD: /* ... ==> ..., value */
1659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1660 emit_nullpointer_check(cd, iptr, s1);
1662 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1663 uf = iptr->sx.s23.s3.uf;
1665 fieldtype = uf->fieldref->parseddesc.fd->type;
1668 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1671 fi = iptr->sx.s23.s3.fmiref->p.field;
1672 fieldtype = fi->type;
1676 switch (fieldtype) {
1678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1682 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1690 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1694 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1701 emit_store_dst(jd, iptr, d);
1704 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1707 emit_nullpointer_check(cd, iptr, s1);
1709 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1710 uf = iptr->sx.s23.s3.uf;
1711 fieldtype = uf->fieldref->parseddesc.fd->type;
1716 fi = iptr->sx.s23.s3.fmiref->p.field;
1717 fieldtype = fi->type;
1721 if (IS_INT_LNG_TYPE(fieldtype))
1722 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1724 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1726 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1727 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1729 switch (fieldtype) {
1731 M_IST(s2, s1, disp);
1734 M_STX(s2, s1, disp);
1737 M_AST(s2, s1, disp);
1740 M_FST(s2, s1, disp);
1743 M_DST(s2, s1, disp);
1751 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1752 /* val = value (in current instruction) */
1753 /* following NOP) */
1755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1756 emit_nullpointer_check(cd, iptr, s1);
1758 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1759 unresolved_field *uf = iptr->sx.s23.s3.uf;
1761 fieldtype = uf->fieldref->parseddesc.fd->type;
1763 codegen_addpatchref(cd, PATCHER_get_putfield,
1766 if (opt_showdisassemble) {
1774 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1776 fieldtype = fi->type;
1782 switch (fieldtype) {
1784 M_IST(REG_ZERO, s1, disp);
1787 M_STX(REG_ZERO, s1, disp);
1790 M_AST(REG_ZERO, s1, disp);
1793 M_FST(REG_ZERO, s1, disp);
1796 M_DST(REG_ZERO, s1, disp);
1802 /* branch operations **************************************************/
1804 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1807 M_INTMOVE(s1, REG_ITMP2_XPTR);
1809 #ifdef ENABLE_VERIFIER
1810 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1811 unresolved_class *uc = iptr->sx.s23.s2.uc;
1813 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1815 #endif /* ENABLE_VERIFIER */
1817 disp = dseg_add_functionptr(cd, asm_handle_exception);
1818 M_ALD(REG_ITMP1, REG_PV, disp);
1819 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1821 M_NOP; /* nop ensures that XPC is less than the end */
1822 /* of basic block */
1826 case ICMD_GOTO: /* ... ==> ... */
1827 case ICMD_RET: /* ... ==> ... */
1829 emit_br(cd, iptr->dst.block);
1833 case ICMD_JSR: /* ... ==> ... */
1835 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1839 case ICMD_IFNULL: /* ..., value ==> ... */
1840 case ICMD_IFNONNULL:
1842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1843 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
1846 /* Note: int compares must not branch on the register directly. */
1847 /* Reason is, that register content is not 32-bit clean. */
1849 case ICMD_IFEQ: /* ..., value ==> ... */
1851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1853 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1854 M_CMP_IMM(s1, iptr->sx.val.i);
1857 ICONST(REG_ITMP2, iptr->sx.val.i);
1858 M_CMP(s1, REG_ITMP2);
1860 emit_beq(cd, iptr->dst.block);
1863 case ICMD_IFLT: /* ..., value ==> ... */
1865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1867 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1868 M_CMP_IMM(s1, iptr->sx.val.i);
1871 ICONST(REG_ITMP2, iptr->sx.val.i);
1872 M_CMP(s1, REG_ITMP2);
1874 emit_blt(cd, iptr->dst.block);
1877 case ICMD_IFLE: /* ..., value ==> ... */
1879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1881 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1882 M_CMP_IMM(s1, iptr->sx.val.i);
1885 ICONST(REG_ITMP2, iptr->sx.val.i);
1886 M_CMP(s1, REG_ITMP2);
1888 emit_ble(cd, iptr->dst.block);
1891 case ICMD_IFNE: /* ..., value ==> ... */
1893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1896 M_CMP_IMM(s1, iptr->sx.val.i);
1899 ICONST(REG_ITMP2, iptr->sx.val.i);
1900 M_CMP(s1, REG_ITMP2);
1902 emit_bne(cd, iptr->dst.block);
1905 case ICMD_IFGT: /* ..., value ==> ... */
1907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1909 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1910 M_CMP_IMM(s1, iptr->sx.val.i);
1913 ICONST(REG_ITMP2, iptr->sx.val.i);
1914 M_CMP(s1, REG_ITMP2);
1916 emit_bgt(cd, iptr->dst.block);
1919 case ICMD_IFGE: /* ..., value ==> ... */
1921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1923 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1924 M_CMP_IMM(s1, iptr->sx.val.i);
1927 ICONST(REG_ITMP2, iptr->sx.val.i);
1928 M_CMP(s1, REG_ITMP2);
1930 emit_bge(cd, iptr->dst.block);
1933 case ICMD_IF_LEQ: /* ..., value ==> ... */
1935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1936 if (iptr->sx.val.l == 0)
1937 emit_beqz(cd, iptr->dst.block, s1);
1939 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1940 M_CMP_IMM(s1, iptr->sx.val.l);
1943 LCONST(REG_ITMP2, iptr->sx.val.l);
1944 M_CMP(s1, REG_ITMP2);
1946 emit_beq_xcc(cd, iptr->dst.block);
1950 case ICMD_IF_LLT: /* ..., value ==> ... */
1952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 if (iptr->sx.val.l == 0)
1954 emit_bltz(cd, iptr->dst.block, s1);
1956 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1957 M_CMP_IMM(s1, iptr->sx.val.l);
1960 LCONST(REG_ITMP2, iptr->sx.val.l);
1961 M_CMP(s1, REG_ITMP2);
1963 emit_blt_xcc(cd, iptr->dst.block);
1967 case ICMD_IF_LLE: /* ..., value ==> ... */
1969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1970 if (iptr->sx.val.l == 0)
1971 emit_blez(cd, iptr->dst.block, s1);
1973 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1974 M_CMP_IMM(s1, iptr->sx.val.l);
1977 LCONST(REG_ITMP2, iptr->sx.val.l);
1978 M_CMP(s1, REG_ITMP2);
1980 emit_ble_xcc(cd, iptr->dst.block);
1984 case ICMD_IF_LNE: /* ..., value ==> ... */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 if (iptr->sx.val.l == 0)
1988 emit_bnez(cd, iptr->dst.block, s1);
1990 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1991 M_CMP_IMM(s1, iptr->sx.val.l);
1994 LCONST(REG_ITMP2, iptr->sx.val.l);
1995 M_CMP(s1, REG_ITMP2);
1997 emit_bne_xcc(cd, iptr->dst.block);
2001 case ICMD_IF_LGT: /* ..., value ==> ... */
2003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2004 if (iptr->sx.val.l == 0)
2005 emit_bgtz(cd, iptr->dst.block, s1);
2007 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2008 M_CMP_IMM(s1, iptr->sx.val.l);
2011 LCONST(REG_ITMP2, iptr->sx.val.l);
2012 M_CMP(s1, REG_ITMP2);
2014 emit_bgt_xcc(cd, iptr->dst.block);
2018 case ICMD_IF_LGE: /* ..., value ==> ... */
2020 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2021 if (iptr->sx.val.l == 0)
2022 emit_bgez(cd, iptr->dst.block, s1);
2024 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2025 M_CMP_IMM(s1, iptr->sx.val.l);
2028 LCONST(REG_ITMP2, iptr->sx.val.l);
2029 M_CMP(s1, REG_ITMP2);
2031 emit_bge_xcc(cd, iptr->dst.block);
2036 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2037 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2040 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2042 emit_beq_xcc(cd, iptr->dst.block);
2045 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2050 emit_beq(cd, iptr->dst.block);
2053 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2054 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2057 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2059 emit_bne_xcc(cd, iptr->dst.block);
2062 case ICMD_IF_ICMPNE: /* 32-bit compare */
2064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2065 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2067 emit_bne(cd, iptr->dst.block);
2070 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2073 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2075 emit_blt_xcc(cd, iptr->dst.block);
2078 case ICMD_IF_ICMPLT: /* 32-bit compare */
2080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2081 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2083 emit_blt(cd, iptr->dst.block);
2086 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2091 emit_bgt_xcc(cd, iptr->dst.block);
2094 case ICMD_IF_ICMPGT: /* 32-bit compare */
2096 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2097 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2099 emit_bgt(cd, iptr->dst.block);
2102 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2105 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2107 emit_ble_xcc(cd, iptr->dst.block);
2110 case ICMD_IF_ICMPLE: /* 32-bit compare */
2112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2115 emit_ble(cd, iptr->dst.block);
2119 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2124 emit_bge_xcc(cd, iptr->dst.block);
2127 case ICMD_IF_ICMPGE: /* 32-bit compare */
2129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2130 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2132 emit_bge(cd, iptr->dst.block);
2136 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2139 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2140 M_INTMOVE(s1, REG_RESULT_CALLEE);
2141 goto nowperformreturn;
2143 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2145 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2146 M_INTMOVE(s1, REG_RESULT_CALLEE);
2148 #ifdef ENABLE_VERIFIER
2149 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2150 unresolved_class *uc = iptr->sx.s23.s2.uc;
2152 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2154 #endif /* ENABLE_VERIFIER */
2155 goto nowperformreturn;
2157 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2160 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2161 M_DBLMOVE(s1, REG_FRESULT);
2162 goto nowperformreturn;
2164 case ICMD_RETURN: /* ... ==> ... */
2170 p = cd->stackframesize;
2172 #if !defined(NDEBUG)
2173 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2174 emit_verbosecall_exit(jd);
2177 #if defined(ENABLE_THREADS)
2178 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2179 /* XXX: REG_RESULT is save, but what about FRESULT? */
2180 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2182 switch (iptr->opc) {
2185 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2189 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2190 M_ALD(REG_ITMP3, REG_PV, disp);
2191 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2193 switch (iptr->opc) {
2196 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2204 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2210 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2213 branch_target_t *table;
2215 table = iptr->dst.table;
2217 l = iptr->sx.s23.s2.tablelow;
2218 i = iptr->sx.s23.s3.tablehigh;
2220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2222 M_INTMOVE(s1, REG_ITMP1);
2224 else if (l <= 4095) {
2225 M_ADD_IMM(s1, -l, REG_ITMP1);
2228 ICONST(REG_ITMP2, l);
2229 /* XXX: do I need to truncate s1 to 32-bit ? */
2230 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2238 M_CMP_IMM(REG_ITMP1, i - 1);
2241 ICONST(REG_ITMP2, i - 1);
2242 M_CMP(REG_ITMP1, REG_ITMP2);
2244 emit_bugt(cd, table[0].block); /* default target */
2246 /* build jump table top down and use address of lowest entry */
2251 dseg_add_target(cd, table->block);
2256 /* length of dataseg after last dseg_addtarget is used by load */
2258 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2259 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2260 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2261 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2266 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2269 lookup_target_t *lookup;
2271 lookup = iptr->dst.lookup;
2273 i = iptr->sx.s23.s2.lookupcount;
2275 MCODECHECK((i<<2)+8);
2276 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2279 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2280 M_CMP_IMM(s1, lookup->value);
2282 ICONST(REG_ITMP2, lookup->value);
2283 M_CMP(s1, REG_ITMP2);
2285 emit_beq(cd, lookup->target.block);
2289 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2295 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2297 bte = iptr->sx.s23.s3.bte;
2300 /* XXX: builtin calling with stack arguments not implemented */
2301 assert(md->paramcount <= 5 && md->argfltreguse <= 16);
2303 s3 = md->paramcount;
2305 MCODECHECK((s3 << 1) + 64);
2307 /* copy float arguments according to ABI convention */
2309 int num_fltregargs = 0;
2310 int fltregarg_inswap[16];
2312 for (s3 = s3 - 1; s3 >= 0; s3--) {
2313 var = VAR(iptr->sx.s23.s2.args[s3]);
2315 if (var->flags & PREALLOC)
2318 if (IS_FLT_DBL_TYPE(var->type)) {
2319 if (!md->params[s3].inmemory) {
2320 s1 = md->params[s3].regoff; /*native flt args use regoff directly*/
2321 d = emit_load(jd, iptr, var, REG_FTMP1);
2324 fltregarg_inswap[num_fltregargs] = s1;
2326 /*printf("builtin: flt arg swap to %d\n", s1 + 16);*/
2335 /* move swapped float args to target regs */
2336 for (i = 0; i < num_fltregargs; i++) {
2337 s1 = fltregarg_inswap[i];
2338 M_DMOV(s1 + 16, s1);
2339 /*printf("builtin float arg to target reg: %d ==> %d\n", s1+16, s1);*/
2344 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2346 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2347 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2348 case ICMD_INVOKEINTERFACE:
2350 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2352 um = iptr->sx.s23.s3.um;
2353 md = um->methodref->parseddesc.md;
2356 lm = iptr->sx.s23.s3.fmiref->p.method;
2358 md = lm->parseddesc;
2362 s3 = md->paramcount;
2364 MCODECHECK((s3 << 1) + 64);
2366 /* copy arguments to registers or stack location */
2368 for (s3 = s3 - 1; s3 >= 0; s3--) {
2369 var = VAR(iptr->sx.s23.s2.args[s3]);
2371 if (var->flags & PREALLOC)
2374 if (IS_INT_LNG_TYPE(var->type)) {
2375 if (!md->params[s3].inmemory) {
2376 s1 = rd->argintregs[md->params[s3].regoff];
2377 d = emit_load(jd, iptr, var, s1);
2381 d = emit_load(jd, iptr, var, REG_ITMP1);
2382 M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2386 if (iptr->opc == ICMD_BUILTIN)
2389 if (!md->params[s3].inmemory) {
2390 s1 = rd->argfltregs[md->params[s3].regoff];
2391 d = emit_load(jd, iptr, var, s1);
2392 if (IS_2_WORD_TYPE(var->type))
2398 d = emit_load(jd, iptr, var, REG_FTMP1);
2399 if (IS_2_WORD_TYPE(var->type))
2400 M_DST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2402 M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2407 switch (iptr->opc) {
2409 disp = dseg_add_functionptr(cd, bte->fp);
2411 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2413 /* XXX jit-c-call */
2414 /* generate the actual call */
2416 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2418 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2419 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2420 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2422 emit_exception_check(cd, iptr);
2423 if (md->returntype.type == TYPE_FLT) {
2424 /* special handling for float return value in %f0 */
2429 case ICMD_INVOKESPECIAL:
2430 emit_nullpointer_check(cd, iptr, REG_OUT0);
2433 case ICMD_INVOKESTATIC:
2435 disp = dseg_add_unique_address(cd, NULL);
2437 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2441 disp = dseg_add_address(cd, lm->stubroutine);
2443 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2445 /* generate the actual call */
2447 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2449 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2450 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2451 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2454 case ICMD_INVOKEVIRTUAL:
2455 emit_nullpointer_check(cd, iptr, REG_OUT0);
2458 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2463 s1 = OFFSET(vftbl_t, table[0]) +
2464 sizeof(methodptr) * lm->vftblindex;
2466 /* implicit null-pointer check */
2467 M_ALD(REG_METHODPTR, REG_OUT0,OFFSET(java_objectheader, vftbl));
2468 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2470 /* generate the actual call */
2472 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2474 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2475 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2476 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2479 case ICMD_INVOKEINTERFACE:
2480 emit_nullpointer_check(cd, iptr, REG_OUT0);
2483 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2489 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2490 sizeof(methodptr*) * lm->class->index;
2492 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2495 /* implicit null-pointer check */
2496 M_ALD(REG_METHODPTR, REG_OUT0, OFFSET(java_objectheader, vftbl));
2497 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2498 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2500 /* generate the actual call */
2502 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2504 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2505 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2506 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2510 /* store return value */
2512 d = md->returntype.type;
2514 if (d != TYPE_VOID) {
2515 if (IS_INT_LNG_TYPE(d)) {
2516 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2517 M_INTMOVE(REG_RESULT_CALLER, s1);
2520 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2521 if (IS_2_WORD_TYPE(d)) {
2522 M_DBLMOVE(REG_FRESULT, s1);
2524 M_FLTMOVE(REG_FRESULT, s1);
2527 emit_store_dst(jd, iptr, s1);
2532 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2533 /* val.a: (classinfo*) superclass */
2535 /* superclass is an interface:
2537 * OK if ((sub == NULL) ||
2538 * (sub->vftbl->interfacetablelength > super->index) &&
2539 * (sub->vftbl->interfacetable[-super->index] != NULL));
2541 * superclass is a class:
2543 * OK if ((sub == NULL) || (0
2544 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2545 * super->vftbl->diffvall));
2548 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2552 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2557 super = iptr->sx.s23.s3.c.cls;
2558 superindex = super->index;
2561 #if defined(ENABLE_THREADS)
2562 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2567 /* if class is not resolved, check which code to call */
2569 if (super == NULL) {
2570 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2572 cr = iptr->sx.s23.s3.c.ref;
2573 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2575 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2578 M_ILD(REG_ITMP2, REG_PV, disp);
2579 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2580 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2583 /* interface checkcast code */
2585 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2586 if (super == NULL) {
2587 cr = iptr->sx.s23.s3.c.ref;
2589 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2593 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2596 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2597 M_ILD(REG_ITMP3, REG_ITMP2,
2598 OFFSET(vftbl_t, interfacetablelength));
2599 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2600 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2602 M_ALD(REG_ITMP3, REG_ITMP2,
2603 OFFSET(vftbl_t, interfacetable[0]) -
2604 superindex * sizeof(methodptr*));
2605 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2608 emit_label_br(cd, BRANCH_LABEL_4);
2610 emit_label(cd, BRANCH_LABEL_3);
2613 /* class checkcast code */
2615 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2616 if (super == NULL) {
2617 emit_label(cd, BRANCH_LABEL_2);
2619 cr = iptr->sx.s23.s3.c.ref;
2620 disp = dseg_add_unique_address(cd, NULL);
2622 codegen_add_patch_ref(cd,
2623 PATCHER_checkcast_instanceof_class,
2627 disp = dseg_add_address(cd, super->vftbl);
2629 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2632 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2633 M_ALD(REG_ITMP3, REG_PV, disp);
2634 #if defined(ENABLE_THREADS)
2635 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2637 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2638 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2639 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2640 M_ALD(REG_ITMP3, REG_PV, disp);
2641 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2642 #if defined(ENABLE_THREADS)
2643 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2646 M_CMP(REG_ITMP3, REG_ITMP2);
2647 emit_classcast_check(cd, iptr, BRANCH_ULT, REG_ITMP3, s1);
2650 emit_label(cd, BRANCH_LABEL_5);
2653 if (super == NULL) {
2654 emit_label(cd, BRANCH_LABEL_1);
2655 emit_label(cd, BRANCH_LABEL_4);
2658 d = codegen_reg_of_dst(jd, iptr, s1);
2661 /* array type cast-check */
2663 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
2664 M_INTMOVE(s1, rd->argintregs[0]);
2666 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2668 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2669 cr = iptr->sx.s23.s3.c.ref;
2670 disp = dseg_add_unique_address(cd, NULL);
2672 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2676 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2678 M_ALD(rd->argintregs[1], REG_PV, disp);
2679 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2680 M_ALD(REG_ITMP3, REG_PV, disp);
2681 /* XXX jit-c-call */
2682 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2686 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT_CALLER, s1);
2688 d = codegen_reg_of_dst(jd, iptr, s1);
2692 emit_store_dst(jd, iptr, d);
2695 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2696 /* val.a: (classinfo*) superclass */
2698 /* superclass is an interface:
2700 * return (sub != NULL) &&
2701 * (sub->vftbl->interfacetablelength > super->index) &&
2702 * (sub->vftbl->interfacetable[-super->index] != NULL);
2704 * superclass is a class:
2706 * return ((sub != NULL) && (0
2707 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2708 * super->vftbl->diffvall));
2713 vftbl_t *supervftbl;
2716 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2722 super = iptr->sx.s23.s3.c.cls;
2723 superindex = super->index;
2724 supervftbl = super->vftbl;
2727 #if defined(ENABLE_THREADS)
2728 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2733 M_MOV(s1, REG_ITMP1);
2739 /* if class is not resolved, check which code to call */
2741 if (super == NULL) {
2742 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2744 cr = iptr->sx.s23.s3.c.ref;
2745 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2747 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2750 M_ILD(REG_ITMP3, REG_PV, disp);
2751 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2752 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2755 /* interface instanceof code */
2757 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2758 if (super == NULL) {
2759 cr = iptr->sx.s23.s3.c.ref;
2761 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2765 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2768 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2769 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2770 M_CMP_IMM(REG_ITMP3, superindex);
2773 M_ALD(REG_ITMP1, REG_ITMP1,
2774 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2775 superindex * sizeof(methodptr*)));
2776 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2779 emit_label_br(cd, BRANCH_LABEL_4);
2781 emit_label(cd, BRANCH_LABEL_3);
2784 /* class instanceof code */
2786 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2787 if (super == NULL) {
2788 emit_label(cd, BRANCH_LABEL_2);
2790 cr = iptr->sx.s23.s3.c.ref;
2791 disp = dseg_add_unique_address(cd, NULL);
2793 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2797 disp = dseg_add_address(cd, supervftbl);
2799 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2802 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2803 M_ALD(REG_ITMP2, REG_PV, disp);
2804 #if defined(ENABLE_THREADS)
2805 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2807 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2808 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2809 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2810 #if defined(ENABLE_THREADS)
2811 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2813 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2814 M_CMP(REG_ITMP1, REG_ITMP2);
2815 M_XCMOVULE_IMM(1, d);
2818 emit_label(cd, BRANCH_LABEL_5);
2821 if (super == NULL) {
2822 emit_label(cd, BRANCH_LABEL_1);
2823 emit_label(cd, BRANCH_LABEL_4);
2826 emit_store_dst(jd, iptr, d);
2830 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2832 /* check for negative sizes and copy sizes to stack if necessary */
2834 MCODECHECK((iptr->s1.argcount << 1) + 64);
2836 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2838 var = VAR(iptr->sx.s23.s2.args[s1]);
2840 /* copy SAVEDVAR sizes to stack */
2842 /* Already Preallocated? */
2844 if (!(var->flags & PREALLOC)) {
2845 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2846 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2850 /* arg 0 = dimension count */
2852 ICONST(REG_OUT0, iptr->s1.argcount);
2854 /* is patcher function set? */
2856 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2857 disp = dseg_add_unique_address(cd, 0);
2859 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2860 iptr->sx.s23.s3.c.ref,
2864 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2866 /* arg 1 = arraydescriptor */
2868 M_ALD(REG_OUT1, REG_PV, disp);
2870 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2872 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2874 /* XXX c abi call */
2875 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2876 M_ALD(REG_ITMP3, REG_PV, disp);
2877 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2880 /* check for exception before result assignment */
2882 emit_exception_check(cd, iptr);
2884 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2885 M_INTMOVE(REG_RESULT_CALLER, d);
2886 emit_store_dst(jd, iptr, d);
2890 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2896 } /* for instruction */
2900 } /* if (bptr -> flags >= BBREACHED) */
2901 } /* for basic block */
2903 dseg_createlinenumbertable(cd);
2905 /* generate stubs */
2907 emit_patcher_stubs(jd);
2908 REPLACEMENT_EMIT_STUBS(jd);
2910 /* everything's ok */
2916 /* createcompilerstub **********************************************************
2918 Creates a stub routine which calls the compiler.
2920 *******************************************************************************/
2922 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
2923 #define COMPILERSTUB_CODESIZE 4 * 4
2925 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2928 u1 *createcompilerstub(methodinfo *m)
2930 u1 *s; /* memory to hold the stub */
2936 s = CNEW(u1, COMPILERSTUB_SIZE);
2938 /* set data pointer and code pointer */
2941 s = s + COMPILERSTUB_DATASIZE;
2943 /* mark start of dump memory area */
2945 dumpsize = dump_size();
2947 cd = DNEW(codegendata);
2950 /* Store the codeinfo pointer in the same place as in the
2951 methodheader for compiled methods. */
2953 code = code_codeinfo_new(m);
2955 d[0] = (ptrint) asm_call_jit_compiler;
2957 d[2] = (ptrint) code;
2959 /* code for the stub */
2960 /* no window save yet, user caller's PV */
2961 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2962 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2963 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2966 #if defined(ENABLE_STATISTICS)
2968 count_cstub_len += COMPILERSTUB_SIZE;
2971 /* release dump area */
2973 dump_release(dumpsize);
2980 /* createnativestub ************************************************************
2982 Creates a stub routine which calls a native method.
2984 *******************************************************************************/
2986 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2994 s4 i, j; /* count variables */
2997 s4 funcdisp; /* displacement of the function */
2999 /* get required compiler data */
3006 /* initialize variables */
3009 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3011 /* calculate stack frame size */
3013 cd->stackframesize =
3014 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3015 sizeof(localref_table) / SIZEOF_VOID_P +
3016 md->paramcount + /* for saving arguments over calls */
3017 nmd->memuse + /* nmd knows about the native stackframe layout */
3020 /* create method header */
3022 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3023 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3024 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3025 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3026 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3027 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3028 (void) dseg_addlinenumbertablesize(cd);
3029 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3031 /* generate stub code */
3033 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3035 #if !defined(NDEBUG)
3036 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3037 emit_verbosecall_enter(jd);
3040 /* get function address (this must happen before the stackframeinfo) */
3042 funcdisp = dseg_add_functionptr(cd, f);
3044 #if !defined(WITH_STATIC_CLASSPATH)
3046 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3050 /* save float argument registers */
3052 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3053 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3054 M_DST(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
3059 /* prepare data structures for native function call */
3061 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
3062 M_MOV(REG_PV_CALLEE, REG_OUT1);
3063 M_MOV(REG_FP, REG_OUT2); /* java sp */
3064 M_MOV(REG_RA_CALLEE, REG_OUT3);
3065 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3066 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3067 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3068 M_NOP; /* XXX fill me! */
3070 /* restore float argument registers */
3072 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3073 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3074 M_DLD(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
3079 /* copy or spill arguments to new locations */
3080 int num_fltregargs = 0;
3081 int fltregarg_inswap[16];
3082 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3083 t = md->paramtypes[i].type;
3085 if (IS_INT_LNG_TYPE(t)) {
3086 if (!md->params[i].inmemory) {
3087 s1 = rd->argintregs[md->params[i].regoff];
3088 /* s1 refers to the old window, transpose */
3089 s1 = REG_WINDOW_TRANSPOSE(s1);
3091 if (!nmd->params[j].inmemory) {
3092 s2 = nat_argintregs[nmd->params[j].regoff];
3095 s2 = nmd->params[j].regoff - 6;
3096 M_AST(s1, REG_SP, CSTACK + s2 * 8);
3100 s1 = md->params[i].regoff + cd->stackframesize;
3101 s2 = nmd->params[j].regoff - 6;
3102 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3103 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3107 if (!md->params[i].inmemory) {
3108 s1 = rd->argfltregs[md->params[i].regoff];
3110 if (!nmd->params[j].inmemory) {
3111 /* no mapping to regs needed, native flt args use regoff */
3112 s2 = nmd->params[j].regoff;
3114 /* we cannot move flt regs to their native arg locations directly */
3115 M_DMOV(s1, s2 + 16);
3116 fltregarg_inswap[num_fltregargs] = s2;
3118 /*printf("flt arg swap to %d\n", s2 + 16);*/
3121 s2 = nmd->params[j].regoff;
3122 if (IS_2_WORD_TYPE(t))
3123 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3125 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3129 s1 = md->params[i].regoff + cd->stackframesize;
3130 s2 = nmd->params[j].regoff - 6;
3131 if (IS_2_WORD_TYPE(t)) {
3132 M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3133 M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3135 M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3136 M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3142 /* move swapped float args to target regs */
3143 for (i = 0; i < num_fltregargs; i++) {
3144 s1 = fltregarg_inswap[i];
3145 M_DMOV(s1 + 16, s1);
3146 /*printf("float arg to target reg: %d ==> %d\n", s1+16, s1);*/
3150 /* put class into second argument register */
3152 if (m->flags & ACC_STATIC) {
3153 disp = dseg_add_address(cd, m->class);
3154 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3157 /* put env into first argument register */
3159 disp = dseg_add_address(cd, _Jv_env);
3160 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3162 /* do the native function call */
3164 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3165 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3166 M_NOP; /* delay slot */
3168 /* save return value */
3170 if (md->returntype.type != TYPE_VOID) {
3171 if (IS_INT_LNG_TYPE(md->returntype.type))
3172 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3174 M_DST(REG_FRESULT, REG_SP, CSTACK);
3177 /* Note: native functions return float values in %f0 (see ABI) */
3178 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3180 #if !defined(NDEBUG)
3181 /* But for the trace function we need to put a flt result into %f1 */
3182 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3183 if (!IS_2_WORD_TYPE(md->returntype.type))
3184 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3185 emit_verbosecall_exit(jd);
3189 /* remove native stackframe info */
3191 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3192 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3193 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3194 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3195 M_NOP; /* XXX fill me! */
3196 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3198 /* restore float return value, int return value already in our return reg */
3200 if (md->returntype.type != TYPE_VOID) {
3201 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3202 if (IS_2_WORD_TYPE(md->returntype.type))
3203 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3205 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3209 /* check for exception */
3210 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3213 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3216 /* handle exception */
3218 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3219 M_ALD(REG_ITMP1, REG_PV, disp); /* load asm exception handler address */
3220 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address */
3221 M_JMP(REG_ZERO, REG_ITMP1, REG_ZERO);/* jump to asm exception handler */
3222 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3225 /* generate patcher stubs */
3227 emit_patcher_stubs(jd);
3231 return code->entrypoint;
3235 * These are local overrides for various environment variables in Emacs.
3236 * Please do not remove this and leave it at the end of the file, where
3237 * Emacs will automagically detect them.
3238 * ---------------------------------------------------------------------
3241 * indent-tabs-mode: t
3245 * vim:noexpandtab:sw=4:ts=4: