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 5815 2006-10-20 18:35:32Z twisti $
52 #include "vm/jit/mips/arch.h"
53 #include "vm/jit/mips/codegen.h"
55 #include "native/native.h"
57 #if defined(ENABLE_THREADS)
58 # include "threads/native/lock.h"
61 #include "vm/builtin.h"
63 #include "vm/exceptions.h"
64 #include "vm/options.h"
65 #include "vm/stringlocal.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit-common.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/patcher.h"
73 #include "vm/jit/reg.h"
74 #include "vm/jit/replace.h"
76 #if defined(ENABLE_LSRA)
77 # include "vm/jit/allocator/lsra.h"
81 /* codegen *********************************************************************
83 Generates machine code.
85 *******************************************************************************/
87 bool codegen(jitdata *jd)
93 s4 len, s1, s2, s3, d, disp;
99 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
100 unresolved_method *um;
101 builtintable_entry *bte;
104 unresolved_field *uf;
105 rplpoint *replacementpoint;
109 /* get required compiler data */
120 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
122 /* space to save used callee saved registers */
124 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
125 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
127 cd->stackframesize = rd->memuse + savedregs_num;
129 #if defined(ENABLE_THREADS)
130 /* space to save argument of monitor_enter */
132 if (checksync && (m->flags & ACC_SYNCHRONIZED))
133 cd->stackframesize++;
136 /* keep stack 16-byte aligned */
138 if (cd->stackframesize & 1)
139 cd->stackframesize++;
141 /* create method header */
143 #if SIZEOF_VOID_P == 4
144 (void) dseg_addaddress(cd, code); /* Filler */
146 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
147 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
149 #if defined(ENABLE_THREADS)
150 /* IsSync contains the offset relative to the stack pointer for the
151 argument of monitor_exit used in the exception handler. Since the
152 offset could be zero and give a wrong meaning of the flag it is
156 if (checksync && (m->flags & ACC_SYNCHRONIZED))
157 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
160 (void) dseg_adds4(cd, 0); /* IsSync */
162 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
163 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
164 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
165 dseg_addlinenumbertablesize(cd);
166 (void) dseg_adds4(cd, jd->exceptiontablelength); /* ExTableSize */
168 /* create exception table */
170 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
171 dseg_addtarget(cd, ex->start);
172 dseg_addtarget(cd, ex->end);
173 dseg_addtarget(cd, ex->handler);
174 (void) dseg_addaddress(cd, ex->catchtype.any);
177 /* create stack frame (if necessary) */
179 if (cd->stackframesize)
180 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
182 /* save return address and used callee saved registers */
184 p = cd->stackframesize;
185 if (!jd->isleafmethod) {
186 p--; M_AST(REG_RA, REG_SP, p * 8);
188 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
189 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
191 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
192 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
195 /* take arguments out of register or stack frame */
199 for (p = 0, l = 0; p < md->paramcount; p++) {
200 t = md->paramtypes[p].type;
202 varindex = jd->local_map[l * 5 + t];
205 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
208 if (varindex == UNUSED)
213 s1 = md->params[p].regoff;
214 if (IS_INT_LNG_TYPE(t)) { /* integer args */
215 if (!md->params[p].inmemory) { /* register arguments */
216 s2 = rd->argintregs[s1];
217 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
218 M_INTMOVE(s2, var->vv.regoff);
219 } else { /* reg arg -> spilled */
220 M_LST(s2, REG_SP, var->vv.regoff * 8);
223 } else { /* stack arguments */
224 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
225 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
226 } else { /* stack arg -> spilled */
227 var->vv.regoff = cd->stackframesize + s1;
231 } else { /* floating args */
232 if (!md->params[p].inmemory) { /* register arguments */
233 s2 = rd->argfltregs[s1];
234 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
235 if (IS_2_WORD_TYPE(t))
236 M_DMOV(s2, var->vv.regoff);
238 M_FMOV(s2, var->vv.regoff);
239 } else { /* reg arg -> spilled */
240 if (IS_2_WORD_TYPE(t))
241 M_DST(s2, REG_SP, var->vv.regoff * 8);
243 M_FST(s2, REG_SP, var->vv.regoff * 8);
246 } else { /* stack arguments */
247 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
248 if (IS_2_WORD_TYPE(t))
249 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
251 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
252 } else /* stack-arg -> spilled */
253 var->vv.regoff = cd->stackframesize + s1;
258 /* call monitorenter function */
260 #if defined(ENABLE_THREADS)
261 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
262 /* stack offset for monitor argument */
266 # if !defined(NDEBUG)
267 if (opt_verbosecall) {
268 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
270 for (p = 0; p < INT_ARG_CNT; p++)
271 M_LST(rd->argintregs[p], REG_SP, p * 8);
273 for (p = 0; p < FLT_ARG_CNT; p++)
274 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
276 s1 += INT_ARG_CNT + FLT_ARG_CNT;
280 /* get correct lock object */
282 if (m->flags & ACC_STATIC) {
283 p = dseg_addaddress(cd, &m->class->object.header);
284 M_ALD(REG_A0, REG_PV, p);
288 codegen_add_nullpointerexception_ref(cd);
291 p = dseg_addaddress(cd, LOCK_monitor_enter);
292 M_ALD(REG_ITMP3, REG_PV, p);
293 M_JSR(REG_RA, REG_ITMP3);
294 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
296 # if !defined(NDEBUG)
297 if (opt_verbosecall) {
298 for (p = 0; p < INT_ARG_CNT; p++)
299 M_LLD(rd->argintregs[p], REG_SP, p * 8);
301 for (p = 0; p < FLT_ARG_CNT; p++)
302 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
305 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
312 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
313 emit_verbosecall_enter(jd);
318 /* end of header generation */
320 replacementpoint = jd->code->rplpoints;
322 /* walk through all basic blocks */
324 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
326 /* handle replacement points */
329 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
331 /* 8-byte align pc */
332 if ((ptrint) cd->mcodeptr & 4) {
336 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
339 assert(cd->lastmcodeptr <= cd->mcodeptr);
340 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
344 /* store relative start of block */
346 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
348 if (bptr->flags >= BBREACHED) {
350 /* branch resolving */
353 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
354 gen_resolvebranch(cd->mcodebase + bref->branchpos,
360 /* copy interface registers to their destination */
364 #if defined(ENABLE_LSRA)
368 src = bptr->invars[len];
369 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
370 /* d = reg_of_var(m, src, REG_ITMP1); */
371 if (!(src->flags & INMEMORY))
375 M_INTMOVE(REG_ITMP1, d);
376 emit_store(jd, NULL, src, d);
383 var = VAR(bptr->invars[len]);
384 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
385 d = codegen_reg_of_var(0, var, REG_ITMP1);
386 M_INTMOVE(REG_ITMP1, d);
387 emit_store(jd, NULL, var, d);
390 assert((var->flags & INOUT));
393 #if defined(ENABLE_LSRA)
396 /* walk through all instructions */
401 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
402 if (iptr->line != currentline) {
403 dseg_addlinenumber(cd, iptr->line);
404 currentline = iptr->line;
407 MCODECHECK(64); /* an instruction usually needs < 64 words */
411 case ICMD_NOP: /* ... ==> ... */
414 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
418 codegen_add_nullpointerexception_ref(cd);
422 /* constant operations ************************************************/
424 case ICMD_ICONST: /* ... ==> ..., constant */
426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
427 ICONST(d, iptr->sx.val.i);
428 emit_store_dst(jd, iptr, d);
431 case ICMD_LCONST: /* ... ==> ..., constant */
433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
434 LCONST(d, iptr->sx.val.l);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_FCONST: /* ... ==> ..., constant */
440 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
441 disp = dseg_addfloat(cd, iptr->sx.val.f);
442 M_FLD(d, REG_PV, disp);
443 emit_store_dst(jd, iptr, d);
446 case ICMD_DCONST: /* ... ==> ..., constant */
448 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
449 disp = dseg_adddouble(cd, iptr->sx.val.d);
450 M_DLD(d, REG_PV, disp);
451 emit_store_dst(jd, iptr, d);
454 case ICMD_ACONST: /* ... ==> ..., constant */
456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
458 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
459 disp = dseg_addaddress(cd, NULL);
461 codegen_addpatchref(cd, PATCHER_aconst,
465 if (opt_showdisassemble) {
469 M_ALD(d, REG_PV, disp);
472 if (iptr->sx.val.anyptr == NULL) {
473 M_INTMOVE(REG_ZERO, d);
475 disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
476 M_ALD(d, REG_PV, disp);
479 emit_store_dst(jd, iptr, d);
483 /* load/store/copy/move operations ************************************/
485 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
486 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
487 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
488 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
489 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
490 case ICMD_ISTORE: /* ..., value ==> ... */
491 case ICMD_LSTORE: /* ..., value ==> ... */
492 case ICMD_ASTORE: /* ..., value ==> ... */
493 case ICMD_FSTORE: /* ..., value ==> ... */
494 case ICMD_DSTORE: /* ..., value ==> ... */
498 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
502 /* pop/dup/swap operations ********************************************/
504 /* attention: double and longs are only one entry in CACAO ICMDs */
506 case ICMD_POP: /* ..., value ==> ... */
507 case ICMD_POP2: /* ..., value, value ==> ... */
511 /* integer operations *************************************************/
513 case ICMD_INEG: /* ..., value ==> ..., - value */
515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
516 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
517 M_ISUB(REG_ZERO, s1, d);
518 emit_store_dst(jd, iptr, d);
521 case ICMD_LNEG: /* ..., value ==> ..., - value */
523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
525 M_LSUB(REG_ZERO, s1, d);
526 emit_store_dst(jd, iptr, d);
529 case ICMD_I2L: /* ..., value ==> ..., value */
531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
534 emit_store_dst(jd, iptr, d);
537 case ICMD_L2I: /* ..., value ==> ..., value */
539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
540 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
541 M_ISLL_IMM(s1, 0, d );
542 emit_store_dst(jd, iptr, d);
545 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
549 M_LSLL_IMM(s1, 56, d);
550 M_LSRA_IMM( d, 56, d);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 emit_store_dst(jd, iptr, d);
562 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 M_LSLL_IMM(s1, 48, d);
567 M_LSRA_IMM( d, 48, d);
568 emit_store_dst(jd, iptr, d);
572 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
575 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 emit_store_dst(jd, iptr, d);
582 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
583 /* sx.val.i = constant */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
588 M_IADD_IMM(s1, iptr->sx.val.i, d);
590 ICONST(REG_ITMP2, iptr->sx.val.i);
591 M_IADD(s1, REG_ITMP2, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602 emit_store_dst(jd, iptr, d);
605 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
606 /* sx.val.l = constant */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
611 M_LADD_IMM(s1, iptr->sx.val.l, d);
613 LCONST(REG_ITMP2, iptr->sx.val.l);
614 M_LADD(s1, REG_ITMP2, d);
616 emit_store_dst(jd, iptr, d);
619 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 emit_store_dst(jd, iptr, d);
628 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
629 /* sx.val.i = constant */
631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
633 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
634 M_IADD_IMM(s1, -iptr->sx.val.i, d);
636 ICONST(REG_ITMP2, iptr->sx.val.i);
637 M_ISUB(s1, REG_ITMP2, d);
639 emit_store_dst(jd, iptr, d);
642 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
652 /* sx.val.l = constant */
654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768)) {
657 M_LADD_IMM(s1, -iptr->sx.val.l, d);
659 LCONST(REG_ITMP2, iptr->sx.val.l);
660 M_LSUB(s1, REG_ITMP2, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
674 emit_store_dst(jd, iptr, d);
677 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
678 /* sx.val.i = constant */
680 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
682 ICONST(REG_ITMP2, iptr->sx.val.i);
683 M_IMUL(s1, REG_ITMP2);
687 emit_store_dst(jd, iptr, d);
690 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
692 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
693 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
694 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
699 emit_store_dst(jd, iptr, d);
702 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
703 /* sx.val.l = constant */
705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
707 LCONST(REG_ITMP2, iptr->sx.val.l);
708 M_LMUL(s1, REG_ITMP2);
712 emit_store_dst(jd, iptr, d);
715 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
719 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
725 emit_store_dst(jd, iptr, d);
728 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
738 emit_store_dst(jd, iptr, d);
741 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
743 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
744 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
745 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
751 emit_store_dst(jd, iptr, d);
754 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
757 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764 emit_store_dst(jd, iptr, d);
767 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
768 case ICMD_LDIVPOW2: /* val.i = constant */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 M_LSRA_IMM(s1, 63, REG_ITMP2);
773 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
774 M_LADD(s1, REG_ITMP2, REG_ITMP2);
775 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
776 emit_store_dst(jd, iptr, d);
779 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
780 /* sx.val.i = constant */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785 M_MOV(s1, REG_ITMP1);
788 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
789 M_AND_IMM(s1, iptr->sx.val.i, d);
792 M_ISUB(REG_ZERO, s1, d);
793 M_AND_IMM(d, iptr->sx.val.i, d);
796 ICONST(REG_ITMP2, iptr->sx.val.i);
797 M_AND(s1, REG_ITMP2, d);
800 M_ISUB(REG_ZERO, s1, d);
801 M_AND(d, REG_ITMP2, d);
803 M_ISUB(REG_ZERO, d, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
808 /* sx.val.l = constant */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 M_MOV(s1, REG_ITMP1);
816 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
817 M_AND_IMM(s1, iptr->sx.val.l, d);
820 M_LSUB(REG_ZERO, s1, d);
821 M_AND_IMM(d, iptr->sx.val.l, d);
824 LCONST(REG_ITMP2, iptr->sx.val.l);
825 M_AND(s1, REG_ITMP2, d);
828 M_LSUB(REG_ZERO, s1, d);
829 M_AND(d, REG_ITMP2, d);
831 M_LSUB(REG_ZERO, d, d);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
845 /* sx.val.i = constant */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
849 M_ISLL_IMM(s1, iptr->sx.val.i, d);
850 emit_store_dst(jd, iptr, d);
853 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
856 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 emit_store_dst(jd, iptr, d);
862 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
863 /* sx.val.i = constant */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
867 M_ISRA_IMM(s1, iptr->sx.val.i, d);
868 emit_store_dst(jd, iptr, d);
871 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
873 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
874 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
877 emit_store_dst(jd, iptr, d);
880 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
881 /* sx.val.i = constant */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
885 M_ISRL_IMM(s1, iptr->sx.val.i, d);
886 emit_store_dst(jd, iptr, d);
889 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
892 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
893 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895 emit_store_dst(jd, iptr, d);
898 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
899 /* sx.val.i = constant */
901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
902 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
903 M_LSLL_IMM(s1, iptr->sx.val.i, d);
904 emit_store_dst(jd, iptr, d);
907 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
910 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
911 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913 emit_store_dst(jd, iptr, d);
916 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
917 /* sx.val.i = constant */
919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
920 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
921 M_LSRA_IMM(s1, iptr->sx.val.i, d);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
928 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
929 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
931 emit_store_dst(jd, iptr, d);
934 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
935 /* sx.val.i = constant */
937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
938 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
939 M_LSRL_IMM(s1, iptr->sx.val.i, d);
940 emit_store_dst(jd, iptr, d);
943 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
947 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
948 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
950 emit_store_dst(jd, iptr, d);
953 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
954 /* sx.val.i = constant */
956 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
958 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
959 M_AND_IMM(s1, iptr->sx.val.i, d);
961 ICONST(REG_ITMP2, iptr->sx.val.i);
962 M_AND(s1, REG_ITMP2, d);
964 emit_store_dst(jd, iptr, d);
967 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
968 /* sx.val.l = constant */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
972 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
973 M_AND_IMM(s1, iptr->sx.val.l, d);
975 LCONST(REG_ITMP2, iptr->sx.val.l);
976 M_AND(s1, REG_ITMP2, d);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
992 /* sx.val.i = constant */
994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
996 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
997 M_OR_IMM(s1, iptr->sx.val.i, d);
999 ICONST(REG_ITMP2, iptr->sx.val.i);
1000 M_OR(s1, REG_ITMP2, d);
1002 emit_store_dst(jd, iptr, d);
1005 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1006 /* sx.val.l = constant */
1008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1009 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1010 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1011 M_OR_IMM(s1, iptr->sx.val.l, d);
1013 LCONST(REG_ITMP2, iptr->sx.val.l);
1014 M_OR(s1, REG_ITMP2, d);
1016 emit_store_dst(jd, iptr, d);
1019 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1024 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1030 /* sx.val.i = constant */
1032 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1033 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1034 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1035 M_XOR_IMM(s1, iptr->sx.val.i, d);
1037 ICONST(REG_ITMP2, iptr->sx.val.i);
1038 M_XOR(s1, REG_ITMP2, d);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1044 /* sx.val.l = constant */
1046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1048 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1049 M_XOR_IMM(s1, iptr->sx.val.l, d);
1051 LCONST(REG_ITMP2, iptr->sx.val.l);
1052 M_XOR(s1, REG_ITMP2, d);
1054 emit_store_dst(jd, iptr, d);
1058 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1063 M_CMPLT(s1, s2, REG_ITMP3);
1064 M_CMPLT(s2, s1, REG_ITMP1);
1065 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1066 emit_store_dst(jd, iptr, d);
1070 /* floating operations ************************************************/
1072 case ICMD_FNEG: /* ..., value ==> ..., - value */
1074 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1075 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1077 emit_store_dst(jd, iptr, d);
1080 case ICMD_DNEG: /* ..., value ==> ..., - value */
1082 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1083 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1090 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1091 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1092 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1094 emit_store_dst(jd, iptr, d);
1097 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1099 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1100 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1101 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1103 emit_store_dst(jd, iptr, d);
1106 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1108 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1109 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1110 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1117 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1118 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1119 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1121 emit_store_dst(jd, iptr, d);
1124 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1126 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1127 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1128 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1130 emit_store_dst(jd, iptr, d);
1133 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1135 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1136 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1137 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1139 emit_store_dst(jd, iptr, d);
1142 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1144 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1145 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1146 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1153 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1154 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1157 emit_store_dst(jd, iptr, d);
1161 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1163 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1164 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1166 M_FDIV(s1,s2, REG_FTMP3);
1167 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1168 M_CVTLF(REG_FTMP3, REG_FTMP3);
1169 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1170 M_FSUB(s1, REG_FTMP3, d);
1171 emit_store_dst(jd, iptr, d);
1174 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1176 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1178 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1179 M_DDIV(s1,s2, REG_FTMP3);
1180 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1181 M_CVTLD(REG_FTMP3, REG_FTMP3);
1182 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1183 M_DSUB(s1, REG_FTMP3, d);
1184 emit_store_dst(jd, iptr, d);
1188 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1191 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1194 emit_store_dst(jd, iptr, d);
1197 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1203 emit_store_dst(jd, iptr, d);
1207 /* XXX these do not work correctly */
1209 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1211 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1212 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1213 M_TRUNCFI(s1, REG_FTMP1);
1214 M_MOVDI(REG_FTMP1, d);
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1221 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1222 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1223 M_TRUNCDI(s1, REG_FTMP1);
1224 M_MOVDI(REG_FTMP1, d);
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1231 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1232 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1233 M_TRUNCFL(s1, REG_FTMP1);
1234 M_MOVDL(REG_FTMP1, d);
1236 emit_store_dst(jd, iptr, d);
1239 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1241 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1243 M_TRUNCDL(s1, REG_FTMP1);
1244 M_MOVDL(REG_FTMP1, d);
1246 emit_store_dst(jd, iptr, d);
1250 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1252 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1253 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1255 emit_store_dst(jd, iptr, d);
1258 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1260 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1261 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1268 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1269 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1270 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1273 M_LADD_IMM(REG_ZERO, 1, d);
1277 M_LSUB_IMM(REG_ZERO, 1, d);
1278 M_CMOVT(REG_ZERO, d);
1279 emit_store_dst(jd, iptr, d);
1282 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1284 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1285 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1289 M_LADD_IMM(REG_ZERO, 1, d);
1293 M_LSUB_IMM(REG_ZERO, 1, d);
1294 M_CMOVT(REG_ZERO, d);
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1300 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1301 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1305 M_LSUB_IMM(REG_ZERO, 1, d);
1309 M_LADD_IMM(REG_ZERO, 1, d);
1310 M_CMOVT(REG_ZERO, d);
1311 emit_store_dst(jd, iptr, d);
1314 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1316 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1317 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1318 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1321 M_LSUB_IMM(REG_ZERO, 1, d);
1325 M_LADD_IMM(REG_ZERO, 1, d);
1326 M_CMOVT(REG_ZERO, d);
1327 emit_store_dst(jd, iptr, d);
1331 /* memory operations **************************************************/
1333 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1335 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1337 gen_nullptr_check(s1);
1338 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1347 if (INSTRUCTION_MUST_CHECK(iptr)) {
1348 gen_nullptr_check(s1);
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 if (INSTRUCTION_MUST_CHECK(iptr)) {
1362 gen_nullptr_check(s1);
1365 M_AADD(s2, s1, REG_ITMP3);
1366 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1367 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1368 emit_store_dst(jd, iptr, d);
1371 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1373 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1374 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1376 if (INSTRUCTION_MUST_CHECK(iptr)) {
1377 gen_nullptr_check(s1);
1380 M_AADD(s2, s1, REG_ITMP3);
1381 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1382 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1383 emit_store_dst(jd, iptr, d);
1386 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1388 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1389 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1391 if (INSTRUCTION_MUST_CHECK(iptr)) {
1392 gen_nullptr_check(s1);
1395 M_ASLL_IMM(s2, 2, REG_ITMP3);
1396 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1397 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1398 emit_store_dst(jd, iptr, d);
1401 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1403 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1404 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1406 if (INSTRUCTION_MUST_CHECK(iptr)) {
1407 gen_nullptr_check(s1);
1410 M_ASLL_IMM(s2, 3, REG_ITMP3);
1411 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1412 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_FALOAD: /* ..., 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 if (INSTRUCTION_MUST_CHECK(iptr)) {
1422 gen_nullptr_check(s1);
1425 M_ASLL_IMM(s2, 2, REG_ITMP3);
1426 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1427 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1433 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1434 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1435 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1436 if (INSTRUCTION_MUST_CHECK(iptr)) {
1437 gen_nullptr_check(s1);
1440 M_ASLL_IMM(s2, 3, REG_ITMP3);
1441 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1442 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1443 emit_store_dst(jd, iptr, d);
1446 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1448 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1449 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1450 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1451 if (INSTRUCTION_MUST_CHECK(iptr)) {
1452 gen_nullptr_check(s1);
1455 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1456 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1457 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1458 emit_store_dst(jd, iptr, d);
1462 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1464 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1465 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1466 if (INSTRUCTION_MUST_CHECK(iptr)) {
1467 gen_nullptr_check(s1);
1470 M_AADD(s2, s1, REG_ITMP1);
1471 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1472 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1475 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1476 case ICMD_SASTORE: /* ..., 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 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1486 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1487 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1490 case ICMD_IASTORE: /* ..., 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_ASLL_IMM(s2, 2, REG_ITMP2);
1499 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1500 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1501 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1504 case ICMD_LASTORE: /* ..., 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, 3, REG_ITMP2);
1513 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1514 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1515 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1518 case ICMD_FASTORE: /* ..., 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, 2, REG_ITMP2);
1527 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1528 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1529 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1532 case ICMD_DASTORE: /* ..., 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, 3, REG_ITMP2);
1541 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1542 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1543 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1547 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1550 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1551 if (INSTRUCTION_MUST_CHECK(iptr)) {
1552 gen_nullptr_check(s1);
1555 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1559 disp = dseg_addaddress(cd, BUILTIN_canstore);
1560 M_ALD(REG_ITMP3, REG_PV, disp);
1561 M_JSR(REG_RA, REG_ITMP3);
1564 M_BEQZ(REG_RESULT, 0);
1565 codegen_add_arraystoreexception_ref(cd);
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1570 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1571 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1572 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1573 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1577 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1580 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1581 if (INSTRUCTION_MUST_CHECK(iptr)) {
1582 gen_nullptr_check(s1);
1585 M_AADD(s2, s1, REG_ITMP1);
1586 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1589 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1590 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1594 if (INSTRUCTION_MUST_CHECK(iptr)) {
1595 gen_nullptr_check(s1);
1598 M_AADD(s2, s1, REG_ITMP1);
1599 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1600 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1603 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1607 if (INSTRUCTION_MUST_CHECK(iptr)) {
1608 gen_nullptr_check(s1);
1611 M_ASLL_IMM(s2, 2, REG_ITMP2);
1612 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1613 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1616 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1620 if (INSTRUCTION_MUST_CHECK(iptr)) {
1621 gen_nullptr_check(s1);
1624 M_ASLL_IMM(s2, 3, REG_ITMP2);
1625 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1626 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1629 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1632 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1633 if (INSTRUCTION_MUST_CHECK(iptr)) {
1634 gen_nullptr_check(s1);
1637 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1638 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1639 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1643 case ICMD_GETSTATIC: /* ... ==> ..., value */
1645 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1646 uf = iptr->sx.s23.s3.uf;
1647 fieldtype = uf->fieldref->parseddesc.fd->type;
1648 disp = dseg_addaddress(cd, NULL);
1650 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1652 if (opt_showdisassemble) {
1657 fi = iptr->sx.s23.s3.fmiref->p.field;
1658 fieldtype = fi->type;
1659 disp = dseg_addaddress(cd, &(fi->value));
1661 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1662 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1664 if (opt_showdisassemble) {
1670 M_ALD(REG_ITMP1, REG_PV, disp);
1672 switch (fieldtype) {
1674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1675 M_ILD_INTERN(d, REG_ITMP1, 0);
1678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1679 M_LLD_INTERN(d, REG_ITMP1, 0);
1682 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1683 M_ALD_INTERN(d, REG_ITMP1, 0);
1686 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1687 M_FLD_INTERN(d, REG_ITMP1, 0);
1690 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1691 M_DLD_INTERN(d, REG_ITMP1, 0);
1694 emit_store_dst(jd, iptr, d);
1697 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1699 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1700 uf = iptr->sx.s23.s3.uf;
1701 fieldtype = uf->fieldref->parseddesc.fd->type;
1702 disp = dseg_addaddress(cd, NULL);
1704 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1706 if (opt_showdisassemble) {
1711 fi = iptr->sx.s23.s3.fmiref->p.field;
1712 fieldtype = fi->type;
1713 disp = dseg_addaddress(cd, &(fi->value));
1715 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1716 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1718 if (opt_showdisassemble) {
1724 M_ALD(REG_ITMP1, REG_PV, disp);
1726 switch (fieldtype) {
1728 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1729 M_IST_INTERN(s1, REG_ITMP1, 0);
1732 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1733 M_LST_INTERN(s1, REG_ITMP1, 0);
1736 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1737 M_AST_INTERN(s1, REG_ITMP1, 0);
1740 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1741 M_FST_INTERN(s1, REG_ITMP1, 0);
1744 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1745 M_DST_INTERN(s1, REG_ITMP1, 0);
1750 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1751 /* val = value (in current instruction) */
1752 /* following NOP) */
1754 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1755 uf = iptr->sx.s23.s3.uf;
1756 fieldtype = uf->fieldref->parseddesc.fd->type;
1757 disp = dseg_addaddress(cd, NULL);
1759 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1761 if (opt_showdisassemble) {
1766 fi = iptr->sx.s23.s3.fmiref->p.field;
1767 fieldtype = fi->type;
1768 disp = dseg_addaddress(cd, &(fi->value));
1770 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1771 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1773 if (opt_showdisassemble) {
1779 M_ALD(REG_ITMP1, REG_PV, disp);
1781 switch (fieldtype) {
1783 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1786 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1789 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1792 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1795 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1801 case ICMD_GETFIELD: /* ... ==> ..., value */
1803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1804 gen_nullptr_check(s1);
1806 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1807 uf = iptr->sx.s23.s3.uf;
1808 fieldtype = uf->fieldref->parseddesc.fd->type;
1811 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1813 if (opt_showdisassemble) {
1818 fi = iptr->sx.s23.s3.fmiref->p.field;
1819 fieldtype = fi->type;
1823 switch (fieldtype) {
1825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1837 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1841 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1845 emit_store_dst(jd, iptr, d);
1848 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1850 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1851 gen_nullptr_check(s1);
1853 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1854 uf = iptr->sx.s23.s3.uf;
1855 fieldtype = uf->fieldref->parseddesc.fd->type;
1859 fi = iptr->sx.s23.s3.fmiref->p.field;
1860 fieldtype = fi->type;
1864 if (IS_INT_LNG_TYPE(fieldtype))
1865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1867 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1869 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1870 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1872 if (opt_showdisassemble) {
1877 switch (fieldtype) {
1879 M_IST(s2, s1, disp);
1882 M_LST(s2, s1, disp);
1885 M_AST(s2, s1, disp);
1888 M_FST(s2, s1, disp);
1891 M_DST(s2, s1, disp);
1896 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899 gen_nullptr_check(s1);
1901 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1902 unresolved_field *uf = iptr->sx.s23.s3.uf;
1904 fieldtype = uf->fieldref->parseddesc.fd->type;
1906 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1908 if (opt_showdisassemble) {
1915 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1916 fieldtype = fi->type;
1920 switch (fieldtype) {
1922 M_IST(REG_ZERO, s1, disp);
1925 M_LST(REG_ZERO, s1, disp);
1928 M_AST(REG_ZERO, s1, disp);
1931 M_FST(REG_ZERO, s1, disp);
1934 M_DST(REG_ZERO, s1, disp);
1940 /* branch operations **************************************************/
1942 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1944 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1945 M_INTMOVE(s1, REG_ITMP1_XPTR);
1947 #ifdef ENABLE_VERIFIER
1948 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1949 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1950 iptr->sx.s23.s2.uc, 0);
1952 if (opt_showdisassemble) {
1956 #endif /* ENABLE_VERIFIER */
1958 disp = dseg_addaddress(cd, asm_handle_exception);
1959 M_ALD(REG_ITMP2, REG_PV, disp);
1960 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
1962 M_NOP; /* nop ensures that XPC is less than the end */
1963 /* of basic block */
1967 case ICMD_GOTO: /* ... ==> ... */
1968 case ICMD_RET: /* ... ==> ... */
1971 codegen_addreference(cd, iptr->dst.block);
1976 case ICMD_JSR: /* ... ==> ... */
1979 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
1984 case ICMD_IFNULL: /* ..., value ==> ... */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1988 codegen_addreference(cd, iptr->dst.block);
1992 case ICMD_IFNONNULL: /* ..., value ==> ... */
1994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1996 codegen_addreference(cd, iptr->dst.block);
2000 case ICMD_IFEQ: /* ..., value ==> ... */
2002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2003 if (iptr->sx.val.i == 0) {
2006 ICONST(REG_ITMP2, iptr->sx.val.i);
2007 M_BEQ(s1, REG_ITMP2, 0);
2009 codegen_addreference(cd, iptr->dst.block);
2013 case ICMD_IFLT: /* ..., value ==> ... */
2015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2016 if (iptr->sx.val.i == 0) {
2019 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2020 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2022 ICONST(REG_ITMP2, iptr->sx.val.i);
2023 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2025 M_BNEZ(REG_ITMP1, 0);
2027 codegen_addreference(cd, iptr->dst.block);
2031 case ICMD_IFLE: /* ..., value ==> ... */
2033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2034 if (iptr->sx.val.i == 0) {
2038 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2039 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2040 M_BNEZ(REG_ITMP1, 0);
2043 ICONST(REG_ITMP2, iptr->sx.val.i);
2044 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2045 M_BEQZ(REG_ITMP1, 0);
2048 codegen_addreference(cd, iptr->dst.block);
2052 case ICMD_IFNE: /* ..., value ==> ... */
2054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2055 if (iptr->sx.val.i == 0) {
2059 ICONST(REG_ITMP2, iptr->sx.val.i);
2060 M_BNE(s1, REG_ITMP2, 0);
2062 codegen_addreference(cd, iptr->dst.block);
2066 case ICMD_IFGT: /* ..., value ==> ... */
2068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2069 if (iptr->sx.val.i == 0) {
2073 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2074 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2075 M_BEQZ(REG_ITMP1, 0);
2078 ICONST(REG_ITMP2, iptr->sx.val.i);
2079 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2080 M_BNEZ(REG_ITMP1, 0);
2083 codegen_addreference(cd, iptr->dst.block);
2087 case ICMD_IFGE: /* ..., value ==> ... */
2089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2090 if (iptr->sx.val.i == 0) {
2094 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2095 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2098 ICONST(REG_ITMP2, iptr->sx.val.i);
2099 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2101 M_BEQZ(REG_ITMP1, 0);
2103 codegen_addreference(cd, iptr->dst.block);
2107 case ICMD_IF_LEQ: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 if (iptr->sx.val.l == 0) {
2114 LCONST(REG_ITMP2, iptr->sx.val.l);
2115 M_BEQ(s1, REG_ITMP2, 0);
2117 codegen_addreference(cd, iptr->dst.block);
2121 case ICMD_IF_LLT: /* ..., value ==> ... */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 if (iptr->sx.val.l == 0) {
2128 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2129 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2132 LCONST(REG_ITMP2, iptr->sx.val.l);
2133 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2135 M_BNEZ(REG_ITMP1, 0);
2137 codegen_addreference(cd, iptr->dst.block);
2141 case ICMD_IF_LLE: /* ..., value ==> ... */
2143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 if (iptr->sx.val.l == 0) {
2148 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2149 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2150 M_BNEZ(REG_ITMP1, 0);
2153 LCONST(REG_ITMP2, iptr->sx.val.l);
2154 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2155 M_BEQZ(REG_ITMP1, 0);
2158 codegen_addreference(cd, iptr->dst.block);
2162 case ICMD_IF_LNE: /* ..., value ==> ... */
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 if (iptr->sx.val.l == 0) {
2169 LCONST(REG_ITMP2, iptr->sx.val.l);
2170 M_BNE(s1, REG_ITMP2, 0);
2172 codegen_addreference(cd, iptr->dst.block);
2176 case ICMD_IF_LGT: /* ..., value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 if (iptr->sx.val.l == 0) {
2183 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2184 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2185 M_BEQZ(REG_ITMP1, 0);
2188 LCONST(REG_ITMP2, iptr->sx.val.l);
2189 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2190 M_BNEZ(REG_ITMP1, 0);
2193 codegen_addreference(cd, iptr->dst.block);
2197 case ICMD_IF_LGE: /* ..., value ==> ... */
2199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2200 if (iptr->sx.val.l == 0) {
2204 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2205 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2208 LCONST(REG_ITMP2, iptr->sx.val.l);
2209 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2211 M_BEQZ(REG_ITMP1, 0);
2213 codegen_addreference(cd, iptr->dst.block);
2217 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2218 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2219 case ICMD_IF_ACMPEQ:
2221 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2222 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2224 codegen_addreference(cd, iptr->dst.block);
2228 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2229 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2230 case ICMD_IF_ACMPNE:
2232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2235 codegen_addreference(cd, iptr->dst.block);
2239 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2240 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2242 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2243 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2244 M_CMPLT(s1, s2, REG_ITMP1);
2245 M_BNEZ(REG_ITMP1, 0);
2246 codegen_addreference(cd, iptr->dst.block);
2250 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2251 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2253 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2254 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2255 M_CMPGT(s1, s2, REG_ITMP1);
2256 M_BNEZ(REG_ITMP1, 0);
2257 codegen_addreference(cd, iptr->dst.block);
2261 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2262 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2264 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2265 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2266 M_CMPGT(s1, s2, REG_ITMP1);
2267 M_BEQZ(REG_ITMP1, 0);
2268 codegen_addreference(cd, iptr->dst.block);
2272 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2273 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2275 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2276 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2277 M_CMPLT(s1, s2, REG_ITMP1);
2278 M_BEQZ(REG_ITMP1, 0);
2279 codegen_addreference(cd, iptr->dst.block);
2284 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2287 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2288 M_INTMOVE(s1, REG_RESULT);
2289 goto nowperformreturn;
2291 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2293 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2294 M_INTMOVE(s1, REG_RESULT);
2296 #ifdef ENABLE_VERIFIER
2297 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2298 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2299 iptr->sx.s23.s2.uc, 0);
2301 if (opt_showdisassemble) {
2305 #endif /* ENABLE_VERIFIER */
2306 goto nowperformreturn;
2308 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2310 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2311 M_FLTMOVE(s1, REG_FRESULT);
2312 goto nowperformreturn;
2314 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2316 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2317 M_DBLMOVE(s1, REG_FRESULT);
2318 goto nowperformreturn;
2320 case ICMD_RETURN: /* ... ==> ... */
2326 p = cd->stackframesize;
2328 #if !defined(NDEBUG)
2329 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2330 emit_verbosecall_exit(jd);
2333 #if defined(ENABLE_THREADS)
2334 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2335 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2336 M_ALD(REG_ITMP3, REG_PV, disp);
2338 /* we need to save the proper return value */
2340 switch (iptr->opc) {
2344 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2345 M_JSR(REG_RA, REG_ITMP3);
2346 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2350 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2351 M_JSR(REG_RA, REG_ITMP3);
2352 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2355 M_JSR(REG_RA, REG_ITMP3);
2356 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2360 /* and now restore the proper return value */
2362 switch (iptr->opc) {
2366 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2370 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2376 /* restore return address */
2378 if (!jd->isleafmethod) {
2379 p--; M_ALD(REG_RA, REG_SP, p * 8);
2382 /* restore saved registers */
2384 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2385 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2387 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2388 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2391 /* deallocate stack and return */
2393 if (cd->stackframesize) {
2396 disp = cd->stackframesize * 8;
2397 lo = (short) (disp);
2398 hi = (short) (((disp) - lo) >> 16);
2402 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2404 M_LUI(REG_ITMP3,hi);
2405 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2407 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2420 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2423 branch_target_t *table;
2425 table = iptr->dst.table;
2427 l = iptr->sx.s23.s2.tablelow;
2428 i = iptr->sx.s23.s3.tablehigh;
2430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2432 {M_INTMOVE(s1, REG_ITMP1);}
2433 else if (l <= 32768) {
2434 M_IADD_IMM(s1, -l, REG_ITMP1);
2437 ICONST(REG_ITMP2, l);
2438 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2441 /* number of targets */
2446 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2447 M_BEQZ(REG_ITMP2, 0);
2448 codegen_addreference(cd, table[0].block); /* default target */
2449 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2451 /* build jump table top down and use address of lowest entry */
2456 dseg_addtarget(cd, table->block);
2461 /* length of dataseg after last dseg_addtarget is used by load */
2463 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2464 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2471 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2474 lookup_target_t *lookup;
2476 lookup = iptr->dst.lookup;
2478 i = iptr->sx.s23.s2.lookupcount;
2480 MCODECHECK((i<<2)+8);
2481 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2484 ICONST(REG_ITMP2, lookup->value);
2485 M_BEQ(s1, REG_ITMP2, 0);
2486 codegen_addreference(cd, lookup->target.block);
2492 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2499 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2501 bte = iptr->sx.s23.s3.bte;
2505 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2507 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2508 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2509 case ICMD_INVOKEINTERFACE:
2511 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2513 um = iptr->sx.s23.s3.um;
2514 md = um->methodref->parseddesc.md;
2517 lm = iptr->sx.s23.s3.fmiref->p.method;
2519 md = lm->parseddesc;
2523 s3 = md->paramcount;
2525 MCODECHECK((s3 << 1) + 64);
2527 /* copy arguments to registers or stack location */
2529 for (s3 = s3 - 1; s3 >= 0; s3--) {
2530 var = VAR(iptr->sx.s23.s2.args[s3]);
2532 if (var->flags & PREALLOC)
2535 if (IS_INT_LNG_TYPE(var->type)) {
2536 if (!md->params[s3].inmemory) {
2537 s1 = rd->argintregs[md->params[s3].regoff];
2538 d = emit_load(jd, iptr, var, s1);
2542 d = emit_load(jd, iptr, var, REG_ITMP1);
2543 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2547 if (!md->params[s3].inmemory) {
2548 s1 = rd->argfltregs[md->params[s3].regoff];
2549 d = emit_load(jd, iptr, var, s1);
2550 if (IS_2_WORD_TYPE(var->type))
2556 d = emit_load(jd, iptr, var, REG_FTMP1);
2557 if (IS_2_WORD_TYPE(var->type))
2558 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2560 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2565 switch (iptr->opc) {
2567 disp = dseg_addaddress(cd, bte->fp);
2569 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2571 /* TWISTI: i actually don't know the reason for using
2572 REG_ITMP3 here instead of REG_PV. */
2576 case ICMD_INVOKESPECIAL:
2578 codegen_add_nullpointerexception_ref(cd);
2582 case ICMD_INVOKESTATIC:
2584 disp = dseg_addaddress(cd, NULL);
2586 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2589 if (opt_showdisassemble) {
2594 disp = dseg_addaddress(cd, lm->stubroutine);
2596 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2600 case ICMD_INVOKEVIRTUAL:
2601 gen_nullptr_check(REG_A0);
2604 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2606 if (opt_showdisassemble) {
2613 s1 = OFFSET(vftbl_t, table[0]) +
2614 sizeof(methodptr) * lm->vftblindex;
2616 M_ALD(REG_METHODPTR, REG_A0,
2617 OFFSET(java_objectheader, vftbl));
2618 M_ALD(REG_PV, REG_METHODPTR, s1);
2622 case ICMD_INVOKEINTERFACE:
2623 gen_nullptr_check(REG_A0);
2626 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2628 if (opt_showdisassemble) {
2636 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2637 sizeof(methodptr*) * lm->class->index;
2639 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2642 M_ALD(REG_METHODPTR, REG_A0,
2643 OFFSET(java_objectheader, vftbl));
2644 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2645 M_ALD(REG_PV, REG_METHODPTR, s2);
2650 /* generate the actual call */
2654 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2655 M_LDA(REG_PV, REG_RA, -disp);
2657 /* actually only used for ICMD_BUILTIN */
2659 if (INSTRUCTION_MUST_CHECK(iptr)) {
2660 M_BEQZ(REG_RESULT, 0);
2661 codegen_add_fillinstacktrace_ref(cd);
2665 /* store return value */
2667 d = md->returntype.type;
2669 if (d != TYPE_VOID) {
2670 if (IS_INT_LNG_TYPE(d)) {
2671 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2672 M_INTMOVE(REG_RESULT, s1);
2675 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2676 if (IS_2_WORD_TYPE(d))
2677 M_DMOV(REG_FRESULT, s1);
2679 M_FMOV(REG_FRESULT, s1);
2681 emit_store_dst(jd, iptr, s1);
2686 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2687 /* val.a: (classinfo*) superclass */
2689 /* superclass is an interface:
2691 * OK if ((sub == NULL) ||
2692 * (sub->vftbl->interfacetablelength > super->index) &&
2693 * (sub->vftbl->interfacetable[-super->index] != NULL));
2695 * superclass is a class:
2697 * OK if ((sub == NULL) || (0
2698 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2699 * super->vftbl->diffvall));
2702 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2704 vftbl_t *supervftbl;
2707 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2713 super = iptr->sx.s23.s3.c.cls;
2714 superindex = super->index;
2715 supervftbl = super->vftbl;
2718 #if defined(ENABLE_THREADS)
2719 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2724 /* calculate interface checkcast code size */
2728 s2 += (opt_showdisassemble ? 2 : 0);
2730 /* calculate class checkcast code size */
2732 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2734 s3 += (opt_showdisassemble ? 2 : 0);
2736 /* if class is not resolved, check which code to call */
2738 if (super == NULL) {
2739 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2742 disp = dseg_adds4(cd, 0); /* super->flags */
2744 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2745 iptr->sx.s23.s3.c.ref,
2748 if (opt_showdisassemble) {
2752 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2753 M_ILD(REG_ITMP2, REG_PV, disp);
2754 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2755 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2759 /* interface checkcast code */
2761 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2762 if (super != NULL) {
2767 codegen_addpatchref(cd,
2768 PATCHER_checkcast_instanceof_interface,
2769 iptr->sx.s23.s3.c.ref,
2772 if (opt_showdisassemble) {
2777 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2778 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2779 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2780 M_BLEZ(REG_ITMP3, 0);
2781 codegen_add_classcastexception_ref(cd, s1);
2783 M_ALD(REG_ITMP3, REG_ITMP2,
2784 OFFSET(vftbl_t, interfacetable[0]) -
2785 superindex * sizeof(methodptr*));
2786 M_BEQZ(REG_ITMP3, 0);
2787 codegen_add_classcastexception_ref(cd, s1);
2790 if (super == NULL) {
2796 /* class checkcast code */
2798 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2799 disp = dseg_addaddress(cd, (void *) supervftbl);
2801 if (super != NULL) {
2806 codegen_addpatchref(cd,
2807 PATCHER_checkcast_instanceof_class,
2808 iptr->sx.s23.s3.c.ref,
2811 if (opt_showdisassemble) {
2816 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2817 M_ALD(REG_ITMP3, REG_PV, disp);
2818 #if defined(ENABLE_THREADS)
2819 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2821 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2822 /* if (s1 != REG_ITMP1) { */
2823 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2824 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2825 /* #if defined(ENABLE_THREADS) */
2826 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2828 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2830 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2831 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2832 M_ALD(REG_ITMP3, REG_PV, disp);
2833 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2834 #if defined(ENABLE_THREADS)
2835 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2838 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2839 M_BNEZ(REG_ITMP3, 0);
2840 codegen_add_classcastexception_ref(cd, s1);
2844 d = codegen_reg_of_dst(jd, iptr, s1);
2847 s1 = emit_load_s1(jd, iptr, REG_A0);
2848 M_INTMOVE(s1, REG_A0);
2850 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
2852 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2853 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2854 iptr->sx.s23.s3.c.ref,
2857 if (opt_showdisassemble) {
2862 M_ALD(REG_A1, REG_PV, disp);
2863 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
2864 M_ALD(REG_ITMP3, REG_PV, disp);
2865 M_JSR(REG_RA, REG_ITMP3);
2868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2869 M_BEQZ(REG_RESULT, 0);
2870 codegen_add_classcastexception_ref(cd, s1);
2873 d = codegen_reg_of_dst(jd, iptr, s1);
2877 emit_store_dst(jd, iptr, d);
2880 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2881 /* val.a: (classinfo*) superclass */
2883 /* superclass is an interface:
2885 * return (sub != NULL) &&
2886 * (sub->vftbl->interfacetablelength > super->index) &&
2887 * (sub->vftbl->interfacetable[-super->index] != NULL);
2889 * superclass is a class:
2891 * return ((sub != NULL) && (0
2892 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2893 * super->vftbl->diffvall));
2898 vftbl_t *supervftbl;
2901 super = iptr->sx.s23.s3.c.cls;
2903 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2909 super = iptr->sx.s23.s3.c.cls;
2910 superindex = super->index;
2911 supervftbl = super->vftbl;
2914 #if defined(ENABLE_THREADS)
2915 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2921 M_MOV(s1, REG_ITMP1);
2925 /* calculate interface instanceof code size */
2929 s2 += (opt_showdisassemble ? 2 : 0);
2931 /* calculate class instanceof code size */
2935 s3 += (opt_showdisassemble ? 2 : 0);
2939 /* if class is not resolved, check which code to call */
2941 if (super == NULL) {
2942 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2945 disp = dseg_adds4(cd, 0); /* super->flags */
2947 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2948 iptr->sx.s23.s3.c.ref, disp);
2950 if (opt_showdisassemble) {
2954 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2955 M_ILD(REG_ITMP3, REG_PV, disp);
2956 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2957 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
2961 /* interface instanceof code */
2963 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2964 if (super != NULL) {
2969 codegen_addpatchref(cd,
2970 PATCHER_checkcast_instanceof_interface,
2971 iptr->sx.s23.s3.c.ref, 0);
2973 if (opt_showdisassemble) {
2978 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2979 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2980 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2981 M_BLEZ(REG_ITMP3, 3);
2983 M_ALD(REG_ITMP1, REG_ITMP1,
2984 OFFSET(vftbl_t, interfacetable[0]) -
2985 superindex * sizeof(methodptr*));
2986 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2988 if (super == NULL) {
2994 /* class instanceof code */
2996 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2997 disp = dseg_addaddress(cd, supervftbl);
2999 if (super != NULL) {
3004 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3005 iptr->sx.s23.s3.c.ref,
3008 if (opt_showdisassemble) {
3013 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3014 M_ALD(REG_ITMP2, REG_PV, disp);
3015 #if defined(ENABLE_THREADS)
3016 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3018 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3019 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3020 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3021 #if defined(ENABLE_THREADS)
3022 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3024 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3025 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3028 emit_store_dst(jd, iptr, d);
3032 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3034 /* check for negative sizes and copy sizes to stack if necessary */
3036 MCODECHECK((iptr->s1.argcount << 1) + 64);
3038 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3040 var = VAR(iptr->sx.s23.s2.args[s1]);
3042 /* copy SAVEDVAR sizes to stack */
3044 if (!(var->flags & PREALLOC)) {
3045 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3046 M_LST(s2, REG_SP, s1 * 8);
3050 /* a0 = dimension count */
3052 ICONST(REG_A0, iptr->s1.argcount);
3054 /* is patcher function set? */
3056 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3057 disp = dseg_addaddress(cd, NULL);
3059 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3060 iptr->sx.s23.s3.c.ref, disp);
3062 if (opt_showdisassemble) {
3067 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3070 /* a1 = arraydescriptor */
3072 M_ALD(REG_A1, REG_PV, disp);
3074 /* a2 = pointer to dimensions = stack pointer */
3076 M_INTMOVE(REG_SP, REG_A2);
3078 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3079 M_ALD(REG_ITMP3, REG_PV, disp);
3080 M_JSR(REG_RA, REG_ITMP3);
3083 /* check for exception before result assignment */
3085 M_BEQZ(REG_RESULT, 0);
3086 codegen_add_fillinstacktrace_ref(cd);
3089 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3090 M_INTMOVE(REG_RESULT, d);
3091 emit_store_dst(jd, iptr, d);
3095 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3099 } /* for instruction */
3101 MCODECHECK(64); /* XXX require smaller number? */
3103 /* At the end of a basic block we may have to append some nops,
3104 because the patcher stub calling code might be longer than the
3105 actual instruction. So codepatching does not change the
3106 following block unintentionally. */
3108 if (cd->mcodeptr < cd->lastmcodeptr) {
3109 while (cd->mcodeptr < cd->lastmcodeptr)
3113 } /* if (bptr -> flags >= BBREACHED) */
3114 } /* for basic block */
3116 dseg_createlinenumbertable(cd);
3118 /* generate exception and patcher stubs */
3120 emit_exception_stubs(jd);
3121 emit_patcher_stubs(jd);
3124 emit_replacement_stubs(jd);
3129 /* everything's ok */
3135 /* createcompilerstub **********************************************************
3137 Creates a stub routine which calls the compiler.
3139 *******************************************************************************/
3141 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3142 #define COMPILERSTUB_CODESIZE 4 * 4
3144 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3147 u1 *createcompilerstub(methodinfo *m)
3149 u1 *s; /* memory to hold the stub */
3155 s = CNEW(u1, COMPILERSTUB_SIZE);
3157 /* set data pointer and code pointer */
3160 s = s + COMPILERSTUB_DATASIZE;
3162 /* mark start of dump memory area */
3164 dumpsize = dump_size();
3166 cd = DNEW(codegendata);
3169 /* Store the codeinfo pointer in the same place as in the
3170 methodheader for compiled methods. */
3172 code = code_codeinfo_new(m);
3174 d[0] = (ptrint) asm_call_jit_compiler;
3176 d[2] = (ptrint) code;
3178 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3179 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3183 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3185 #if defined(ENABLE_STATISTICS)
3187 count_cstub_len += COMPILERSTUB_SIZE;
3190 /* release dump area */
3192 dump_release(dumpsize);
3198 /* createnativestub ************************************************************
3200 Creates a stub routine which calls a native method.
3202 *******************************************************************************/
3204 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3212 s4 i, j; /* count variables */
3215 s4 funcdisp; /* displacement of the function */
3217 /* get required compiler data */
3224 /* initialize variables */
3227 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3229 /* calculate stack frame size */
3231 cd->stackframesize =
3232 1 + /* return address */
3233 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3234 sizeof(localref_table) / SIZEOF_VOID_P +
3235 md->paramcount + /* for saving arguments over calls */
3236 1 + /* for saving return address */
3239 /* create method header */
3241 #if SIZEOF_VOID_P == 4
3242 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3244 (void) dseg_addaddress(cd, code); /* MethodPointer */
3245 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3246 (void) dseg_adds4(cd, 0); /* IsSync */
3247 (void) dseg_adds4(cd, 0); /* IsLeaf */
3248 (void) dseg_adds4(cd, 0); /* IntSave */
3249 (void) dseg_adds4(cd, 0); /* FltSave */
3250 (void) dseg_addlinenumbertablesize(cd);
3251 (void) dseg_adds4(cd, 0); /* ExTableSize */
3253 /* generate stub code */
3255 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3256 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3258 #if !defined(NDEBUG)
3259 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3260 emit_verbosecall_enter(jd);
3263 /* get function address (this must happen before the stackframeinfo) */
3265 funcdisp = dseg_addaddress(cd, f);
3267 #if !defined(WITH_STATIC_CLASSPATH)
3269 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3271 if (opt_showdisassemble) {
3277 /* save integer and float argument registers */
3279 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3280 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3281 M_LST(rd->argintregs[i], REG_SP, j * 8);
3286 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3287 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3288 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3293 /* prepare data structures for native function call */
3295 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3296 M_MOV(REG_PV, REG_A1);
3297 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3298 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3299 disp = dseg_addaddress(cd, codegen_start_native_call);
3300 M_ALD(REG_ITMP3, REG_PV, disp);
3301 M_JSR(REG_RA, REG_ITMP3);
3302 M_NOP; /* XXX fill me! */
3304 /* restore integer and float argument registers */
3306 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3307 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3308 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3313 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3314 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3315 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3320 /* copy or spill arguments to new locations */
3322 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3323 t = md->paramtypes[i].type;
3325 if (IS_INT_LNG_TYPE(t)) {
3326 if (!md->params[i].inmemory) {
3327 s1 = rd->argintregs[md->params[i].regoff];
3329 if (!nmd->params[j].inmemory) {
3330 s2 = rd->argintregs[nmd->params[j].regoff];
3333 s2 = nmd->params[j].regoff;
3334 M_AST(s1, REG_SP, s2 * 8);
3338 s1 = md->params[i].regoff + cd->stackframesize;
3339 s2 = nmd->params[j].regoff;
3340 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3341 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3345 if (!md->params[i].inmemory) {
3346 s1 = rd->argfltregs[md->params[i].regoff];
3348 if (!nmd->params[j].inmemory) {
3349 s2 = rd->argfltregs[nmd->params[j].regoff];
3350 if (IS_2_WORD_TYPE(t))
3356 s2 = nmd->params[j].regoff;
3357 if (IS_2_WORD_TYPE(t))
3358 M_DST(s1, REG_SP, s2 * 8);
3360 M_FST(s1, REG_SP, s2 * 8);
3364 s1 = md->params[i].regoff + cd->stackframesize;
3365 s2 = nmd->params[j].regoff;
3366 if (IS_2_WORD_TYPE(t)) {
3367 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3368 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3370 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3371 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3377 /* put class into second argument register */
3379 if (m->flags & ACC_STATIC) {
3380 disp = dseg_addaddress(cd, m->class);
3381 M_ALD(REG_A1, REG_PV, disp);
3384 /* put env into first argument register */
3386 disp = dseg_addaddress(cd, _Jv_env);
3387 M_ALD(REG_A0, REG_PV, disp);
3389 /* do the native function call */
3391 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3392 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3393 M_NOP; /* delay slot */
3395 /* save return value */
3397 if (md->returntype.type != TYPE_VOID) {
3398 if (IS_INT_LNG_TYPE(md->returntype.type))
3399 M_LST(REG_RESULT, REG_SP, 0 * 8);
3401 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3404 #if !defined(NDEBUG)
3405 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3406 emit_verbosecall_exit(jd);
3409 /* remove native stackframe info */
3411 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3412 disp = dseg_addaddress(cd, codegen_finish_native_call);
3413 M_ALD(REG_ITMP3, REG_PV, disp);
3414 M_JSR(REG_RA, REG_ITMP3);
3415 M_NOP; /* XXX fill me! */
3416 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3418 /* restore return value */
3420 if (md->returntype.type != TYPE_VOID) {
3421 if (IS_INT_LNG_TYPE(md->returntype.type))
3422 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3424 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3427 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3429 /* check for exception */
3431 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3432 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3434 M_RET(REG_RA); /* return to caller */
3435 M_NOP; /* DELAY SLOT */
3437 /* handle exception */
3439 disp = dseg_addaddress(cd, asm_handle_nat_exception);
3440 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3441 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3442 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3444 /* generate patcher stubs */
3446 emit_patcher_stubs(jd);
3450 return code->entrypoint;
3455 * These are local overrides for various environment variables in Emacs.
3456 * Please do not remove this and leave it at the end of the file, where
3457 * Emacs will automagically detect them.
3458 * ---------------------------------------------------------------------
3461 * indent-tabs-mode: t
3465 * vim:noexpandtab:sw=4:ts=4: