1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006 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
30 Changes: Christian Thalinger
34 Contains the codegenerator for an MIPS (R4000 or higher) processor.
35 This module generates MIPS machine code for a sequence of
36 intermediate code commands (ICMDs).
38 $Id: codegen.c 5619 2006-10-01 23:51:23Z edwin $
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
56 #include "native/native.h"
58 #if defined(ENABLE_THREADS)
59 # include "threads/native/lock.h"
62 #include "vm/builtin.h"
64 #include "vm/exceptions.h"
65 #include "vm/options.h"
66 #include "vm/stringlocal.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit-common.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
82 /* codegen *********************************************************************
84 Generates machine code.
86 *******************************************************************************/
88 bool codegen(jitdata *jd)
94 s4 len, s1, s2, s3, d, disp;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
106 rplpoint *replacementpoint;
110 /* get required compiler data */
121 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
123 /* space to save used callee saved registers */
125 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128 cd->stackframesize = rd->memuse + savedregs_num;
130 #if defined(ENABLE_THREADS)
131 /* space to save argument of monitor_enter */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED))
134 cd->stackframesize++;
137 /* keep stack 16-byte aligned */
139 if (cd->stackframesize & 1)
140 cd->stackframesize++;
142 /* create method header */
144 #if SIZEOF_VOID_P == 4
145 (void) dseg_addaddress(cd, code); /* Filler */
147 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
148 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
150 #if defined(ENABLE_THREADS)
151 /* IsSync contains the offset relative to the stack pointer for the
152 argument of monitor_exit used in the exception handler. Since the
153 offset could be zero and give a wrong meaning of the flag it is
157 if (checksync && (m->flags & ACC_SYNCHRONIZED))
158 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
161 (void) dseg_adds4(cd, 0); /* IsSync */
163 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
164 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
165 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
166 dseg_addlinenumbertablesize(cd);
167 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
169 /* create exception table */
171 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
172 dseg_addtarget(cd, ex->start);
173 dseg_addtarget(cd, ex->end);
174 dseg_addtarget(cd, ex->handler);
175 (void) dseg_addaddress(cd, ex->catchtype.any);
178 /* create stack frame (if necessary) */
180 if (cd->stackframesize)
181 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
183 /* save return address and used callee saved registers */
185 p = cd->stackframesize;
186 if (!jd->isleafmethod) {
187 p--; M_AST(REG_RA, REG_SP, p * 8);
189 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
190 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
192 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
193 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
196 /* take arguments out of register or stack frame */
200 for (p = 0, l = 0; p < md->paramcount; p++) {
201 t = md->paramtypes[p].type;
203 varindex = jd->local_map[l * 5 + t];
206 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
209 if (varindex == UNUSED)
214 s1 = md->params[p].regoff;
215 if (IS_INT_LNG_TYPE(t)) { /* integer args */
216 if (!md->params[p].inmemory) { /* register arguments */
217 s2 = rd->argintregs[s1];
218 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
219 M_INTMOVE(s2, var->vv.regoff);
220 } else { /* reg arg -> spilled */
221 M_LST(s2, REG_SP, var->vv.regoff * 8);
224 } else { /* stack arguments */
225 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
226 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
227 } else { /* stack arg -> spilled */
228 var->vv.regoff = cd->stackframesize + s1;
232 } else { /* floating args */
233 if (!md->params[p].inmemory) { /* register arguments */
234 s2 = rd->argfltregs[s1];
235 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
236 if (IS_2_WORD_TYPE(t))
237 M_DMOV(s2, var->vv.regoff);
239 M_FMOV(s2, var->vv.regoff);
240 } else { /* reg arg -> spilled */
241 if (IS_2_WORD_TYPE(t))
242 M_DST(s2, REG_SP, var->vv.regoff * 8);
244 M_FST(s2, REG_SP, var->vv.regoff * 8);
247 } else { /* stack arguments */
248 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
249 if (IS_2_WORD_TYPE(t))
250 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
252 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
253 } else /* stack-arg -> spilled */
254 var->vv.regoff = cd->stackframesize + s1;
259 /* call monitorenter function */
261 #if defined(ENABLE_THREADS)
262 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
263 /* stack offset for monitor argument */
267 # if !defined(NDEBUG)
268 if (opt_verbosecall) {
269 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
271 for (p = 0; p < INT_ARG_CNT; p++)
272 M_LST(rd->argintregs[p], REG_SP, p * 8);
274 for (p = 0; p < FLT_ARG_CNT; p++)
275 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
277 s1 += INT_ARG_CNT + FLT_ARG_CNT;
281 /* get correct lock object */
283 if (m->flags & ACC_STATIC) {
284 p = dseg_addaddress(cd, &m->class->object.header);
285 M_ALD(REG_A0, REG_PV, p);
289 codegen_add_nullpointerexception_ref(cd);
292 p = dseg_addaddress(cd, LOCK_monitor_enter);
293 M_ALD(REG_ITMP3, REG_PV, p);
294 M_JSR(REG_RA, REG_ITMP3);
295 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
297 # if !defined(NDEBUG)
298 if (opt_verbosecall) {
299 for (p = 0; p < INT_ARG_CNT; p++)
300 M_LLD(rd->argintregs[p], REG_SP, p * 8);
302 for (p = 0; p < FLT_ARG_CNT; p++)
303 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
306 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
313 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
314 emit_verbosecall_enter(jd);
319 /* end of header generation */
321 replacementpoint = jd->code->rplpoints;
323 /* walk through all basic blocks */
325 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
327 /* handle replacement points */
330 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
332 /* 8-byte align pc */
333 if ((ptrint) cd->mcodeptr & 4) {
337 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
340 assert(cd->lastmcodeptr <= cd->mcodeptr);
341 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
345 /* store relative start of block */
347 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
349 if (bptr->flags >= BBREACHED) {
351 /* branch resolving */
354 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
355 gen_resolvebranch(cd->mcodebase + bref->branchpos,
361 /* copy interface registers to their destination */
365 #if defined(ENABLE_LSRA)
369 src = bptr->invars[len];
370 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
371 /* d = reg_of_var(m, src, REG_ITMP1); */
372 if (!(src->flags & INMEMORY))
376 M_INTMOVE(REG_ITMP1, d);
377 emit_store(jd, NULL, src, d);
384 var = VAR(bptr->invars[len]);
385 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
386 d = codegen_reg_of_var(0, var, REG_ITMP1);
387 M_INTMOVE(REG_ITMP1, d);
388 emit_store(jd, NULL, var, d);
391 assert((var->flags & OUTVAR));
392 d = codegen_reg_of_var(0, var, REG_IFTMP);
395 #if defined(ENABLE_LSRA)
398 /* walk through all instructions */
403 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
404 if (iptr->line != currentline) {
405 dseg_addlinenumber(cd, iptr->line);
406 currentline = iptr->line;
409 MCODECHECK(64); /* an instruction usually needs < 64 words */
413 case ICMD_NOP: /* ... ==> ... */
416 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
420 codegen_add_nullpointerexception_ref(cd);
424 /* constant operations ************************************************/
426 case ICMD_ICONST: /* ... ==> ..., constant */
428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
429 ICONST(d, iptr->sx.val.i);
430 emit_store_dst(jd, iptr, d);
433 case ICMD_LCONST: /* ... ==> ..., constant */
435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
436 LCONST(d, iptr->sx.val.l);
437 emit_store_dst(jd, iptr, d);
440 case ICMD_FCONST: /* ... ==> ..., constant */
442 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
443 disp = dseg_addfloat(cd, iptr->sx.val.f);
444 M_FLD(d, REG_PV, disp);
445 emit_store_dst(jd, iptr, d);
448 case ICMD_DCONST: /* ... ==> ..., constant */
450 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
451 disp = dseg_adddouble(cd, iptr->sx.val.d);
452 M_DLD(d, REG_PV, disp);
453 emit_store_dst(jd, iptr, d);
456 case ICMD_ACONST: /* ... ==> ..., constant */
458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
460 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
461 disp = dseg_addaddress(cd, NULL);
463 codegen_addpatchref(cd, PATCHER_aconst,
467 if (opt_showdisassemble) {
471 M_ALD(d, REG_PV, disp);
474 if (iptr->sx.val.anyptr == NULL) {
475 M_INTMOVE(REG_ZERO, d);
477 disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
478 M_ALD(d, REG_PV, disp);
481 emit_store_dst(jd, iptr, d);
485 /* load/store/copy/move operations ************************************/
487 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
488 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
489 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
490 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
491 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
492 case ICMD_ISTORE: /* ..., value ==> ... */
493 case ICMD_LSTORE: /* ..., value ==> ... */
494 case ICMD_ASTORE: /* ..., value ==> ... */
495 case ICMD_FSTORE: /* ..., value ==> ... */
496 case ICMD_DSTORE: /* ..., value ==> ... */
501 M_COPY(iptr->s1.varindex, iptr->dst.varindex);
505 /* pop/dup/swap operations ********************************************/
507 /* attention: double and longs are only one entry in CACAO ICMDs */
509 case ICMD_POP: /* ..., value ==> ... */
510 case ICMD_POP2: /* ..., value, value ==> ... */
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);
584 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
585 /* sx.val.i = constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
590 M_IADD_IMM(s1, iptr->sx.val.i, d);
592 ICONST(REG_ITMP2, iptr->sx.val.i);
593 M_IADD(s1, REG_ITMP2, d);
595 emit_store_dst(jd, iptr, d);
598 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
604 emit_store_dst(jd, iptr, d);
607 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
608 /* sx.val.l = constant */
610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
612 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
613 M_LADD_IMM(s1, iptr->sx.val.l, d);
615 LCONST(REG_ITMP2, iptr->sx.val.l);
616 M_LADD(s1, REG_ITMP2, d);
618 emit_store_dst(jd, iptr, d);
621 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
623 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
624 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 emit_store_dst(jd, iptr, d);
630 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
631 /* sx.val.i = constant */
633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
635 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
636 M_IADD_IMM(s1, -iptr->sx.val.i, d);
638 ICONST(REG_ITMP2, iptr->sx.val.i);
639 M_ISUB(s1, REG_ITMP2, d);
641 emit_store_dst(jd, iptr, d);
644 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 emit_store_dst(jd, iptr, d);
653 case ICMD_LSUBCONST: /* ..., 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 >= -32767) && (iptr->sx.val.l <= 32768)) {
659 M_LADD_IMM(s1, -iptr->sx.val.l, d);
661 LCONST(REG_ITMP2, iptr->sx.val.l);
662 M_LSUB(s1, REG_ITMP2, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
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);
676 emit_store_dst(jd, iptr, d);
679 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
680 /* sx.val.i = constant */
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 ICONST(REG_ITMP2, iptr->sx.val.i);
685 M_IMUL(s1, REG_ITMP2);
689 emit_store_dst(jd, iptr, d);
692 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
695 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
696 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
701 emit_store_dst(jd, iptr, d);
704 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
705 /* sx.val.l = constant */
707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709 LCONST(REG_ITMP2, iptr->sx.val.l);
710 M_LMUL(s1, REG_ITMP2);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
727 emit_store_dst(jd, iptr, d);
730 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
732 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
733 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
740 emit_store_dst(jd, iptr, d);
743 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
746 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
747 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
753 emit_store_dst(jd, iptr, d);
756 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
760 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766 emit_store_dst(jd, iptr, d);
769 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
770 case ICMD_LDIVPOW2: /* val.i = constant */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774 M_LSRA_IMM(s1, 63, REG_ITMP2);
775 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
776 M_LADD(s1, REG_ITMP2, REG_ITMP2);
777 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
778 emit_store_dst(jd, iptr, d);
781 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
782 /* sx.val.i = constant */
784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
787 M_MOV(s1, REG_ITMP1);
790 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
791 M_AND_IMM(s1, iptr->sx.val.i, d);
794 M_ISUB(REG_ZERO, s1, d);
795 M_AND_IMM(d, iptr->sx.val.i, d);
798 ICONST(REG_ITMP2, iptr->sx.val.i);
799 M_AND(s1, REG_ITMP2, d);
802 M_ISUB(REG_ZERO, s1, d);
803 M_AND(d, REG_ITMP2, d);
805 M_ISUB(REG_ZERO, d, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
810 /* sx.val.l = constant */
812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
815 M_MOV(s1, REG_ITMP1);
818 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
819 M_AND_IMM(s1, iptr->sx.val.l, d);
822 M_LSUB(REG_ZERO, s1, d);
823 M_AND_IMM(d, iptr->sx.val.l, d);
826 LCONST(REG_ITMP2, iptr->sx.val.l);
827 M_AND(s1, REG_ITMP2, d);
830 M_LSUB(REG_ZERO, s1, d);
831 M_AND(d, REG_ITMP2, d);
833 M_LSUB(REG_ZERO, d, d);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 emit_store_dst(jd, iptr, d);
846 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
847 /* sx.val.i = constant */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 M_ISLL_IMM(s1, iptr->sx.val.i, d);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
865 /* sx.val.i = constant */
867 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 M_ISRA_IMM(s1, iptr->sx.val.i, d);
870 emit_store_dst(jd, iptr, d);
873 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
877 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 emit_store_dst(jd, iptr, d);
882 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
883 /* sx.val.i = constant */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887 M_ISRL_IMM(s1, iptr->sx.val.i, d);
888 emit_store_dst(jd, iptr, d);
891 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
897 emit_store_dst(jd, iptr, d);
900 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
901 /* sx.val.i = constant */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905 M_LSLL_IMM(s1, iptr->sx.val.i, d);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 emit_store_dst(jd, iptr, d);
918 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
919 /* sx.val.i = constant */
921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
923 M_LSRA_IMM(s1, iptr->sx.val.i, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
930 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
933 emit_store_dst(jd, iptr, d);
936 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
937 /* sx.val.i = constant */
939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
940 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
941 M_LSRL_IMM(s1, iptr->sx.val.i, d);
942 emit_store_dst(jd, iptr, d);
945 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
952 emit_store_dst(jd, iptr, d);
955 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
956 /* sx.val.i = constant */
958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
959 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
960 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
961 M_AND_IMM(s1, iptr->sx.val.i, d);
963 ICONST(REG_ITMP2, iptr->sx.val.i);
964 M_AND(s1, REG_ITMP2, d);
966 emit_store_dst(jd, iptr, d);
969 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
970 /* sx.val.l = constant */
972 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
975 M_AND_IMM(s1, iptr->sx.val.l, d);
977 LCONST(REG_ITMP2, iptr->sx.val.l);
978 M_AND(s1, REG_ITMP2, d);
980 emit_store_dst(jd, iptr, d);
983 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
987 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990 emit_store_dst(jd, iptr, d);
993 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
994 /* sx.val.i = constant */
996 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
997 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
998 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
999 M_OR_IMM(s1, iptr->sx.val.i, d);
1001 ICONST(REG_ITMP2, iptr->sx.val.i);
1002 M_OR(s1, REG_ITMP2, d);
1004 emit_store_dst(jd, iptr, d);
1007 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1008 /* sx.val.l = constant */
1010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1012 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1013 M_OR_IMM(s1, iptr->sx.val.l, d);
1015 LCONST(REG_ITMP2, iptr->sx.val.l);
1016 M_OR(s1, REG_ITMP2, d);
1018 emit_store_dst(jd, iptr, d);
1021 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1025 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1028 emit_store_dst(jd, iptr, d);
1031 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1032 /* sx.val.i = constant */
1034 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1035 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1036 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1037 M_XOR_IMM(s1, iptr->sx.val.i, d);
1039 ICONST(REG_ITMP2, iptr->sx.val.i);
1040 M_XOR(s1, REG_ITMP2, d);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1046 /* sx.val.l = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1050 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1051 M_XOR_IMM(s1, iptr->sx.val.l, d);
1053 LCONST(REG_ITMP2, iptr->sx.val.l);
1054 M_XOR(s1, REG_ITMP2, d);
1056 emit_store_dst(jd, iptr, d);
1060 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 M_CMPLT(s1, s2, REG_ITMP3);
1066 M_CMPLT(s2, s1, REG_ITMP1);
1067 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1068 emit_store_dst(jd, iptr, d);
1072 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1073 /* s1.localindex = variable, sx.val.i = constant */
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 M_IADD_IMM(s1, iptr->sx.val.i, d);
1080 emit_store_dst(jd, iptr, d);
1084 /* floating operations ************************************************/
1086 case ICMD_FNEG: /* ..., value ==> ..., - value */
1088 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1089 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1091 emit_store_dst(jd, iptr, d);
1094 case ICMD_DNEG: /* ..., value ==> ..., - value */
1096 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1097 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1099 emit_store_dst(jd, iptr, d);
1102 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1104 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1105 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1106 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1113 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1114 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1115 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1117 emit_store_dst(jd, iptr, d);
1120 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1122 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1123 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1124 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1126 emit_store_dst(jd, iptr, d);
1129 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1131 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1132 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1133 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1140 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1141 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1142 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1144 emit_store_dst(jd, iptr, d);
1147 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1149 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1150 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1151 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1158 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1159 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1162 emit_store_dst(jd, iptr, d);
1165 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1167 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1168 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1169 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1171 emit_store_dst(jd, iptr, d);
1175 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1177 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1178 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1179 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1180 M_FDIV(s1,s2, REG_FTMP3);
1181 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1182 M_CVTLF(REG_FTMP3, REG_FTMP3);
1183 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1184 M_FSUB(s1, REG_FTMP3, d);
1185 emit_store_dst(jd, iptr, d);
1188 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1190 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1191 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1193 M_DDIV(s1,s2, REG_FTMP3);
1194 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1195 M_CVTLD(REG_FTMP3, REG_FTMP3);
1196 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1197 M_DSUB(s1, REG_FTMP3, d);
1198 emit_store_dst(jd, iptr, d);
1202 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1204 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1205 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1214 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1217 emit_store_dst(jd, iptr, d);
1221 /* XXX these do not work correctly */
1223 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1225 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1227 M_TRUNCFI(s1, REG_FTMP1);
1228 M_MOVDI(REG_FTMP1, d);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1237 M_TRUNCDI(s1, REG_FTMP1);
1238 M_MOVDI(REG_FTMP1, d);
1240 emit_store_dst(jd, iptr, d);
1243 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1245 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1246 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1247 M_TRUNCFL(s1, REG_FTMP1);
1248 M_MOVDL(REG_FTMP1, d);
1250 emit_store_dst(jd, iptr, d);
1253 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1255 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1256 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1257 M_TRUNCDL(s1, REG_FTMP1);
1258 M_MOVDL(REG_FTMP1, d);
1260 emit_store_dst(jd, iptr, d);
1264 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1266 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1267 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1274 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1275 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1277 emit_store_dst(jd, iptr, d);
1280 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1282 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1283 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1284 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1287 M_LADD_IMM(REG_ZERO, 1, d);
1291 M_LSUB_IMM(REG_ZERO, 1, d);
1292 M_CMOVT(REG_ZERO, d);
1293 emit_store_dst(jd, iptr, d);
1296 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1298 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1299 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1303 M_LADD_IMM(REG_ZERO, 1, d);
1307 M_LSUB_IMM(REG_ZERO, 1, d);
1308 M_CMOVT(REG_ZERO, d);
1309 emit_store_dst(jd, iptr, d);
1312 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1314 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1315 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1319 M_LSUB_IMM(REG_ZERO, 1, d);
1323 M_LADD_IMM(REG_ZERO, 1, d);
1324 M_CMOVT(REG_ZERO, d);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1330 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1332 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1335 M_LSUB_IMM(REG_ZERO, 1, d);
1339 M_LADD_IMM(REG_ZERO, 1, d);
1340 M_CMOVT(REG_ZERO, d);
1341 emit_store_dst(jd, iptr, d);
1345 /* memory operations **************************************************/
1347 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1351 gen_nullptr_check(s1);
1352 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1353 emit_store_dst(jd, iptr, d);
1356 case ICMD_BALOAD: /* ..., 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 if (INSTRUCTION_MUST_CHECK(iptr)) {
1362 gen_nullptr_check(s1);
1365 M_AADD(s2, s1, REG_ITMP3);
1366 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1367 emit_store_dst(jd, iptr, d);
1370 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1372 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1373 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1375 if (INSTRUCTION_MUST_CHECK(iptr)) {
1376 gen_nullptr_check(s1);
1379 M_AADD(s2, s1, REG_ITMP3);
1380 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1381 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1382 emit_store_dst(jd, iptr, d);
1385 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1390 if (INSTRUCTION_MUST_CHECK(iptr)) {
1391 gen_nullptr_check(s1);
1394 M_AADD(s2, s1, REG_ITMP3);
1395 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1396 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1397 emit_store_dst(jd, iptr, d);
1400 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1405 if (INSTRUCTION_MUST_CHECK(iptr)) {
1406 gen_nullptr_check(s1);
1409 M_ASLL_IMM(s2, 2, REG_ITMP3);
1410 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1411 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1417 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1418 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1420 if (INSTRUCTION_MUST_CHECK(iptr)) {
1421 gen_nullptr_check(s1);
1424 M_ASLL_IMM(s2, 3, REG_ITMP3);
1425 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1426 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1427 emit_store_dst(jd, iptr, d);
1430 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1435 if (INSTRUCTION_MUST_CHECK(iptr)) {
1436 gen_nullptr_check(s1);
1439 M_ASLL_IMM(s2, 2, REG_ITMP3);
1440 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1441 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1442 emit_store_dst(jd, iptr, d);
1445 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1447 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1448 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1449 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1450 if (INSTRUCTION_MUST_CHECK(iptr)) {
1451 gen_nullptr_check(s1);
1454 M_ASLL_IMM(s2, 3, REG_ITMP3);
1455 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1456 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1465 if (INSTRUCTION_MUST_CHECK(iptr)) {
1466 gen_nullptr_check(s1);
1469 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1470 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1471 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1472 emit_store_dst(jd, iptr, d);
1476 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1478 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1479 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1480 if (INSTRUCTION_MUST_CHECK(iptr)) {
1481 gen_nullptr_check(s1);
1484 M_AADD(s2, s1, REG_ITMP1);
1485 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1486 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1489 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1490 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1492 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1493 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1494 if (INSTRUCTION_MUST_CHECK(iptr)) {
1495 gen_nullptr_check(s1);
1498 M_AADD(s2, s1, REG_ITMP1);
1499 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1500 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1501 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1504 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1508 if (INSTRUCTION_MUST_CHECK(iptr)) {
1509 gen_nullptr_check(s1);
1512 M_ASLL_IMM(s2, 2, REG_ITMP2);
1513 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1514 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1515 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1518 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1521 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1522 if (INSTRUCTION_MUST_CHECK(iptr)) {
1523 gen_nullptr_check(s1);
1526 M_ASLL_IMM(s2, 3, REG_ITMP2);
1527 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1528 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1529 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1532 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1535 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1536 if (INSTRUCTION_MUST_CHECK(iptr)) {
1537 gen_nullptr_check(s1);
1540 M_ASLL_IMM(s2, 2, REG_ITMP2);
1541 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1542 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1543 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1546 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 if (INSTRUCTION_MUST_CHECK(iptr)) {
1551 gen_nullptr_check(s1);
1554 M_ASLL_IMM(s2, 3, REG_ITMP2);
1555 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1556 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1557 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1561 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1565 if (INSTRUCTION_MUST_CHECK(iptr)) {
1566 gen_nullptr_check(s1);
1569 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1573 disp = dseg_addaddress(cd, BUILTIN_canstore);
1574 M_ALD(REG_ITMP3, REG_PV, disp);
1575 M_JSR(REG_RA, REG_ITMP3);
1578 M_BEQZ(REG_RESULT, 0);
1579 codegen_add_arraystoreexception_ref(cd);
1582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1583 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1584 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1585 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1586 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1587 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1591 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1594 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1595 if (INSTRUCTION_MUST_CHECK(iptr)) {
1596 gen_nullptr_check(s1);
1599 M_AADD(s2, s1, REG_ITMP1);
1600 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1603 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1604 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1607 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1608 if (INSTRUCTION_MUST_CHECK(iptr)) {
1609 gen_nullptr_check(s1);
1612 M_AADD(s2, s1, REG_ITMP1);
1613 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1614 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1617 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621 if (INSTRUCTION_MUST_CHECK(iptr)) {
1622 gen_nullptr_check(s1);
1625 M_ASLL_IMM(s2, 2, REG_ITMP2);
1626 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1627 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1630 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1634 if (INSTRUCTION_MUST_CHECK(iptr)) {
1635 gen_nullptr_check(s1);
1638 M_ASLL_IMM(s2, 3, REG_ITMP2);
1639 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1640 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1643 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1647 if (INSTRUCTION_MUST_CHECK(iptr)) {
1648 gen_nullptr_check(s1);
1651 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1652 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1653 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1657 case ICMD_GETSTATIC: /* ... ==> ..., value */
1659 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1660 uf = iptr->sx.s23.s3.uf;
1661 fieldtype = uf->fieldref->parseddesc.fd->type;
1662 disp = dseg_addaddress(cd, NULL);
1664 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1666 if (opt_showdisassemble) {
1671 fi = iptr->sx.s23.s3.fmiref->p.field;
1672 fieldtype = fi->type;
1673 disp = dseg_addaddress(cd, &(fi->value));
1675 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1676 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1678 if (opt_showdisassemble) {
1684 M_ALD(REG_ITMP1, REG_PV, disp);
1686 switch (fieldtype) {
1688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1689 M_ILD_INTERN(d, REG_ITMP1, 0);
1692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1693 M_LLD_INTERN(d, REG_ITMP1, 0);
1696 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1697 M_ALD_INTERN(d, REG_ITMP1, 0);
1700 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1701 M_FLD_INTERN(d, REG_ITMP1, 0);
1704 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1705 M_DLD_INTERN(d, REG_ITMP1, 0);
1708 emit_store_dst(jd, iptr, d);
1711 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1713 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1714 uf = iptr->sx.s23.s3.uf;
1715 fieldtype = uf->fieldref->parseddesc.fd->type;
1716 disp = dseg_addaddress(cd, NULL);
1718 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1720 if (opt_showdisassemble) {
1725 fi = iptr->sx.s23.s3.fmiref->p.field;
1726 fieldtype = fi->type;
1727 disp = dseg_addaddress(cd, &(fi->value));
1729 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1730 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1732 if (opt_showdisassemble) {
1738 M_ALD(REG_ITMP1, REG_PV, disp);
1740 switch (fieldtype) {
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1743 M_IST_INTERN(s1, REG_ITMP1, 0);
1746 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1747 M_LST_INTERN(s1, REG_ITMP1, 0);
1750 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1751 M_AST_INTERN(s1, REG_ITMP1, 0);
1754 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1755 M_FST_INTERN(s1, REG_ITMP1, 0);
1758 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1759 M_DST_INTERN(s1, REG_ITMP1, 0);
1764 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1765 /* val = value (in current instruction) */
1766 /* following NOP) */
1768 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1769 uf = iptr->sx.s23.s3.uf;
1770 fieldtype = uf->fieldref->parseddesc.fd->type;
1771 disp = dseg_addaddress(cd, NULL);
1773 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1775 if (opt_showdisassemble) {
1780 fi = iptr->sx.s23.s3.fmiref->p.field;
1781 fieldtype = fi->type;
1782 disp = dseg_addaddress(cd, &(fi->value));
1784 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1785 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1787 if (opt_showdisassemble) {
1793 M_ALD(REG_ITMP1, REG_PV, disp);
1795 switch (fieldtype) {
1797 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1800 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1803 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1806 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1809 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1815 case ICMD_GETFIELD: /* ... ==> ..., value */
1817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1818 gen_nullptr_check(s1);
1820 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1821 uf = iptr->sx.s23.s3.uf;
1822 fieldtype = uf->fieldref->parseddesc.fd->type;
1825 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1827 if (opt_showdisassemble) {
1832 fi = iptr->sx.s23.s3.fmiref->p.field;
1833 fieldtype = fi->type;
1837 switch (fieldtype) {
1839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1851 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1855 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1859 emit_store_dst(jd, iptr, d);
1862 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1865 gen_nullptr_check(s1);
1867 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1868 uf = iptr->sx.s23.s3.uf;
1869 fieldtype = uf->fieldref->parseddesc.fd->type;
1873 fi = iptr->sx.s23.s3.fmiref->p.field;
1874 fieldtype = fi->type;
1878 if (IS_INT_LNG_TYPE(fieldtype))
1879 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1881 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1883 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1884 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1886 if (opt_showdisassemble) {
1891 switch (fieldtype) {
1893 M_IST(s2, s1, disp);
1896 M_LST(s2, s1, disp);
1899 M_AST(s2, s1, disp);
1902 M_FST(s2, s1, disp);
1905 M_DST(s2, s1, disp);
1910 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913 gen_nullptr_check(s1);
1915 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1916 unresolved_field *uf = iptr->sx.s23.s3.uf;
1918 fieldtype = uf->fieldref->parseddesc.fd->type;
1920 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1922 if (opt_showdisassemble) {
1929 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1930 fieldtype = fi->type;
1934 switch (fieldtype) {
1936 M_IST(REG_ZERO, s1, disp);
1939 M_LST(REG_ZERO, s1, disp);
1942 M_AST(REG_ZERO, s1, disp);
1945 M_FST(REG_ZERO, s1, disp);
1948 M_DST(REG_ZERO, s1, disp);
1954 /* branch operations **************************************************/
1956 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959 M_INTMOVE(s1, REG_ITMP1_XPTR);
1961 #ifdef ENABLE_VERIFIER
1962 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1963 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1964 iptr->sx.s23.s2.uc, 0);
1966 if (opt_showdisassemble) {
1970 #endif /* ENABLE_VERIFIER */
1972 disp = dseg_addaddress(cd, asm_handle_exception);
1973 M_ALD(REG_ITMP2, REG_PV, disp);
1974 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
1976 M_NOP; /* nop ensures that XPC is less than the end */
1977 /* of basic block */
1981 case ICMD_GOTO: /* ... ==> ... */
1982 case ICMD_RET: /* ... ==> ... */
1985 codegen_addreference(cd, iptr->dst.block);
1990 case ICMD_JSR: /* ... ==> ... */
1992 dseg_addtarget(cd, iptr->sx.s23.s3.jsrtarget.block);
1993 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
1994 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
1998 case ICMD_IFNULL: /* ..., value ==> ... */
2000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2002 codegen_addreference(cd, iptr->dst.block);
2006 case ICMD_IFNONNULL: /* ..., value ==> ... */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2010 codegen_addreference(cd, iptr->dst.block);
2014 case ICMD_IFEQ: /* ..., value ==> ... */
2016 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2017 if (iptr->sx.val.i == 0) {
2020 ICONST(REG_ITMP2, iptr->sx.val.i);
2021 M_BEQ(s1, REG_ITMP2, 0);
2023 codegen_addreference(cd, iptr->dst.block);
2027 case ICMD_IFLT: /* ..., value ==> ... */
2029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2030 if (iptr->sx.val.i == 0) {
2033 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2034 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2036 ICONST(REG_ITMP2, iptr->sx.val.i);
2037 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2039 M_BNEZ(REG_ITMP1, 0);
2041 codegen_addreference(cd, iptr->dst.block);
2045 case ICMD_IFLE: /* ..., value ==> ... */
2047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048 if (iptr->sx.val.i == 0) {
2052 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2053 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2054 M_BNEZ(REG_ITMP1, 0);
2057 ICONST(REG_ITMP2, iptr->sx.val.i);
2058 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2059 M_BEQZ(REG_ITMP1, 0);
2062 codegen_addreference(cd, iptr->dst.block);
2066 case ICMD_IFNE: /* ..., value ==> ... */
2068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2069 if (iptr->sx.val.i == 0) {
2073 ICONST(REG_ITMP2, iptr->sx.val.i);
2074 M_BNE(s1, REG_ITMP2, 0);
2076 codegen_addreference(cd, iptr->dst.block);
2080 case ICMD_IFGT: /* ..., value ==> ... */
2082 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2083 if (iptr->sx.val.i == 0) {
2087 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2088 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2089 M_BEQZ(REG_ITMP1, 0);
2092 ICONST(REG_ITMP2, iptr->sx.val.i);
2093 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2094 M_BNEZ(REG_ITMP1, 0);
2097 codegen_addreference(cd, iptr->dst.block);
2101 case ICMD_IFGE: /* ..., value ==> ... */
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 if (iptr->sx.val.i == 0) {
2108 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2109 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2112 ICONST(REG_ITMP2, iptr->sx.val.i);
2113 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2115 M_BEQZ(REG_ITMP1, 0);
2117 codegen_addreference(cd, iptr->dst.block);
2121 case ICMD_IF_LEQ: /* ..., value ==> ... */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 if (iptr->sx.val.l == 0) {
2128 LCONST(REG_ITMP2, iptr->sx.val.l);
2129 M_BEQ(s1, REG_ITMP2, 0);
2131 codegen_addreference(cd, iptr->dst.block);
2135 case ICMD_IF_LLT: /* ..., value ==> ... */
2137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2138 if (iptr->sx.val.l == 0) {
2142 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2143 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2146 LCONST(REG_ITMP2, iptr->sx.val.l);
2147 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2149 M_BNEZ(REG_ITMP1, 0);
2151 codegen_addreference(cd, iptr->dst.block);
2155 case ICMD_IF_LLE: /* ..., value ==> ... */
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158 if (iptr->sx.val.l == 0) {
2162 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2163 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2164 M_BNEZ(REG_ITMP1, 0);
2167 LCONST(REG_ITMP2, iptr->sx.val.l);
2168 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2169 M_BEQZ(REG_ITMP1, 0);
2172 codegen_addreference(cd, iptr->dst.block);
2176 case ICMD_IF_LNE: /* ..., value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 if (iptr->sx.val.l == 0) {
2183 LCONST(REG_ITMP2, iptr->sx.val.l);
2184 M_BNE(s1, REG_ITMP2, 0);
2186 codegen_addreference(cd, iptr->dst.block);
2190 case ICMD_IF_LGT: /* ..., value ==> ... */
2192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2193 if (iptr->sx.val.l == 0) {
2197 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2198 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2199 M_BEQZ(REG_ITMP1, 0);
2202 LCONST(REG_ITMP2, iptr->sx.val.l);
2203 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2204 M_BNEZ(REG_ITMP1, 0);
2207 codegen_addreference(cd, iptr->dst.block);
2211 case ICMD_IF_LGE: /* ..., value ==> ... */
2213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2214 if (iptr->sx.val.l == 0) {
2218 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2219 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2222 LCONST(REG_ITMP2, iptr->sx.val.l);
2223 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2225 M_BEQZ(REG_ITMP1, 0);
2227 codegen_addreference(cd, iptr->dst.block);
2231 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2232 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2233 case ICMD_IF_ACMPEQ:
2235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2238 codegen_addreference(cd, iptr->dst.block);
2242 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2243 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2244 case ICMD_IF_ACMPNE:
2246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2247 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2249 codegen_addreference(cd, iptr->dst.block);
2253 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2254 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2256 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2257 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2258 M_CMPLT(s1, s2, REG_ITMP1);
2259 M_BNEZ(REG_ITMP1, 0);
2260 codegen_addreference(cd, iptr->dst.block);
2264 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2265 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2268 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2269 M_CMPGT(s1, s2, REG_ITMP1);
2270 M_BNEZ(REG_ITMP1, 0);
2271 codegen_addreference(cd, iptr->dst.block);
2275 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2276 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2279 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2280 M_CMPGT(s1, s2, REG_ITMP1);
2281 M_BEQZ(REG_ITMP1, 0);
2282 codegen_addreference(cd, iptr->dst.block);
2286 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2287 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2289 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2290 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2291 M_CMPLT(s1, s2, REG_ITMP1);
2292 M_BEQZ(REG_ITMP1, 0);
2293 codegen_addreference(cd, iptr->dst.block);
2298 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2301 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2302 M_INTMOVE(s1, REG_RESULT);
2303 goto nowperformreturn;
2305 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2307 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2308 M_INTMOVE(s1, REG_RESULT);
2310 #ifdef ENABLE_VERIFIER
2311 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2312 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2313 iptr->sx.s23.s2.uc, 0);
2315 if (opt_showdisassemble) {
2319 #endif /* ENABLE_VERIFIER */
2320 goto nowperformreturn;
2322 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2324 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2325 M_FLTMOVE(s1, REG_FRESULT);
2326 goto nowperformreturn;
2328 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2330 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2331 M_DBLMOVE(s1, REG_FRESULT);
2332 goto nowperformreturn;
2334 case ICMD_RETURN: /* ... ==> ... */
2340 p = cd->stackframesize;
2342 #if !defined(NDEBUG)
2343 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2344 emit_verbosecall_exit(jd);
2347 #if defined(ENABLE_THREADS)
2348 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2349 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2350 M_ALD(REG_ITMP3, REG_PV, disp);
2352 /* we need to save the proper return value */
2354 switch (iptr->opc) {
2358 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2359 M_JSR(REG_RA, REG_ITMP3);
2360 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2364 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2365 M_JSR(REG_RA, REG_ITMP3);
2366 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2369 M_JSR(REG_RA, REG_ITMP3);
2370 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2374 /* and now restore the proper return value */
2376 switch (iptr->opc) {
2380 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2384 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2390 /* restore return address */
2392 if (!jd->isleafmethod) {
2393 p--; M_ALD(REG_RA, REG_SP, p * 8);
2396 /* restore saved registers */
2398 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2399 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2401 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2402 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2405 /* deallocate stack and return */
2407 if (cd->stackframesize) {
2410 disp = cd->stackframesize * 8;
2411 lo = (short) (disp);
2412 hi = (short) (((disp) - lo) >> 16);
2416 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2418 M_LUI(REG_ITMP3,hi);
2419 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2421 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2434 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2437 branch_target_t *table;
2439 table = iptr->dst.table;
2441 l = iptr->sx.s23.s2.tablelow;
2442 i = iptr->sx.s23.s3.tablehigh;
2444 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2446 {M_INTMOVE(s1, REG_ITMP1);}
2447 else if (l <= 32768) {
2448 M_IADD_IMM(s1, -l, REG_ITMP1);
2451 ICONST(REG_ITMP2, l);
2452 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2455 /* number of targets */
2460 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2461 M_BEQZ(REG_ITMP2, 0);
2462 codegen_addreference(cd, table[0].block); /* default target */
2463 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2465 /* build jump table top down and use address of lowest entry */
2470 dseg_addtarget(cd, table->block);
2475 /* length of dataseg after last dseg_addtarget is used by load */
2477 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2478 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2485 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2488 lookup_target_t *lookup;
2490 lookup = iptr->dst.lookup;
2492 i = iptr->sx.s23.s2.lookupcount;
2494 MCODECHECK((i<<2)+8);
2495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2498 ICONST(REG_ITMP2, lookup->value);
2499 M_BEQ(s1, REG_ITMP2, 0);
2500 codegen_addreference(cd, lookup->target.block);
2506 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2513 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2515 bte = iptr->sx.s23.s3.bte;
2519 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2521 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2522 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2523 case ICMD_INVOKEINTERFACE:
2525 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2527 um = iptr->sx.s23.s3.um;
2528 md = um->methodref->parseddesc.md;
2531 lm = iptr->sx.s23.s3.fmiref->p.method;
2533 md = lm->parseddesc;
2537 s3 = md->paramcount;
2539 MCODECHECK((s3 << 1) + 64);
2541 /* copy arguments to registers or stack location */
2543 for (s3 = s3 - 1; s3 >= 0; s3--) {
2544 var = VAR(iptr->sx.s23.s2.args[s3]);
2546 if (var->flags & PREALLOC)
2549 if (IS_INT_LNG_TYPE(var->type)) {
2550 if (!md->params[s3].inmemory) {
2551 s1 = rd->argintregs[md->params[s3].regoff];
2552 d = emit_load(jd, iptr, var, s1);
2556 d = emit_load(jd, iptr, var, REG_ITMP1);
2557 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2561 if (!md->params[s3].inmemory) {
2562 s1 = rd->argfltregs[md->params[s3].regoff];
2563 d = emit_load(jd, iptr, var, s1);
2564 if (IS_2_WORD_TYPE(var->type))
2570 d = emit_load(jd, iptr, var, REG_FTMP1);
2571 if (IS_2_WORD_TYPE(var->type))
2572 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2574 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2579 switch (iptr->opc) {
2581 disp = dseg_addaddress(cd, bte->fp);
2583 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2585 /* TWISTI: i actually don't know the reason for using
2586 REG_ITMP3 here instead of REG_PV. */
2590 case ICMD_INVOKESPECIAL:
2592 codegen_add_nullpointerexception_ref(cd);
2596 case ICMD_INVOKESTATIC:
2598 disp = dseg_addaddress(cd, NULL);
2600 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2603 if (opt_showdisassemble) {
2608 disp = dseg_addaddress(cd, lm->stubroutine);
2610 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2614 case ICMD_INVOKEVIRTUAL:
2615 gen_nullptr_check(REG_A0);
2618 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2620 if (opt_showdisassemble) {
2627 s1 = OFFSET(vftbl_t, table[0]) +
2628 sizeof(methodptr) * lm->vftblindex;
2630 M_ALD(REG_METHODPTR, REG_A0,
2631 OFFSET(java_objectheader, vftbl));
2632 M_ALD(REG_PV, REG_METHODPTR, s1);
2636 case ICMD_INVOKEINTERFACE:
2637 gen_nullptr_check(REG_A0);
2640 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2642 if (opt_showdisassemble) {
2650 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2651 sizeof(methodptr*) * lm->class->index;
2653 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2656 M_ALD(REG_METHODPTR, REG_A0,
2657 OFFSET(java_objectheader, vftbl));
2658 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2659 M_ALD(REG_PV, REG_METHODPTR, s2);
2664 /* generate the actual call */
2668 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2669 M_LDA(REG_PV, REG_RA, -disp);
2671 /* actually only used for ICMD_BUILTIN */
2673 if (INSTRUCTION_MUST_CHECK(iptr)) {
2674 M_BEQZ(REG_RESULT, 0);
2675 codegen_add_fillinstacktrace_ref(cd);
2679 /* store return value */
2681 d = md->returntype.type;
2683 if (d != TYPE_VOID) {
2684 if (IS_INT_LNG_TYPE(d)) {
2685 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2686 M_INTMOVE(REG_RESULT, s1);
2689 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2690 if (IS_2_WORD_TYPE(d))
2691 M_DMOV(REG_FRESULT, s1);
2693 M_FMOV(REG_FRESULT, s1);
2695 emit_store_dst(jd, iptr, s1);
2700 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2701 /* val.a: (classinfo*) superclass */
2703 /* superclass is an interface:
2705 * OK if ((sub == NULL) ||
2706 * (sub->vftbl->interfacetablelength > super->index) &&
2707 * (sub->vftbl->interfacetable[-super->index] != NULL));
2709 * superclass is a class:
2711 * OK if ((sub == NULL) || (0
2712 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2713 * super->vftbl->diffvall));
2716 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2718 vftbl_t *supervftbl;
2721 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2727 super = iptr->sx.s23.s3.c.cls;
2728 superindex = super->index;
2729 supervftbl = super->vftbl;
2732 #if defined(ENABLE_THREADS)
2733 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2738 /* calculate interface checkcast code size */
2742 s2 += (opt_showdisassemble ? 2 : 0);
2744 /* calculate class checkcast code size */
2746 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2748 s3 += (opt_showdisassemble ? 2 : 0);
2750 /* if class is not resolved, check which code to call */
2752 if (super == NULL) {
2753 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2756 disp = dseg_adds4(cd, 0); /* super->flags */
2758 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2759 iptr->sx.s23.s3.c.ref,
2762 if (opt_showdisassemble) {
2766 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2767 M_ILD(REG_ITMP2, REG_PV, disp);
2768 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2769 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2773 /* interface checkcast code */
2775 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2776 if (super != NULL) {
2781 codegen_addpatchref(cd,
2782 PATCHER_checkcast_instanceof_interface,
2783 iptr->sx.s23.s3.c.ref,
2786 if (opt_showdisassemble) {
2791 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2792 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2793 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2794 M_BLEZ(REG_ITMP3, 0);
2795 codegen_add_classcastexception_ref(cd, s1);
2797 M_ALD(REG_ITMP3, REG_ITMP2,
2798 OFFSET(vftbl_t, interfacetable[0]) -
2799 superindex * sizeof(methodptr*));
2800 M_BEQZ(REG_ITMP3, 0);
2801 codegen_add_classcastexception_ref(cd, s1);
2804 if (super == NULL) {
2810 /* class checkcast code */
2812 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2813 disp = dseg_addaddress(cd, (void *) supervftbl);
2815 if (super != NULL) {
2820 codegen_addpatchref(cd,
2821 PATCHER_checkcast_instanceof_class,
2822 iptr->sx.s23.s3.c.ref,
2825 if (opt_showdisassemble) {
2830 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2831 M_ALD(REG_ITMP3, REG_PV, disp);
2832 #if defined(ENABLE_THREADS)
2833 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2835 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2836 /* if (s1 != REG_ITMP1) { */
2837 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2838 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2839 /* #if defined(ENABLE_THREADS) */
2840 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2842 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2844 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2845 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2846 M_ALD(REG_ITMP3, REG_PV, disp);
2847 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2848 #if defined(ENABLE_THREADS)
2849 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2852 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2853 M_BNEZ(REG_ITMP3, 0);
2854 codegen_add_classcastexception_ref(cd, s1);
2858 d = codegen_reg_of_dst(jd, iptr, s1);
2861 s1 = emit_load_s1(jd, iptr, REG_A0);
2862 M_INTMOVE(s1, REG_A0);
2864 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
2866 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2867 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2868 iptr->sx.s23.s3.c.ref,
2871 if (opt_showdisassemble) {
2876 M_ALD(REG_A1, REG_PV, disp);
2877 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
2878 M_ALD(REG_ITMP3, REG_PV, disp);
2879 M_JSR(REG_RA, REG_ITMP3);
2882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2883 M_BEQZ(REG_RESULT, 0);
2884 codegen_add_classcastexception_ref(cd, s1);
2887 d = codegen_reg_of_dst(jd, iptr, s1);
2891 emit_store_dst(jd, iptr, d);
2894 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2895 /* val.a: (classinfo*) superclass */
2897 /* superclass is an interface:
2899 * return (sub != NULL) &&
2900 * (sub->vftbl->interfacetablelength > super->index) &&
2901 * (sub->vftbl->interfacetable[-super->index] != NULL);
2903 * superclass is a class:
2905 * return ((sub != NULL) && (0
2906 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2907 * super->vftbl->diffvall));
2912 vftbl_t *supervftbl;
2915 super = iptr->sx.s23.s3.c.cls;
2917 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2923 super = iptr->sx.s23.s3.c.cls;
2924 superindex = super->index;
2925 supervftbl = super->vftbl;
2928 #if defined(ENABLE_THREADS)
2929 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2935 M_MOV(s1, REG_ITMP1);
2939 /* calculate interface instanceof code size */
2943 s2 += (opt_showdisassemble ? 2 : 0);
2945 /* calculate class instanceof code size */
2949 s3 += (opt_showdisassemble ? 2 : 0);
2953 /* if class is not resolved, check which code to call */
2955 if (super == NULL) {
2956 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2959 disp = dseg_adds4(cd, 0); /* super->flags */
2961 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2962 iptr->sx.s23.s3.c.ref, disp);
2964 if (opt_showdisassemble) {
2968 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2969 M_ILD(REG_ITMP3, REG_PV, disp);
2970 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2971 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
2975 /* interface instanceof code */
2977 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2978 if (super != NULL) {
2983 codegen_addpatchref(cd,
2984 PATCHER_checkcast_instanceof_interface,
2985 iptr->sx.s23.s3.c.ref, 0);
2987 if (opt_showdisassemble) {
2992 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2993 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2994 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2995 M_BLEZ(REG_ITMP3, 3);
2997 M_ALD(REG_ITMP1, REG_ITMP1,
2998 OFFSET(vftbl_t, interfacetable[0]) -
2999 superindex * sizeof(methodptr*));
3000 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3002 if (super == NULL) {
3008 /* class instanceof code */
3010 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3011 disp = dseg_addaddress(cd, supervftbl);
3013 if (super != NULL) {
3018 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3019 iptr->sx.s23.s3.c.ref,
3022 if (opt_showdisassemble) {
3027 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3028 M_ALD(REG_ITMP2, REG_PV, disp);
3029 #if defined(ENABLE_THREADS)
3030 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3032 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3033 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3034 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3035 #if defined(ENABLE_THREADS)
3036 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3038 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3039 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3042 emit_store_dst(jd, iptr, d);
3046 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3048 /* check for negative sizes and copy sizes to stack if necessary */
3050 MCODECHECK((iptr->s1.argcount << 1) + 64);
3052 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3054 var = VAR(iptr->sx.s23.s2.args[s1]);
3056 /* copy SAVEDVAR sizes to stack */
3058 if (!(var->flags & PREALLOC)) {
3059 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3060 M_LST(s2, REG_SP, s1 * 8);
3064 /* a0 = dimension count */
3066 ICONST(REG_A0, iptr->s1.argcount);
3068 /* is patcher function set? */
3070 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3071 disp = dseg_addaddress(cd, NULL);
3073 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3074 iptr->sx.s23.s3.c.ref, disp);
3076 if (opt_showdisassemble) {
3081 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3084 /* a1 = arraydescriptor */
3086 M_ALD(REG_A1, REG_PV, disp);
3088 /* a2 = pointer to dimensions = stack pointer */
3090 M_INTMOVE(REG_SP, REG_A2);
3092 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3093 M_ALD(REG_ITMP3, REG_PV, disp);
3094 M_JSR(REG_RA, REG_ITMP3);
3097 /* check for exception before result assignment */
3099 M_BEQZ(REG_RESULT, 0);
3100 codegen_add_fillinstacktrace_ref(cd);
3103 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3104 M_INTMOVE(REG_RESULT, d);
3105 emit_store_dst(jd, iptr, d);
3109 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3113 } /* for instruction */
3115 MCODECHECK(64); /* XXX require smaller number? */
3117 /* At the end of a basic block we may have to append some nops,
3118 because the patcher stub calling code might be longer than the
3119 actual instruction. So codepatching does not change the
3120 following block unintentionally. */
3122 if (cd->mcodeptr < cd->lastmcodeptr) {
3123 while (cd->mcodeptr < cd->lastmcodeptr)
3127 } /* if (bptr -> flags >= BBREACHED) */
3128 } /* for basic block */
3130 dseg_createlinenumbertable(cd);
3132 /* generate exception and patcher stubs */
3134 emit_exception_stubs(jd);
3135 emit_patcher_stubs(jd);
3138 emit_replacement_stubs(jd);
3143 /* everything's ok */
3149 /* createcompilerstub **********************************************************
3151 Creates a stub routine which calls the compiler.
3153 *******************************************************************************/
3155 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3156 #define COMPILERSTUB_CODESIZE 4 * 4
3158 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3161 u1 *createcompilerstub(methodinfo *m)
3163 u1 *s; /* memory to hold the stub */
3169 s = CNEW(u1, COMPILERSTUB_SIZE);
3171 /* set data pointer and code pointer */
3174 s = s + COMPILERSTUB_DATASIZE;
3176 /* mark start of dump memory area */
3178 dumpsize = dump_size();
3180 cd = DNEW(codegendata);
3183 /* Store the codeinfo pointer in the same place as in the
3184 methodheader for compiled methods. */
3186 code = code_codeinfo_new(m);
3188 d[0] = (ptrint) asm_call_jit_compiler;
3190 d[2] = (ptrint) code;
3192 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3193 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3197 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3199 #if defined(ENABLE_STATISTICS)
3201 count_cstub_len += COMPILERSTUB_SIZE;
3204 /* release dump area */
3206 dump_release(dumpsize);
3212 /* createnativestub ************************************************************
3214 Creates a stub routine which calls a native method.
3216 *******************************************************************************/
3218 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3226 s4 i, j; /* count variables */
3229 s4 funcdisp; /* displacement of the function */
3231 /* get required compiler data */
3238 /* initialize variables */
3241 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3243 /* calculate stack frame size */
3245 cd->stackframesize =
3246 1 + /* return address */
3247 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3248 sizeof(localref_table) / SIZEOF_VOID_P +
3249 md->paramcount + /* for saving arguments over calls */
3250 1 + /* for saving return address */
3253 /* create method header */
3255 #if SIZEOF_VOID_P == 4
3256 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3258 (void) dseg_addaddress(cd, code); /* MethodPointer */
3259 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3260 (void) dseg_adds4(cd, 0); /* IsSync */
3261 (void) dseg_adds4(cd, 0); /* IsLeaf */
3262 (void) dseg_adds4(cd, 0); /* IntSave */
3263 (void) dseg_adds4(cd, 0); /* FltSave */
3264 (void) dseg_addlinenumbertablesize(cd);
3265 (void) dseg_adds4(cd, 0); /* ExTableSize */
3267 /* generate stub code */
3269 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3270 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3272 #if !defined(NDEBUG)
3273 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3274 emit_verbosecall_enter(jd);
3277 /* get function address (this must happen before the stackframeinfo) */
3279 funcdisp = dseg_addaddress(cd, f);
3281 #if !defined(WITH_STATIC_CLASSPATH)
3283 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3285 if (opt_showdisassemble) {
3291 /* save integer and float argument registers */
3293 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3294 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3295 M_LST(rd->argintregs[i], REG_SP, j * 8);
3300 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3301 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3302 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3307 /* prepare data structures for native function call */
3309 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3310 M_MOV(REG_PV, REG_A1);
3311 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3312 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3313 disp = dseg_addaddress(cd, codegen_start_native_call);
3314 M_ALD(REG_ITMP3, REG_PV, disp);
3315 M_JSR(REG_RA, REG_ITMP3);
3316 M_NOP; /* XXX fill me! */
3318 /* restore integer and float argument registers */
3320 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3321 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3322 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3327 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3328 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3329 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3334 /* copy or spill arguments to new locations */
3336 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3337 t = md->paramtypes[i].type;
3339 if (IS_INT_LNG_TYPE(t)) {
3340 if (!md->params[i].inmemory) {
3341 s1 = rd->argintregs[md->params[i].regoff];
3343 if (!nmd->params[j].inmemory) {
3344 s2 = rd->argintregs[nmd->params[j].regoff];
3347 s2 = nmd->params[j].regoff;
3348 M_AST(s1, REG_SP, s2 * 8);
3352 s1 = md->params[i].regoff + cd->stackframesize;
3353 s2 = nmd->params[j].regoff;
3354 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3355 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3359 if (!md->params[i].inmemory) {
3360 s1 = rd->argfltregs[md->params[i].regoff];
3362 if (!nmd->params[j].inmemory) {
3363 s2 = rd->argfltregs[nmd->params[j].regoff];
3364 if (IS_2_WORD_TYPE(t))
3370 s2 = nmd->params[j].regoff;
3371 if (IS_2_WORD_TYPE(t))
3372 M_DST(s1, REG_SP, s2 * 8);
3374 M_FST(s1, REG_SP, s2 * 8);
3378 s1 = md->params[i].regoff + cd->stackframesize;
3379 s2 = nmd->params[j].regoff;
3380 if (IS_2_WORD_TYPE(t)) {
3381 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3382 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3384 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3385 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3391 /* put class into second argument register */
3393 if (m->flags & ACC_STATIC) {
3394 disp = dseg_addaddress(cd, m->class);
3395 M_ALD(REG_A1, REG_PV, disp);
3398 /* put env into first argument register */
3400 disp = dseg_addaddress(cd, _Jv_env);
3401 M_ALD(REG_A0, REG_PV, disp);
3403 /* do the native function call */
3405 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3406 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3407 M_NOP; /* delay slot */
3409 /* save return value */
3411 if (md->returntype.type != TYPE_VOID) {
3412 if (IS_INT_LNG_TYPE(md->returntype.type))
3413 M_LST(REG_RESULT, REG_SP, 0 * 8);
3415 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3418 #if !defined(NDEBUG)
3419 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3420 emit_verbosecall_exit(jd);
3423 /* remove native stackframe info */
3425 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3426 disp = dseg_addaddress(cd, codegen_finish_native_call);
3427 M_ALD(REG_ITMP3, REG_PV, disp);
3428 M_JSR(REG_RA, REG_ITMP3);
3429 M_NOP; /* XXX fill me! */
3430 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3432 /* restore return value */
3434 if (md->returntype.type != TYPE_VOID) {
3435 if (IS_INT_LNG_TYPE(md->returntype.type))
3436 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3438 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3441 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3443 /* check for exception */
3445 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3446 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3448 M_RET(REG_RA); /* return to caller */
3449 M_NOP; /* DELAY SLOT */
3451 /* handle exception */
3453 disp = dseg_addaddress(cd, asm_handle_nat_exception);
3454 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3455 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3456 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3458 /* generate patcher stubs */
3460 emit_patcher_stubs(jd);
3464 return code->entrypoint;
3469 * These are local overrides for various environment variables in Emacs.
3470 * Please do not remove this and leave it at the end of the file, where
3471 * Emacs will automagically detect them.
3472 * ---------------------------------------------------------------------
3475 * indent-tabs-mode: t
3479 * vim:noexpandtab:sw=4:ts=4: