1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
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 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
33 Contains the codegenerator for an MIPS (R4000 or higher) processor.
34 This module generates MIPS machine code for a sequence of
35 intermediate code commands (ICMDs).
37 $Id: codegen.c 6286 2007-01-10 10:03:38Z twisti $
51 #include "vm/jit/mips/arch.h"
52 #include "vm/jit/mips/codegen.h"
54 #include "native/native.h"
56 #if defined(ENABLE_THREADS)
57 # include "threads/native/lock.h"
60 #include "vm/builtin.h"
62 #include "vm/exceptions.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/codegen-common.h"
68 #include "vm/jit/dseg.h"
69 #include "vm/jit/emit-common.h"
70 #include "vm/jit/jit.h"
71 #include "vm/jit/patcher.h"
72 #include "vm/jit/reg.h"
73 #include "vm/jit/replace.h"
75 #if defined(ENABLE_LSRA)
76 # include "vm/jit/allocator/lsra.h"
80 /* codegen *********************************************************************
82 Generates machine code.
84 *******************************************************************************/
86 bool codegen(jitdata *jd)
92 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
131 /* space to save used callee saved registers */
133 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
134 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
136 cd->stackframesize = rd->memuse + savedregs_num;
138 #if defined(ENABLE_THREADS)
139 /* space to save argument of monitor_enter */
141 if (checksync && (m->flags & ACC_SYNCHRONIZED))
142 cd->stackframesize++;
145 /* keep stack 16-byte aligned */
147 if (cd->stackframesize & 1)
148 cd->stackframesize++;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 #if defined(ENABLE_THREADS)
156 /* IsSync contains the offset relative to the stack pointer for the
157 argument of monitor_exit used in the exception handler. Since the
158 offset could be zero and give a wrong meaning of the flag it is
162 if (checksync && (m->flags & ACC_SYNCHRONIZED))
163 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
166 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
168 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
169 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
170 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
171 dseg_addlinenumbertablesize(cd);
172 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_add_target(cd, ex->start);
178 dseg_add_target(cd, ex->end);
179 dseg_add_target(cd, ex->handler);
180 (void) dseg_add_unique_address(cd, ex->catchtype.any);
183 /* create stack frame (if necessary) */
185 if (cd->stackframesize)
186 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
188 /* save return address and used callee saved registers */
190 p = cd->stackframesize;
191 if (!jd->isleafmethod) {
192 p--; M_AST(REG_RA, REG_SP, p * 8);
194 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
195 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
197 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
198 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
201 /* take arguments out of register or stack frame */
205 for (p = 0, l = 0; p < md->paramcount; p++) {
206 t = md->paramtypes[p].type;
208 varindex = jd->local_map[l * 5 + t];
211 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
214 if (varindex == UNUSED)
219 s1 = md->params[p].regoff;
220 if (IS_INT_LNG_TYPE(t)) { /* integer args */
221 if (!md->params[p].inmemory) { /* register arguments */
222 s2 = rd->argintregs[s1];
223 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
224 M_INTMOVE(s2, var->vv.regoff);
225 } else { /* reg arg -> spilled */
226 M_LST(s2, REG_SP, var->vv.regoff * 8);
229 } else { /* stack arguments */
230 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
231 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
232 } else { /* stack arg -> spilled */
233 var->vv.regoff = cd->stackframesize + s1;
237 } else { /* floating args */
238 if (!md->params[p].inmemory) { /* register arguments */
239 s2 = rd->argfltregs[s1];
240 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
241 if (IS_2_WORD_TYPE(t))
242 M_DMOV(s2, var->vv.regoff);
244 M_FMOV(s2, var->vv.regoff);
245 } else { /* reg arg -> spilled */
246 if (IS_2_WORD_TYPE(t))
247 M_DST(s2, REG_SP, var->vv.regoff * 8);
249 M_FST(s2, REG_SP, var->vv.regoff * 8);
252 } else { /* stack arguments */
253 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
254 if (IS_2_WORD_TYPE(t))
255 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
257 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
258 } else /* stack-arg -> spilled */
259 var->vv.regoff = cd->stackframesize + s1;
264 /* call monitorenter function */
266 #if defined(ENABLE_THREADS)
267 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
268 /* stack offset for monitor argument */
272 # if !defined(NDEBUG)
273 if (opt_verbosecall) {
274 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
276 for (p = 0; p < INT_ARG_CNT; p++)
277 M_LST(rd->argintregs[p], REG_SP, p * 8);
279 for (p = 0; p < FLT_ARG_CNT; p++)
280 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
282 s1 += INT_ARG_CNT + FLT_ARG_CNT;
286 /* get correct lock object */
288 if (m->flags & ACC_STATIC) {
289 disp = dseg_add_address(cd, &m->class->object.header);
290 M_ALD(REG_A0, REG_PV, disp);
293 /* emit_nullpointer_check(cd, iptr, REG_A0); */
298 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
299 codegen_add_nullpointerexception_ref(cd);
300 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
305 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
306 M_ALD(REG_ITMP3, REG_PV, disp);
307 M_JSR(REG_RA, REG_ITMP3);
308 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
310 # if !defined(NDEBUG)
311 if (opt_verbosecall) {
312 for (p = 0; p < INT_ARG_CNT; p++)
313 M_LLD(rd->argintregs[p], REG_SP, p * 8);
315 for (p = 0; p < FLT_ARG_CNT; p++)
316 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
319 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
326 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
327 emit_verbosecall_enter(jd);
332 /* end of header generation */
334 /* create replacement points */
336 REPLACEMENT_POINTS_INIT(cd, jd);
338 /* walk through all basic blocks */
340 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
342 /* handle replacement points */
344 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
346 /* store relative start of block */
348 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
350 if (bptr->flags >= BBREACHED) {
351 /* branch resolving */
353 codegen_resolve_branchrefs(cd, bptr);
355 /* copy interface registers to their destination */
359 #if defined(ENABLE_LSRA)
363 src = bptr->invars[len];
364 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
365 /* d = reg_of_var(m, src, REG_ITMP1); */
366 if (!(src->flags & INMEMORY))
370 M_INTMOVE(REG_ITMP1, d);
371 emit_store(jd, NULL, src, d);
378 var = VAR(bptr->invars[len]);
379 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
380 d = codegen_reg_of_var(0, var, REG_ITMP1);
381 M_INTMOVE(REG_ITMP1, d);
382 emit_store(jd, NULL, var, d);
385 assert((var->flags & INOUT));
388 #if defined(ENABLE_LSRA)
391 /* walk through all instructions */
396 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
397 if (iptr->line != currentline) {
398 dseg_addlinenumber(cd, iptr->line);
399 currentline = iptr->line;
402 MCODECHECK(64); /* an instruction usually needs < 64 words */
406 case ICMD_NOP: /* ... ==> ... */
407 case ICMD_POP: /* ..., value ==> ... */
408 case ICMD_POP2: /* ..., value, value ==> ... */
411 case ICMD_INLINE_START:
413 REPLACEMENT_POINT_INLINE_START(cd, iptr);
416 case ICMD_INLINE_BODY:
418 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
419 dseg_addlinenumber_inline_start(cd, iptr);
420 dseg_addlinenumber(cd, iptr->line);
423 case ICMD_INLINE_END:
425 dseg_addlinenumber_inline_end(cd, iptr);
426 dseg_addlinenumber(cd, iptr->line);
429 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
432 emit_nullpointer_check(cd, iptr, s1);
435 /* constant operations ************************************************/
437 case ICMD_ICONST: /* ... ==> ..., constant */
439 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
440 ICONST(d, iptr->sx.val.i);
441 emit_store_dst(jd, iptr, d);
444 case ICMD_LCONST: /* ... ==> ..., constant */
446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
447 LCONST(d, iptr->sx.val.l);
448 emit_store_dst(jd, iptr, d);
451 case ICMD_FCONST: /* ... ==> ..., constant */
453 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
454 disp = dseg_add_float(cd, iptr->sx.val.f);
455 M_FLD(d, REG_PV, disp);
456 emit_store_dst(jd, iptr, d);
459 case ICMD_DCONST: /* ... ==> ..., constant */
461 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
462 disp = dseg_add_double(cd, iptr->sx.val.d);
463 M_DLD(d, REG_PV, disp);
464 emit_store_dst(jd, iptr, d);
467 case ICMD_ACONST: /* ... ==> ..., constant */
469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
471 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
472 cr = iptr->sx.val.c.ref;
473 disp = dseg_add_unique_address(cd, cr);
475 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
477 M_ALD(d, REG_PV, disp);
480 if (iptr->sx.val.anyptr == NULL)
481 M_INTMOVE(REG_ZERO, d);
483 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
484 M_ALD(d, REG_PV, disp);
487 emit_store_dst(jd, iptr, d);
491 /* load/store/copy/move operations ************************************/
493 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
494 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
495 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
496 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
497 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
498 case ICMD_ISTORE: /* ..., value ==> ... */
499 case ICMD_LSTORE: /* ..., value ==> ... */
500 case ICMD_FSTORE: /* ..., value ==> ... */
501 case ICMD_DSTORE: /* ..., value ==> ... */
505 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
509 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
510 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
514 /* integer operations *************************************************/
516 case ICMD_INEG: /* ..., value ==> ..., - value */
518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
520 M_ISUB(REG_ZERO, s1, d);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_LNEG: /* ..., value ==> ..., - value */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528 M_LSUB(REG_ZERO, s1, d);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_I2L: /* ..., value ==> ..., value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
537 emit_store_dst(jd, iptr, d);
540 case ICMD_L2I: /* ..., value ==> ..., value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
544 M_ISLL_IMM(s1, 0, d );
545 emit_store_dst(jd, iptr, d);
548 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552 M_LSLL_IMM(s1, 56, d);
553 M_LSRA_IMM( d, 56, d);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
562 emit_store_dst(jd, iptr, d);
565 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
569 M_LSLL_IMM(s1, 48, d);
570 M_LSRA_IMM( d, 48, d);
571 emit_store_dst(jd, iptr, d);
575 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
581 emit_store_dst(jd, iptr, d);
585 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
586 /* sx.val.i = constant */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
590 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
591 M_IADD_IMM(s1, iptr->sx.val.i, d);
593 ICONST(REG_ITMP2, iptr->sx.val.i);
594 M_IADD(s1, REG_ITMP2, d);
596 emit_store_dst(jd, iptr, d);
599 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 emit_store_dst(jd, iptr, d);
608 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
609 /* sx.val.l = constant */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
613 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
614 M_LADD_IMM(s1, iptr->sx.val.l, d);
616 LCONST(REG_ITMP2, iptr->sx.val.l);
617 M_LADD(s1, REG_ITMP2, d);
619 emit_store_dst(jd, iptr, d);
622 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628 emit_store_dst(jd, iptr, d);
631 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
632 /* sx.val.i = constant */
634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
636 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
637 M_IADD_IMM(s1, -iptr->sx.val.i, d);
639 ICONST(REG_ITMP2, iptr->sx.val.i);
640 M_ISUB(s1, REG_ITMP2, d);
642 emit_store_dst(jd, iptr, d);
645 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
651 emit_store_dst(jd, iptr, d);
654 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
655 /* sx.val.l = constant */
657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
659 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
660 M_LADD_IMM(s1, -iptr->sx.val.l, d);
662 LCONST(REG_ITMP2, iptr->sx.val.l);
663 M_LSUB(s1, REG_ITMP2, d);
665 emit_store_dst(jd, iptr, d);
668 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 emit_store_dst(jd, iptr, d);
680 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
681 /* sx.val.i = constant */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685 ICONST(REG_ITMP2, iptr->sx.val.i);
686 M_IMUL(s1, REG_ITMP2);
690 emit_store_dst(jd, iptr, d);
693 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
706 /* sx.val.l = constant */
708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710 LCONST(REG_ITMP2, iptr->sx.val.l);
711 M_LMUL(s1, REG_ITMP2);
715 emit_store_dst(jd, iptr, d);
718 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
722 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
723 emit_arithmetic_check(cd, iptr, s2);
728 emit_store_dst(jd, iptr, d);
731 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736 emit_arithmetic_check(cd, iptr, s2);
741 emit_store_dst(jd, iptr, d);
744 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
747 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
748 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
749 emit_arithmetic_check(cd, iptr, s2);
754 emit_store_dst(jd, iptr, d);
757 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
760 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
761 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
762 emit_arithmetic_check(cd, iptr, s2);
767 emit_store_dst(jd, iptr, d);
770 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
771 case ICMD_LDIVPOW2: /* val.i = constant */
773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
775 M_LSRA_IMM(s1, 63, REG_ITMP2);
776 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
777 M_LADD(s1, REG_ITMP2, REG_ITMP2);
778 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
779 emit_store_dst(jd, iptr, d);
782 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
783 /* sx.val.i = constant */
785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
786 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
788 M_MOV(s1, REG_ITMP1);
791 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
792 M_AND_IMM(s1, iptr->sx.val.i, d);
795 M_ISUB(REG_ZERO, s1, d);
796 M_AND_IMM(d, iptr->sx.val.i, d);
799 ICONST(REG_ITMP2, iptr->sx.val.i);
800 M_AND(s1, REG_ITMP2, d);
803 M_ISUB(REG_ZERO, s1, d);
804 M_AND(d, REG_ITMP2, d);
806 M_ISUB(REG_ZERO, d, d);
807 emit_store_dst(jd, iptr, d);
810 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
811 /* sx.val.l = constant */
813 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
814 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
816 M_MOV(s1, REG_ITMP1);
819 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
820 M_AND_IMM(s1, iptr->sx.val.l, d);
823 M_LSUB(REG_ZERO, s1, d);
824 M_AND_IMM(d, iptr->sx.val.l, d);
827 LCONST(REG_ITMP2, iptr->sx.val.l);
828 M_AND(s1, REG_ITMP2, d);
831 M_LSUB(REG_ZERO, s1, d);
832 M_AND(d, REG_ITMP2, d);
834 M_LSUB(REG_ZERO, d, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
844 emit_store_dst(jd, iptr, d);
847 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
848 /* sx.val.i = constant */
850 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 M_ISLL_IMM(s1, iptr->sx.val.i, d);
853 emit_store_dst(jd, iptr, d);
856 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
860 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
862 emit_store_dst(jd, iptr, d);
865 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
866 /* sx.val.i = constant */
868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870 M_ISRA_IMM(s1, iptr->sx.val.i, d);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
884 /* sx.val.i = constant */
886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
888 M_ISRL_IMM(s1, iptr->sx.val.i, d);
889 emit_store_dst(jd, iptr, d);
892 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
902 /* sx.val.i = constant */
904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
906 M_LSLL_IMM(s1, iptr->sx.val.i, d);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
913 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
914 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
916 emit_store_dst(jd, iptr, d);
919 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
920 /* sx.val.i = constant */
922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
924 M_LSRA_IMM(s1, iptr->sx.val.i, d);
925 emit_store_dst(jd, iptr, d);
928 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
931 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
932 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
934 emit_store_dst(jd, iptr, d);
937 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
938 /* sx.val.i = constant */
940 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
942 M_LSRL_IMM(s1, iptr->sx.val.i, d);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
950 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953 emit_store_dst(jd, iptr, d);
956 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
957 /* sx.val.i = constant */
959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
960 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
961 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
962 M_AND_IMM(s1, iptr->sx.val.i, d);
964 ICONST(REG_ITMP2, iptr->sx.val.i);
965 M_AND(s1, REG_ITMP2, d);
967 emit_store_dst(jd, iptr, d);
970 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
971 /* sx.val.l = constant */
973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
976 M_AND_IMM(s1, iptr->sx.val.l, d);
978 LCONST(REG_ITMP2, iptr->sx.val.l);
979 M_AND(s1, REG_ITMP2, d);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
988 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
989 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
991 emit_store_dst(jd, iptr, d);
994 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
995 /* sx.val.i = constant */
997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
998 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
999 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1000 M_OR_IMM(s1, iptr->sx.val.i, d);
1002 ICONST(REG_ITMP2, iptr->sx.val.i);
1003 M_OR(s1, REG_ITMP2, d);
1005 emit_store_dst(jd, iptr, d);
1008 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1009 /* sx.val.l = constant */
1011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1014 M_OR_IMM(s1, iptr->sx.val.l, d);
1016 LCONST(REG_ITMP2, iptr->sx.val.l);
1017 M_OR(s1, REG_ITMP2, d);
1019 emit_store_dst(jd, iptr, d);
1022 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1027 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1033 /* sx.val.i = constant */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1037 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1038 M_XOR_IMM(s1, iptr->sx.val.i, d);
1040 ICONST(REG_ITMP2, iptr->sx.val.i);
1041 M_XOR(s1, REG_ITMP2, d);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1047 /* sx.val.l = constant */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1051 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1052 M_XOR_IMM(s1, iptr->sx.val.l, d);
1054 LCONST(REG_ITMP2, iptr->sx.val.l);
1055 M_XOR(s1, REG_ITMP2, d);
1057 emit_store_dst(jd, iptr, d);
1061 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1065 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066 M_CMPLT(s1, s2, REG_ITMP3);
1067 M_CMPLT(s2, s1, REG_ITMP1);
1068 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1069 emit_store_dst(jd, iptr, d);
1073 /* floating operations ************************************************/
1075 case ICMD_FNEG: /* ..., value ==> ..., - value */
1077 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1078 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1080 emit_store_dst(jd, iptr, d);
1083 case ICMD_DNEG: /* ..., value ==> ..., - value */
1085 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1086 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_FADD: /* ..., 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_DADD: /* ..., 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);
1109 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1111 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1113 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1115 emit_store_dst(jd, iptr, d);
1118 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1120 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1121 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1122 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1124 emit_store_dst(jd, iptr, d);
1127 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1129 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1130 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1131 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1147 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1148 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1149 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1151 emit_store_dst(jd, iptr, d);
1154 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1156 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1157 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1158 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1160 emit_store_dst(jd, iptr, d);
1164 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1168 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1169 M_FDIV(s1,s2, REG_FTMP3);
1170 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1171 M_CVTLF(REG_FTMP3, REG_FTMP3);
1172 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1173 M_FSUB(s1, REG_FTMP3, d);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1179 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1180 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1181 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1182 M_DDIV(s1,s2, REG_FTMP3);
1183 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1184 M_CVTLD(REG_FTMP3, REG_FTMP3);
1185 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1186 M_DSUB(s1, REG_FTMP3, d);
1187 emit_store_dst(jd, iptr, d);
1191 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1193 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1194 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1197 emit_store_dst(jd, iptr, d);
1200 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1203 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1206 emit_store_dst(jd, iptr, d);
1210 /* XXX these do not work correctly */
1212 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1214 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1215 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1216 M_TRUNCFI(s1, REG_FTMP1);
1217 M_MOVDI(REG_FTMP1, d);
1219 emit_store_dst(jd, iptr, d);
1222 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1224 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1225 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1226 M_TRUNCDI(s1, REG_FTMP1);
1227 M_MOVDI(REG_FTMP1, d);
1229 emit_store_dst(jd, iptr, d);
1232 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1234 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1236 M_TRUNCFL(s1, REG_FTMP1);
1237 M_MOVDL(REG_FTMP1, d);
1239 emit_store_dst(jd, iptr, d);
1242 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1244 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1246 M_TRUNCDL(s1, REG_FTMP1);
1247 M_MOVDL(REG_FTMP1, d);
1249 emit_store_dst(jd, iptr, d);
1253 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1255 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1256 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1258 emit_store_dst(jd, iptr, d);
1261 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1263 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1264 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1271 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1272 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1273 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1276 M_LADD_IMM(REG_ZERO, 1, d);
1280 M_LSUB_IMM(REG_ZERO, 1, d);
1281 M_CMOVT(REG_ZERO, d);
1282 emit_store_dst(jd, iptr, d);
1285 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1287 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1288 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1289 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1292 M_LADD_IMM(REG_ZERO, 1, d);
1296 M_LSUB_IMM(REG_ZERO, 1, d);
1297 M_CMOVT(REG_ZERO, d);
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1303 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1304 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1305 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1308 M_LSUB_IMM(REG_ZERO, 1, d);
1312 M_LADD_IMM(REG_ZERO, 1, d);
1313 M_CMOVT(REG_ZERO, d);
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1319 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1320 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1321 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1324 M_LSUB_IMM(REG_ZERO, 1, d);
1328 M_LADD_IMM(REG_ZERO, 1, d);
1329 M_CMOVT(REG_ZERO, d);
1330 emit_store_dst(jd, iptr, d);
1334 /* memory operations **************************************************/
1336 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1340 emit_nullpointer_check(cd, iptr, s1);
1341 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1348 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1349 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1350 emit_array_checks(cd, iptr, s1, s2);
1351 M_AADD(s2, s1, REG_ITMP3);
1352 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1353 emit_store_dst(jd, iptr, d);
1356 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1358 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1359 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1360 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1361 emit_array_checks(cd, iptr, s1, s2);
1362 M_AADD(s2, s1, REG_ITMP3);
1363 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1364 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1365 emit_store_dst(jd, iptr, d);
1368 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1370 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1371 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1373 emit_array_checks(cd, iptr, s1, s2);
1374 M_AADD(s2, s1, REG_ITMP3);
1375 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1376 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1377 emit_store_dst(jd, iptr, d);
1380 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1383 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1384 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1385 emit_array_checks(cd, iptr, s1, s2);
1386 M_ASLL_IMM(s2, 2, REG_ITMP3);
1387 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1388 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1389 emit_store_dst(jd, iptr, d);
1392 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1395 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1396 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1397 emit_array_checks(cd, iptr, s1, s2);
1398 M_ASLL_IMM(s2, 3, REG_ITMP3);
1399 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1400 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1401 emit_store_dst(jd, iptr, d);
1404 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1407 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1408 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1409 emit_array_checks(cd, iptr, s1, s2);
1410 M_ASLL_IMM(s2, 2, REG_ITMP3);
1411 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1412 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1419 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1420 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1421 emit_array_checks(cd, iptr, s1, s2);
1422 M_ASLL_IMM(s2, 3, REG_ITMP3);
1423 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1424 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1432 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1433 emit_array_checks(cd, iptr, s1, s2);
1434 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1435 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1436 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1437 emit_store_dst(jd, iptr, d);
1441 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1444 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1445 emit_array_checks(cd, iptr, s1, s2);
1446 M_AADD(s2, s1, REG_ITMP1);
1447 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1448 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1451 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1452 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1454 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1455 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1456 emit_array_checks(cd, iptr, s1, s2);
1457 M_AADD(s2, s1, REG_ITMP1);
1458 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1459 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1460 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1463 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467 emit_array_checks(cd, iptr, s1, s2);
1468 M_ASLL_IMM(s2, 2, REG_ITMP2);
1469 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1470 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1471 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1474 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1476 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1478 emit_array_checks(cd, iptr, s1, s2);
1479 M_ASLL_IMM(s2, 3, REG_ITMP2);
1480 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1481 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1482 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1485 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1487 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1488 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1489 emit_array_checks(cd, iptr, s1, s2);
1490 M_ASLL_IMM(s2, 2, REG_ITMP2);
1491 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1492 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1493 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1496 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1499 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1500 emit_array_checks(cd, iptr, s1, s2);
1501 M_ASLL_IMM(s2, 3, REG_ITMP2);
1502 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1503 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1504 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1508 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512 emit_array_checks(cd, iptr, s1, s2);
1513 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1517 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1518 M_ALD(REG_ITMP3, REG_PV, disp);
1519 M_JSR(REG_RA, REG_ITMP3);
1522 /* M_BEQZ(REG_RESULT, 0); */
1523 /* codegen_add_arraystoreexception_ref(cd); */
1525 emit_arraystore_check(cd, iptr, REG_RESULT);
1527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1529 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1530 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1531 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1532 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1536 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1539 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1540 emit_array_checks(cd, iptr, s1, s2);
1541 M_AADD(s2, s1, REG_ITMP1);
1542 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1545 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1546 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 emit_array_checks(cd, iptr, s1, s2);
1551 M_AADD(s2, s1, REG_ITMP1);
1552 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1553 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1556 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1559 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1560 emit_array_checks(cd, iptr, s1, s2);
1561 M_ASLL_IMM(s2, 2, REG_ITMP2);
1562 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1563 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1566 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1570 emit_array_checks(cd, iptr, s1, s2);
1571 M_ASLL_IMM(s2, 3, REG_ITMP2);
1572 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1573 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1576 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1580 emit_array_checks(cd, iptr, s1, s2);
1581 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1582 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1583 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1587 case ICMD_GETSTATIC: /* ... ==> ..., value */
1589 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1590 uf = iptr->sx.s23.s3.uf;
1591 fieldtype = uf->fieldref->parseddesc.fd->type;
1592 disp = dseg_add_unique_address(cd, uf);
1594 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1597 fi = iptr->sx.s23.s3.fmiref->p.field;
1598 fieldtype = fi->type;
1599 disp = dseg_add_address(cd, &(fi->value));
1601 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1602 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1605 M_ALD(REG_ITMP1, REG_PV, disp);
1607 switch (fieldtype) {
1609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1610 M_ILD_INTERN(d, REG_ITMP1, 0);
1613 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1614 M_LLD_INTERN(d, REG_ITMP1, 0);
1617 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1618 M_ALD_INTERN(d, REG_ITMP1, 0);
1621 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1622 M_FLD_INTERN(d, REG_ITMP1, 0);
1625 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1626 M_DLD_INTERN(d, REG_ITMP1, 0);
1629 emit_store_dst(jd, iptr, d);
1632 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1634 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1635 uf = iptr->sx.s23.s3.uf;
1636 fieldtype = uf->fieldref->parseddesc.fd->type;
1637 disp = dseg_add_unique_address(cd, uf);
1639 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1642 fi = iptr->sx.s23.s3.fmiref->p.field;
1643 fieldtype = fi->type;
1644 disp = dseg_add_address(cd, &(fi->value));
1646 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1647 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1650 M_ALD(REG_ITMP1, REG_PV, disp);
1652 switch (fieldtype) {
1654 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1655 M_IST_INTERN(s1, REG_ITMP1, 0);
1658 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1659 M_LST_INTERN(s1, REG_ITMP1, 0);
1662 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1663 M_AST_INTERN(s1, REG_ITMP1, 0);
1666 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1667 M_FST_INTERN(s1, REG_ITMP1, 0);
1670 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1671 M_DST_INTERN(s1, REG_ITMP1, 0);
1676 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1677 /* val = value (in current instruction) */
1678 /* following NOP) */
1680 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1681 uf = iptr->sx.s23.s3.uf;
1682 fieldtype = uf->fieldref->parseddesc.fd->type;
1683 disp = dseg_add_unique_address(cd, uf);
1685 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1688 fi = iptr->sx.s23.s3.fmiref->p.field;
1689 fieldtype = fi->type;
1690 disp = dseg_add_address(cd, &(fi->value));
1692 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1693 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1696 M_ALD(REG_ITMP1, REG_PV, disp);
1698 switch (fieldtype) {
1700 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1703 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1706 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1709 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1712 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1718 case ICMD_GETFIELD: /* ... ==> ..., value */
1720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721 emit_nullpointer_check(cd, iptr, s1);
1723 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1724 uf = iptr->sx.s23.s3.uf;
1725 fieldtype = uf->fieldref->parseddesc.fd->type;
1728 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1731 fi = iptr->sx.s23.s3.fmiref->p.field;
1732 fieldtype = fi->type;
1736 switch (fieldtype) {
1738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1750 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1754 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1758 emit_store_dst(jd, iptr, d);
1761 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1764 emit_nullpointer_check(cd, iptr, s1);
1766 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1767 uf = iptr->sx.s23.s3.uf;
1768 fieldtype = uf->fieldref->parseddesc.fd->type;
1772 fi = iptr->sx.s23.s3.fmiref->p.field;
1773 fieldtype = fi->type;
1777 if (IS_INT_LNG_TYPE(fieldtype))
1778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1780 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1782 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1783 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1785 switch (fieldtype) {
1787 M_IST(s2, s1, disp);
1790 M_LST(s2, s1, disp);
1793 M_AST(s2, s1, disp);
1796 M_FST(s2, s1, disp);
1799 M_DST(s2, s1, disp);
1804 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1807 emit_nullpointer_check(cd, iptr, s1);
1809 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1810 unresolved_field *uf = iptr->sx.s23.s3.uf;
1812 fieldtype = uf->fieldref->parseddesc.fd->type;
1815 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1818 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1819 fieldtype = fi->type;
1823 switch (fieldtype) {
1825 M_IST(REG_ZERO, s1, disp);
1828 M_LST(REG_ZERO, s1, disp);
1831 M_AST(REG_ZERO, s1, disp);
1834 M_FST(REG_ZERO, s1, disp);
1837 M_DST(REG_ZERO, s1, disp);
1843 /* branch operations **************************************************/
1845 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848 M_INTMOVE(s1, REG_ITMP1_XPTR);
1850 #ifdef ENABLE_VERIFIER
1851 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1852 uc = iptr->sx.s23.s2.uc;
1854 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1856 #endif /* ENABLE_VERIFIER */
1858 disp = dseg_add_functionptr(cd, asm_handle_exception);
1859 M_ALD(REG_ITMP2, REG_PV, disp);
1860 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
1862 M_NOP; /* nop ensures that XPC is less than the end */
1863 /* of basic block */
1867 case ICMD_GOTO: /* ... ==> ... */
1868 case ICMD_RET: /* ... ==> ... */
1871 codegen_add_branch_ref(cd, iptr->dst.block);
1876 case ICMD_JSR: /* ... ==> ... */
1879 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
1884 case ICMD_IFNULL: /* ..., value ==> ... */
1886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1888 codegen_add_branch_ref(cd, iptr->dst.block);
1892 case ICMD_IFNONNULL: /* ..., value ==> ... */
1894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1896 codegen_add_branch_ref(cd, iptr->dst.block);
1900 case ICMD_IFEQ: /* ..., value ==> ... */
1902 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1903 if (iptr->sx.val.i == 0) {
1906 ICONST(REG_ITMP2, iptr->sx.val.i);
1907 M_BEQ(s1, REG_ITMP2, 0);
1909 codegen_add_branch_ref(cd, iptr->dst.block);
1913 case ICMD_IFLT: /* ..., value ==> ... */
1915 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1916 if (iptr->sx.val.i == 0) {
1919 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
1920 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1922 ICONST(REG_ITMP2, iptr->sx.val.i);
1923 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1925 M_BNEZ(REG_ITMP1, 0);
1927 codegen_add_branch_ref(cd, iptr->dst.block);
1931 case ICMD_IFLE: /* ..., value ==> ... */
1933 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1934 if (iptr->sx.val.i == 0) {
1938 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
1939 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
1940 M_BNEZ(REG_ITMP1, 0);
1943 ICONST(REG_ITMP2, iptr->sx.val.i);
1944 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
1945 M_BEQZ(REG_ITMP1, 0);
1948 codegen_add_branch_ref(cd, iptr->dst.block);
1952 case ICMD_IFNE: /* ..., value ==> ... */
1954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1955 if (iptr->sx.val.i == 0) {
1959 ICONST(REG_ITMP2, iptr->sx.val.i);
1960 M_BNE(s1, REG_ITMP2, 0);
1962 codegen_add_branch_ref(cd, iptr->dst.block);
1966 case ICMD_IFGT: /* ..., value ==> ... */
1968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1969 if (iptr->sx.val.i == 0) {
1973 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
1974 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
1975 M_BEQZ(REG_ITMP1, 0);
1978 ICONST(REG_ITMP2, iptr->sx.val.i);
1979 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
1980 M_BNEZ(REG_ITMP1, 0);
1983 codegen_add_branch_ref(cd, iptr->dst.block);
1987 case ICMD_IFGE: /* ..., value ==> ... */
1989 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1990 if (iptr->sx.val.i == 0) {
1994 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
1995 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1998 ICONST(REG_ITMP2, iptr->sx.val.i);
1999 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2001 M_BEQZ(REG_ITMP1, 0);
2003 codegen_add_branch_ref(cd, iptr->dst.block);
2007 case ICMD_IF_LEQ: /* ..., value ==> ... */
2009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2010 if (iptr->sx.val.l == 0) {
2014 LCONST(REG_ITMP2, iptr->sx.val.l);
2015 M_BEQ(s1, REG_ITMP2, 0);
2017 codegen_add_branch_ref(cd, iptr->dst.block);
2021 case ICMD_IF_LLT: /* ..., value ==> ... */
2023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2024 if (iptr->sx.val.l == 0) {
2028 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2029 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2032 LCONST(REG_ITMP2, iptr->sx.val.l);
2033 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2035 M_BNEZ(REG_ITMP1, 0);
2037 codegen_add_branch_ref(cd, iptr->dst.block);
2041 case ICMD_IF_LLE: /* ..., value ==> ... */
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2044 if (iptr->sx.val.l == 0) {
2048 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2049 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2050 M_BNEZ(REG_ITMP1, 0);
2053 LCONST(REG_ITMP2, iptr->sx.val.l);
2054 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2055 M_BEQZ(REG_ITMP1, 0);
2058 codegen_add_branch_ref(cd, iptr->dst.block);
2062 case ICMD_IF_LNE: /* ..., value ==> ... */
2064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2065 if (iptr->sx.val.l == 0) {
2069 LCONST(REG_ITMP2, iptr->sx.val.l);
2070 M_BNE(s1, REG_ITMP2, 0);
2072 codegen_add_branch_ref(cd, iptr->dst.block);
2076 case ICMD_IF_LGT: /* ..., value ==> ... */
2078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2079 if (iptr->sx.val.l == 0) {
2083 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2084 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2085 M_BEQZ(REG_ITMP1, 0);
2088 LCONST(REG_ITMP2, iptr->sx.val.l);
2089 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2090 M_BNEZ(REG_ITMP1, 0);
2093 codegen_add_branch_ref(cd, iptr->dst.block);
2097 case ICMD_IF_LGE: /* ..., value ==> ... */
2099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2100 if (iptr->sx.val.l == 0) {
2104 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2105 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2108 LCONST(REG_ITMP2, iptr->sx.val.l);
2109 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2111 M_BEQZ(REG_ITMP1, 0);
2113 codegen_add_branch_ref(cd, iptr->dst.block);
2117 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2118 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2119 case ICMD_IF_ACMPEQ:
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2124 codegen_add_branch_ref(cd, iptr->dst.block);
2128 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2129 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2130 case ICMD_IF_ACMPNE:
2132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2133 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2135 codegen_add_branch_ref(cd, iptr->dst.block);
2139 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2140 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2143 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2144 M_CMPLT(s1, s2, REG_ITMP1);
2145 M_BNEZ(REG_ITMP1, 0);
2146 codegen_add_branch_ref(cd, iptr->dst.block);
2150 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2151 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2155 M_CMPGT(s1, s2, REG_ITMP1);
2156 M_BNEZ(REG_ITMP1, 0);
2157 codegen_add_branch_ref(cd, iptr->dst.block);
2161 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2162 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2166 M_CMPGT(s1, s2, REG_ITMP1);
2167 M_BEQZ(REG_ITMP1, 0);
2168 codegen_add_branch_ref(cd, iptr->dst.block);
2172 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2173 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2176 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2177 M_CMPLT(s1, s2, REG_ITMP1);
2178 M_BEQZ(REG_ITMP1, 0);
2179 codegen_add_branch_ref(cd, iptr->dst.block);
2184 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2187 REPLACEMENT_POINT_RETURN(cd, iptr);
2188 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2189 M_INTMOVE(s1, REG_RESULT);
2190 goto nowperformreturn;
2192 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2194 REPLACEMENT_POINT_RETURN(cd, iptr);
2195 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2196 M_INTMOVE(s1, REG_RESULT);
2198 #ifdef ENABLE_VERIFIER
2199 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2200 uc = iptr->sx.s23.s2.uc;
2202 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2204 #endif /* ENABLE_VERIFIER */
2205 goto nowperformreturn;
2207 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2209 REPLACEMENT_POINT_RETURN(cd, iptr);
2210 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2211 M_FLTMOVE(s1, REG_FRESULT);
2212 goto nowperformreturn;
2214 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2216 REPLACEMENT_POINT_RETURN(cd, iptr);
2217 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2218 M_DBLMOVE(s1, REG_FRESULT);
2219 goto nowperformreturn;
2221 case ICMD_RETURN: /* ... ==> ... */
2223 REPLACEMENT_POINT_RETURN(cd, iptr);
2229 p = cd->stackframesize;
2231 #if !defined(NDEBUG)
2232 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2233 emit_verbosecall_exit(jd);
2236 #if defined(ENABLE_THREADS)
2237 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2238 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2239 M_ALD(REG_ITMP3, REG_PV, disp);
2241 /* we need to save the proper return value */
2243 switch (iptr->opc) {
2247 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2248 M_JSR(REG_RA, REG_ITMP3);
2249 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2253 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2254 M_JSR(REG_RA, REG_ITMP3);
2255 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2258 M_JSR(REG_RA, REG_ITMP3);
2259 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2263 /* and now restore the proper return value */
2265 switch (iptr->opc) {
2269 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2273 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2279 /* restore return address */
2281 if (!jd->isleafmethod) {
2282 p--; M_ALD(REG_RA, REG_SP, p * 8);
2285 /* restore saved registers */
2287 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2288 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2290 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2291 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2294 /* deallocate stack and return */
2296 if (cd->stackframesize) {
2299 disp = cd->stackframesize * 8;
2300 lo = (short) (disp);
2301 hi = (short) (((disp) - lo) >> 16);
2305 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2307 M_LUI(REG_ITMP3,hi);
2308 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2310 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2323 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2326 branch_target_t *table;
2328 table = iptr->dst.table;
2330 l = iptr->sx.s23.s2.tablelow;
2331 i = iptr->sx.s23.s3.tablehigh;
2333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2335 {M_INTMOVE(s1, REG_ITMP1);}
2336 else if (l <= 32768) {
2337 M_IADD_IMM(s1, -l, REG_ITMP1);
2340 ICONST(REG_ITMP2, l);
2341 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2344 /* number of targets */
2349 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2350 M_BEQZ(REG_ITMP2, 0);
2351 codegen_add_branch_ref(cd, table[0].block); /* default target */
2352 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2354 /* build jump table top down and use address of lowest entry */
2359 dseg_add_target(cd, table->block);
2364 /* length of dataseg after last dseg_add_target is used by load */
2366 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2367 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2374 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2377 lookup_target_t *lookup;
2379 lookup = iptr->dst.lookup;
2381 i = iptr->sx.s23.s2.lookupcount;
2383 MCODECHECK((i<<2)+8);
2384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2387 ICONST(REG_ITMP2, lookup->value);
2388 M_BEQ(s1, REG_ITMP2, 0);
2389 codegen_add_branch_ref(cd, lookup->target.block);
2395 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2402 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2404 bte = iptr->sx.s23.s3.bte;
2408 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2410 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2411 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2412 case ICMD_INVOKEINTERFACE:
2414 REPLACEMENT_POINT_INVOKE(cd, iptr);
2416 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2418 um = iptr->sx.s23.s3.um;
2419 md = um->methodref->parseddesc.md;
2422 lm = iptr->sx.s23.s3.fmiref->p.method;
2424 md = lm->parseddesc;
2428 s3 = md->paramcount;
2430 MCODECHECK((s3 << 1) + 64);
2432 /* copy arguments to registers or stack location */
2434 for (s3 = s3 - 1; s3 >= 0; s3--) {
2435 var = VAR(iptr->sx.s23.s2.args[s3]);
2437 if (var->flags & PREALLOC)
2440 if (IS_INT_LNG_TYPE(var->type)) {
2441 if (!md->params[s3].inmemory) {
2442 s1 = rd->argintregs[md->params[s3].regoff];
2443 d = emit_load(jd, iptr, var, s1);
2447 d = emit_load(jd, iptr, var, REG_ITMP1);
2448 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2452 if (!md->params[s3].inmemory) {
2453 s1 = rd->argfltregs[md->params[s3].regoff];
2454 d = emit_load(jd, iptr, var, s1);
2455 if (IS_2_WORD_TYPE(var->type))
2461 d = emit_load(jd, iptr, var, REG_FTMP1);
2462 if (IS_2_WORD_TYPE(var->type))
2463 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2465 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2470 switch (iptr->opc) {
2472 disp = dseg_add_functionptr(cd, bte->fp);
2474 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2476 /* TWISTI: i actually don't know the reason for using
2477 REG_ITMP3 here instead of REG_PV. */
2481 case ICMD_INVOKESPECIAL:
2482 /* emit_nullpointer_check(cd, REG_A0); */
2486 M_LUI(REG_ITMP3, 0);
2487 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
2488 codegen_add_nullpointerexception_ref(cd);
2489 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
2495 case ICMD_INVOKESTATIC:
2497 disp = dseg_add_unique_address(cd, um);
2499 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
2503 disp = dseg_add_address(cd, lm->stubroutine);
2505 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2509 case ICMD_INVOKEVIRTUAL:
2510 emit_nullpointer_check(cd, iptr, REG_A0);
2513 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2518 s1 = OFFSET(vftbl_t, table[0]) +
2519 sizeof(methodptr) * lm->vftblindex;
2521 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2522 M_ALD(REG_PV, REG_METHODPTR, s1);
2526 case ICMD_INVOKEINTERFACE:
2527 emit_nullpointer_check(cd, iptr, REG_A0);
2530 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2536 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2537 sizeof(methodptr*) * lm->class->index;
2539 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2542 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2543 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2544 M_ALD(REG_PV, REG_METHODPTR, s2);
2549 /* generate the actual call */
2553 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2554 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2555 M_LDA(REG_PV, REG_RA, -disp);
2557 /* actually only used for ICMD_BUILTIN */
2559 emit_exception_check(cd, iptr);
2561 /* store return value */
2563 d = md->returntype.type;
2565 if (d != TYPE_VOID) {
2566 if (IS_INT_LNG_TYPE(d)) {
2567 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2568 M_INTMOVE(REG_RESULT, s1);
2571 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2572 if (IS_2_WORD_TYPE(d))
2573 M_DMOV(REG_FRESULT, s1);
2575 M_FMOV(REG_FRESULT, s1);
2577 emit_store_dst(jd, iptr, s1);
2582 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2583 /* val.a: (classinfo*) superclass */
2585 /* superclass is an interface:
2587 * OK if ((sub == NULL) ||
2588 * (sub->vftbl->interfacetablelength > super->index) &&
2589 * (sub->vftbl->interfacetable[-super->index] != NULL));
2591 * superclass is a class:
2593 * OK if ((sub == NULL) || (0
2594 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2595 * super->vftbl->diffvall));
2598 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2602 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2607 super = iptr->sx.s23.s3.c.cls;
2608 superindex = super->index;
2611 #if defined(ENABLE_THREADS)
2612 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2617 /* calculate interface checkcast code size */
2619 /* s2 = 3 + 2 + 1 + 2; */
2622 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2624 /* calculate class checkcast code size */
2626 /* s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */
2627 s3 = 2 + 1 + 4 + 1 + 7;
2629 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2631 /* if class is not resolved, check which code to call */
2633 if (super == NULL) {
2634 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
2637 cr = iptr->sx.s23.s3.c.ref;
2638 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2640 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2643 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2644 M_ILD(REG_ITMP2, REG_PV, disp);
2645 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2646 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2650 /* interface checkcast code */
2652 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2653 if (super == NULL) {
2654 cr = iptr->sx.s23.s3.c.ref;
2656 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2664 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2665 M_ILD(REG_ITMP3, REG_ITMP2,
2666 OFFSET(vftbl_t, interfacetablelength));
2667 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2668 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2670 M_ALD(REG_ITMP3, REG_ITMP2,
2671 OFFSET(vftbl_t, interfacetable[0]) -
2672 superindex * sizeof(methodptr*));
2673 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2675 if (super == NULL) {
2681 /* class checkcast code */
2683 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2684 if (super == NULL) {
2685 cr = iptr->sx.s23.s3.c.ref;
2686 disp = dseg_add_unique_address(cd, NULL);
2688 codegen_add_patch_ref(cd,
2689 PATCHER_checkcast_instanceof_class,
2693 disp = dseg_add_address(cd, super->vftbl);
2699 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2700 M_ALD(REG_ITMP3, REG_PV, disp);
2701 #if defined(ENABLE_THREADS)
2702 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2704 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2705 /* if (s1 != REG_ITMP1) { */
2706 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2707 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2708 /* #if defined(ENABLE_THREADS) */
2709 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2711 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2713 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2714 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2715 M_ALD(REG_ITMP3, REG_PV, disp);
2716 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2717 #if defined(ENABLE_THREADS)
2718 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2721 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2722 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
2725 d = codegen_reg_of_dst(jd, iptr, s1);
2728 s1 = emit_load_s1(jd, iptr, REG_A0);
2729 M_INTMOVE(s1, REG_A0);
2731 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2732 cr = iptr->sx.s23.s3.c.ref;
2733 disp = dseg_add_unique_address(cd, NULL);
2735 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2739 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2741 M_ALD(REG_A1, REG_PV, disp);
2742 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2743 M_ALD(REG_ITMP3, REG_PV, disp);
2744 M_JSR(REG_RA, REG_ITMP3);
2747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2748 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
2750 d = codegen_reg_of_dst(jd, iptr, s1);
2754 emit_store_dst(jd, iptr, d);
2757 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2758 /* val.a: (classinfo*) superclass */
2760 /* superclass is an interface:
2762 * return (sub != NULL) &&
2763 * (sub->vftbl->interfacetablelength > super->index) &&
2764 * (sub->vftbl->interfacetable[-super->index] != NULL);
2766 * superclass is a class:
2768 * return ((sub != NULL) && (0
2769 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2770 * super->vftbl->diffvall));
2777 super = iptr->sx.s23.s3.c.cls;
2779 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2784 super = iptr->sx.s23.s3.c.cls;
2785 superindex = super->index;
2788 #if defined(ENABLE_THREADS)
2789 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2795 M_MOV(s1, REG_ITMP1);
2799 /* calculate interface instanceof code size */
2803 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2805 /* calculate class instanceof code size */
2809 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2813 /* if class is not resolved, check which code to call */
2815 if (super == NULL) {
2816 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
2819 cr = iptr->sx.s23.s3.c.ref;
2820 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2822 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2825 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2826 M_ILD(REG_ITMP3, REG_PV, disp);
2827 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2828 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
2832 /* interface instanceof code */
2834 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2835 if (super == NULL) {
2836 cr = iptr->sx.s23.s3.c.ref;
2838 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2846 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2847 M_ILD(REG_ITMP3, REG_ITMP1,
2848 OFFSET(vftbl_t, interfacetablelength));
2849 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2850 M_BLEZ(REG_ITMP3, 3);
2852 M_ALD(REG_ITMP1, REG_ITMP1,
2853 OFFSET(vftbl_t, interfacetable[0]) -
2854 superindex * sizeof(methodptr*));
2855 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2857 if (super == NULL) {
2863 /* class instanceof code */
2865 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2866 if (super == NULL) {
2867 cr = iptr->sx.s23.s3.c.ref;
2868 disp = dseg_add_unique_address(cd, NULL);
2870 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2874 disp = dseg_add_address(cd, super->vftbl);
2880 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2881 M_ALD(REG_ITMP2, REG_PV, disp);
2882 #if defined(ENABLE_THREADS)
2883 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2885 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2886 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2887 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2888 #if defined(ENABLE_THREADS)
2889 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2891 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2892 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
2895 emit_store_dst(jd, iptr, d);
2899 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2901 /* check for negative sizes and copy sizes to stack if necessary */
2903 MCODECHECK((iptr->s1.argcount << 1) + 64);
2905 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2907 var = VAR(iptr->sx.s23.s2.args[s1]);
2909 /* copy SAVEDVAR sizes to stack */
2911 if (!(var->flags & PREALLOC)) {
2912 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2913 M_LST(s2, REG_SP, s1 * 8);
2917 /* a0 = dimension count */
2919 ICONST(REG_A0, iptr->s1.argcount);
2921 /* is patcher function set? */
2923 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2924 cr = iptr->sx.s23.s3.c.ref;
2925 disp = dseg_add_unique_address(cd, NULL);
2927 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2931 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2933 /* a1 = arraydescriptor */
2935 M_ALD(REG_A1, REG_PV, disp);
2937 /* a2 = pointer to dimensions = stack pointer */
2939 M_INTMOVE(REG_SP, REG_A2);
2941 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2942 M_ALD(REG_ITMP3, REG_PV, disp);
2943 M_JSR(REG_RA, REG_ITMP3);
2946 /* check for exception before result assignment */
2948 emit_exception_check(cd, iptr);
2950 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2951 M_INTMOVE(REG_RESULT, d);
2952 emit_store_dst(jd, iptr, d);
2956 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2961 } /* for instruction */
2963 MCODECHECK(64); /* XXX require smaller number? */
2965 /* At the end of a basic block we may have to append some nops,
2966 because the patcher stub calling code might be longer than the
2967 actual instruction. So codepatching does not change the
2968 following block unintentionally. */
2970 if (cd->mcodeptr < cd->lastmcodeptr) {
2971 while (cd->mcodeptr < cd->lastmcodeptr)
2975 } /* if (bptr -> flags >= BBREACHED) */
2976 } /* for basic block */
2978 dseg_createlinenumbertable(cd);
2980 /* generate exception and patcher stubs */
2982 emit_exception_stubs(jd);
2983 emit_patcher_stubs(jd);
2984 REPLACEMENT_EMIT_STUBS(jd);
2988 /* everything's ok */
2994 /* createcompilerstub **********************************************************
2996 Creates a stub routine which calls the compiler.
2998 *******************************************************************************/
3000 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3001 #define COMPILERSTUB_CODESIZE 4 * 4
3003 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3006 u1 *createcompilerstub(methodinfo *m)
3008 u1 *s; /* memory to hold the stub */
3014 s = CNEW(u1, COMPILERSTUB_SIZE);
3016 /* set data pointer and code pointer */
3019 s = s + COMPILERSTUB_DATASIZE;
3021 /* mark start of dump memory area */
3023 dumpsize = dump_size();
3025 cd = DNEW(codegendata);
3028 /* Store the codeinfo pointer in the same place as in the
3029 methodheader for compiled methods. */
3031 code = code_codeinfo_new(m);
3033 d[0] = (ptrint) asm_call_jit_compiler;
3035 d[2] = (ptrint) code;
3037 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3038 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3042 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3044 #if defined(ENABLE_STATISTICS)
3046 count_cstub_len += COMPILERSTUB_SIZE;
3049 /* release dump area */
3051 dump_release(dumpsize);
3057 /* createnativestub ************************************************************
3059 Creates a stub routine which calls a native method.
3061 *******************************************************************************/
3063 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3071 s4 i, j; /* count variables */
3074 s4 funcdisp; /* displacement of the function */
3076 /* get required compiler data */
3083 /* initialize variables */
3086 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3088 /* calculate stack frame size */
3090 cd->stackframesize =
3091 1 + /* return address */
3092 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3093 sizeof(localref_table) / SIZEOF_VOID_P +
3094 md->paramcount + /* for saving arguments over calls */
3095 1 + /* for saving return address */
3098 /* create method header */
3100 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3101 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3102 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3103 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3104 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3105 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3106 (void) dseg_addlinenumbertablesize(cd);
3107 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3109 /* generate stub code */
3111 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3112 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3114 #if !defined(NDEBUG)
3115 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3116 emit_verbosecall_enter(jd);
3119 /* get function address (this must happen before the stackframeinfo) */
3121 funcdisp = dseg_add_functionptr(cd, f);
3123 #if !defined(WITH_STATIC_CLASSPATH)
3125 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3128 /* save integer and float argument registers */
3130 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3131 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3132 M_LST(rd->argintregs[i], REG_SP, j * 8);
3137 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3138 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3139 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3144 /* prepare data structures for native function call */
3146 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3147 M_MOV(REG_PV, REG_A1);
3148 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3149 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3150 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3151 M_ALD(REG_ITMP3, REG_PV, disp);
3152 M_JSR(REG_RA, REG_ITMP3);
3153 M_NOP; /* XXX fill me! */
3155 /* restore integer and float argument registers */
3157 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3158 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3159 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3164 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3165 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3166 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3171 /* copy or spill arguments to new locations */
3173 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3174 t = md->paramtypes[i].type;
3176 if (IS_INT_LNG_TYPE(t)) {
3177 if (!md->params[i].inmemory) {
3178 s1 = rd->argintregs[md->params[i].regoff];
3180 if (!nmd->params[j].inmemory) {
3181 s2 = rd->argintregs[nmd->params[j].regoff];
3184 s2 = nmd->params[j].regoff;
3185 M_AST(s1, REG_SP, s2 * 8);
3189 s1 = md->params[i].regoff + cd->stackframesize;
3190 s2 = nmd->params[j].regoff;
3191 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3192 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3196 if (!md->params[i].inmemory) {
3197 s1 = rd->argfltregs[md->params[i].regoff];
3199 if (!nmd->params[j].inmemory) {
3200 s2 = rd->argfltregs[nmd->params[j].regoff];
3201 if (IS_2_WORD_TYPE(t))
3207 s2 = nmd->params[j].regoff;
3208 if (IS_2_WORD_TYPE(t))
3209 M_DST(s1, REG_SP, s2 * 8);
3211 M_FST(s1, REG_SP, s2 * 8);
3215 s1 = md->params[i].regoff + cd->stackframesize;
3216 s2 = nmd->params[j].regoff;
3217 if (IS_2_WORD_TYPE(t)) {
3218 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3219 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3221 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3222 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3228 /* put class into second argument register */
3230 if (m->flags & ACC_STATIC) {
3231 disp = dseg_add_address(cd, m->class);
3232 M_ALD(REG_A1, REG_PV, disp);
3235 /* put env into first argument register */
3237 disp = dseg_add_address(cd, _Jv_env);
3238 M_ALD(REG_A0, REG_PV, disp);
3240 /* do the native function call */
3242 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3243 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3244 M_NOP; /* delay slot */
3246 /* save return value */
3248 if (md->returntype.type != TYPE_VOID) {
3249 if (IS_INT_LNG_TYPE(md->returntype.type))
3250 M_LST(REG_RESULT, REG_SP, 0 * 8);
3252 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3255 #if !defined(NDEBUG)
3256 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3257 emit_verbosecall_exit(jd);
3260 /* remove native stackframe info */
3262 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3263 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3264 M_ALD(REG_ITMP3, REG_PV, disp);
3265 M_JSR(REG_RA, REG_ITMP3);
3266 M_NOP; /* XXX fill me! */
3267 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3269 /* restore return value */
3271 if (md->returntype.type != TYPE_VOID) {
3272 if (IS_INT_LNG_TYPE(md->returntype.type))
3273 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3275 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3278 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3280 /* check for exception */
3282 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3283 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3285 M_RET(REG_RA); /* return to caller */
3286 M_NOP; /* DELAY SLOT */
3288 /* handle exception */
3290 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3291 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3292 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3293 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3295 /* generate patcher stubs */
3297 emit_patcher_stubs(jd);
3301 return code->entrypoint;
3306 * These are local overrides for various environment variables in Emacs.
3307 * Please do not remove this and leave it at the end of the file, where
3308 * Emacs will automagically detect them.
3309 * ---------------------------------------------------------------------
3312 * indent-tabs-mode: t
3316 * vim:noexpandtab:sw=4:ts=4: