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
33 Contains the codegenerator for an MIPS (R4000 or higher) processor.
34 This module generates MIPS machine code for a sequence of
35 intermediate code commands (ICMDs).
37 $Id: codegen.c 6180 2006-12-11 23:29:26Z twisti $
51 #include "vm/jit/mips/arch.h"
52 #include "vm/jit/mips/codegen.h"
54 #include "native/native.h"
56 #if defined(ENABLE_THREADS)
57 # include "threads/native/lock.h"
60 #include "vm/builtin.h"
62 #include "vm/exceptions.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/codegen-common.h"
68 #include "vm/jit/dseg.h"
69 #include "vm/jit/emit-common.h"
70 #include "vm/jit/jit.h"
71 #include "vm/jit/patcher.h"
72 #include "vm/jit/reg.h"
73 #include "vm/jit/replace.h"
75 #if defined(ENABLE_LSRA)
76 # include "vm/jit/allocator/lsra.h"
80 /* codegen *********************************************************************
82 Generates machine code.
84 *******************************************************************************/
86 bool codegen(jitdata *jd)
92 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
106 rplpoint *replacementpoint;
110 /* get required compiler data */
117 /* prevent compiler warnings */
130 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
132 /* space to save used callee saved registers */
134 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
135 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
137 cd->stackframesize = rd->memuse + savedregs_num;
139 #if defined(ENABLE_THREADS)
140 /* space to save argument of monitor_enter */
142 if (checksync && (m->flags & ACC_SYNCHRONIZED))
143 cd->stackframesize++;
146 /* keep stack 16-byte aligned */
148 if (cd->stackframesize & 1)
149 cd->stackframesize++;
151 /* create method header */
153 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
154 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
156 #if defined(ENABLE_THREADS)
157 /* IsSync contains the offset relative to the stack pointer for the
158 argument of monitor_exit used in the exception handler. Since the
159 offset could be zero and give a wrong meaning of the flag it is
163 if (checksync && (m->flags & ACC_SYNCHRONIZED))
164 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
167 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
169 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
170 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
171 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
172 dseg_addlinenumbertablesize(cd);
173 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
175 /* create exception table */
177 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
178 dseg_add_target(cd, ex->start);
179 dseg_add_target(cd, ex->end);
180 dseg_add_target(cd, ex->handler);
181 (void) dseg_add_unique_address(cd, ex->catchtype.any);
184 /* create stack frame (if necessary) */
186 if (cd->stackframesize)
187 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
189 /* save return address and used callee saved registers */
191 p = cd->stackframesize;
192 if (!jd->isleafmethod) {
193 p--; M_AST(REG_RA, REG_SP, p * 8);
195 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
196 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
198 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
199 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
202 /* take arguments out of register or stack frame */
206 for (p = 0, l = 0; p < md->paramcount; p++) {
207 t = md->paramtypes[p].type;
209 varindex = jd->local_map[l * 5 + t];
212 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
215 if (varindex == UNUSED)
220 s1 = md->params[p].regoff;
221 if (IS_INT_LNG_TYPE(t)) { /* integer args */
222 if (!md->params[p].inmemory) { /* register arguments */
223 s2 = rd->argintregs[s1];
224 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
225 M_INTMOVE(s2, var->vv.regoff);
226 } else { /* reg arg -> spilled */
227 M_LST(s2, REG_SP, var->vv.regoff * 8);
230 } else { /* stack arguments */
231 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
232 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
233 } else { /* stack arg -> spilled */
234 var->vv.regoff = cd->stackframesize + s1;
238 } else { /* floating args */
239 if (!md->params[p].inmemory) { /* register arguments */
240 s2 = rd->argfltregs[s1];
241 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
242 if (IS_2_WORD_TYPE(t))
243 M_DMOV(s2, var->vv.regoff);
245 M_FMOV(s2, var->vv.regoff);
246 } else { /* reg arg -> spilled */
247 if (IS_2_WORD_TYPE(t))
248 M_DST(s2, REG_SP, var->vv.regoff * 8);
250 M_FST(s2, REG_SP, var->vv.regoff * 8);
253 } else { /* stack arguments */
254 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
255 if (IS_2_WORD_TYPE(t))
256 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
258 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
259 } else /* stack-arg -> spilled */
260 var->vv.regoff = cd->stackframesize + s1;
265 /* call monitorenter function */
267 #if defined(ENABLE_THREADS)
268 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
269 /* stack offset for monitor argument */
273 # if !defined(NDEBUG)
274 if (opt_verbosecall) {
275 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
277 for (p = 0; p < INT_ARG_CNT; p++)
278 M_LST(rd->argintregs[p], REG_SP, p * 8);
280 for (p = 0; p < FLT_ARG_CNT; p++)
281 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
283 s1 += INT_ARG_CNT + FLT_ARG_CNT;
287 /* get correct lock object */
289 if (m->flags & ACC_STATIC) {
290 disp = dseg_add_address(cd, &m->class->object.header);
291 M_ALD(REG_A0, REG_PV, disp);
294 /* emit_nullpointer_check(cd, iptr, REG_A0); */
299 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
300 codegen_add_nullpointerexception_ref(cd);
301 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
306 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
307 M_ALD(REG_ITMP3, REG_PV, disp);
308 M_JSR(REG_RA, REG_ITMP3);
309 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
311 # if !defined(NDEBUG)
312 if (opt_verbosecall) {
313 for (p = 0; p < INT_ARG_CNT; p++)
314 M_LLD(rd->argintregs[p], REG_SP, p * 8);
316 for (p = 0; p < FLT_ARG_CNT; p++)
317 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
320 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
327 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
328 emit_verbosecall_enter(jd);
333 /* end of header generation */
335 replacementpoint = jd->code->rplpoints;
337 /* walk through all basic blocks */
339 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
341 /* handle replacement points */
344 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
346 /* 8-byte align pc */
347 if ((ptrint) cd->mcodeptr & 4) {
351 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
354 assert(cd->lastmcodeptr <= cd->mcodeptr);
355 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
359 /* store relative start of block */
361 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
363 if (bptr->flags >= BBREACHED) {
364 /* branch resolving */
366 codegen_resolve_branchrefs(cd, bptr);
368 /* copy interface registers to their destination */
372 #if defined(ENABLE_LSRA)
376 src = bptr->invars[len];
377 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
378 /* d = reg_of_var(m, src, REG_ITMP1); */
379 if (!(src->flags & INMEMORY))
383 M_INTMOVE(REG_ITMP1, d);
384 emit_store(jd, NULL, src, d);
391 var = VAR(bptr->invars[len]);
392 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
393 d = codegen_reg_of_var(0, var, REG_ITMP1);
394 M_INTMOVE(REG_ITMP1, d);
395 emit_store(jd, NULL, var, d);
398 assert((var->flags & INOUT));
401 #if defined(ENABLE_LSRA)
404 /* walk through all instructions */
409 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
410 if (iptr->line != currentline) {
411 dseg_addlinenumber(cd, iptr->line);
412 currentline = iptr->line;
415 MCODECHECK(64); /* an instruction usually needs < 64 words */
419 case ICMD_NOP: /* ... ==> ... */
420 case ICMD_POP: /* ..., value ==> ... */
421 case ICMD_POP2: /* ..., value, value ==> ... */
427 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
430 emit_nullpointer_check(cd, iptr, s1);
433 /* constant operations ************************************************/
435 case ICMD_ICONST: /* ... ==> ..., constant */
437 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
438 ICONST(d, iptr->sx.val.i);
439 emit_store_dst(jd, iptr, d);
442 case ICMD_LCONST: /* ... ==> ..., constant */
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
445 LCONST(d, iptr->sx.val.l);
446 emit_store_dst(jd, iptr, d);
449 case ICMD_FCONST: /* ... ==> ..., constant */
451 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
452 disp = dseg_add_float(cd, iptr->sx.val.f);
453 M_FLD(d, REG_PV, disp);
454 emit_store_dst(jd, iptr, d);
457 case ICMD_DCONST: /* ... ==> ..., constant */
459 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
460 disp = dseg_add_double(cd, iptr->sx.val.d);
461 M_DLD(d, REG_PV, disp);
462 emit_store_dst(jd, iptr, d);
465 case ICMD_ACONST: /* ... ==> ..., constant */
467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
469 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
470 cr = iptr->sx.val.c.ref;
471 disp = dseg_add_unique_address(cd, cr);
473 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
475 M_ALD(d, REG_PV, disp);
478 if (iptr->sx.val.anyptr == NULL)
479 M_INTMOVE(REG_ZERO, d);
481 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
482 M_ALD(d, REG_PV, disp);
485 emit_store_dst(jd, iptr, d);
489 /* load/store/copy/move operations ************************************/
491 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
492 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
493 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
494 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
495 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
496 case ICMD_ISTORE: /* ..., value ==> ... */
497 case ICMD_LSTORE: /* ..., value ==> ... */
498 case ICMD_FSTORE: /* ..., value ==> ... */
499 case ICMD_DSTORE: /* ..., value ==> ... */
503 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
507 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
508 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
512 /* integer operations *************************************************/
514 case ICMD_INEG: /* ..., value ==> ..., - value */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
518 M_ISUB(REG_ZERO, s1, d);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_LNEG: /* ..., value ==> ..., - value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
526 M_LSUB(REG_ZERO, s1, d);
527 emit_store_dst(jd, iptr, d);
530 case ICMD_I2L: /* ..., value ==> ..., value */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
535 emit_store_dst(jd, iptr, d);
538 case ICMD_L2I: /* ..., value ==> ..., value */
540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
542 M_ISLL_IMM(s1, 0, d );
543 emit_store_dst(jd, iptr, d);
546 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550 M_LSLL_IMM(s1, 56, d);
551 M_LSRA_IMM( d, 56, d);
552 emit_store_dst(jd, iptr, d);
555 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
560 emit_store_dst(jd, iptr, d);
563 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
567 M_LSLL_IMM(s1, 48, d);
568 M_LSRA_IMM( d, 48, d);
569 emit_store_dst(jd, iptr, d);
573 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
579 emit_store_dst(jd, iptr, d);
583 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
584 /* sx.val.i = constant */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
588 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
589 M_IADD_IMM(s1, iptr->sx.val.i, d);
591 ICONST(REG_ITMP2, iptr->sx.val.i);
592 M_IADD(s1, REG_ITMP2, d);
594 emit_store_dst(jd, iptr, d);
597 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
607 /* sx.val.l = constant */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
612 M_LADD_IMM(s1, iptr->sx.val.l, d);
614 LCONST(REG_ITMP2, iptr->sx.val.l);
615 M_LADD(s1, REG_ITMP2, d);
617 emit_store_dst(jd, iptr, d);
620 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
630 /* sx.val.i = constant */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
635 M_IADD_IMM(s1, -iptr->sx.val.i, d);
637 ICONST(REG_ITMP2, iptr->sx.val.i);
638 M_ISUB(s1, REG_ITMP2, d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649 emit_store_dst(jd, iptr, d);
652 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
653 /* sx.val.l = constant */
655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
658 M_LADD_IMM(s1, -iptr->sx.val.l, d);
660 LCONST(REG_ITMP2, iptr->sx.val.l);
661 M_LSUB(s1, REG_ITMP2, d);
663 emit_store_dst(jd, iptr, d);
666 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
675 emit_store_dst(jd, iptr, d);
678 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
679 /* sx.val.i = constant */
681 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
682 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
683 ICONST(REG_ITMP2, iptr->sx.val.i);
684 M_IMUL(s1, REG_ITMP2);
688 emit_store_dst(jd, iptr, d);
691 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 emit_store_dst(jd, iptr, d);
703 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
704 /* sx.val.l = constant */
706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
708 LCONST(REG_ITMP2, iptr->sx.val.l);
709 M_LMUL(s1, REG_ITMP2);
713 emit_store_dst(jd, iptr, d);
716 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
719 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
721 emit_arithmetic_check(cd, iptr, s2);
726 emit_store_dst(jd, iptr, d);
729 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
734 emit_arithmetic_check(cd, iptr, s2);
739 emit_store_dst(jd, iptr, d);
742 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
745 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
747 emit_arithmetic_check(cd, iptr, s2);
752 emit_store_dst(jd, iptr, d);
755 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
757 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
758 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
760 emit_arithmetic_check(cd, iptr, s2);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
769 case ICMD_LDIVPOW2: /* val.i = constant */
771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
773 M_LSRA_IMM(s1, 63, REG_ITMP2);
774 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
775 M_LADD(s1, REG_ITMP2, REG_ITMP2);
776 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
777 emit_store_dst(jd, iptr, d);
780 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
781 /* sx.val.i = constant */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
786 M_MOV(s1, REG_ITMP1);
789 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
790 M_AND_IMM(s1, iptr->sx.val.i, d);
793 M_ISUB(REG_ZERO, s1, d);
794 M_AND_IMM(d, iptr->sx.val.i, d);
797 ICONST(REG_ITMP2, iptr->sx.val.i);
798 M_AND(s1, REG_ITMP2, d);
801 M_ISUB(REG_ZERO, s1, d);
802 M_AND(d, REG_ITMP2, d);
804 M_ISUB(REG_ZERO, d, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
809 /* sx.val.l = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814 M_MOV(s1, REG_ITMP1);
817 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
818 M_AND_IMM(s1, iptr->sx.val.l, d);
821 M_LSUB(REG_ZERO, s1, d);
822 M_AND_IMM(d, iptr->sx.val.l, d);
825 LCONST(REG_ITMP2, iptr->sx.val.l);
826 M_AND(s1, REG_ITMP2, d);
829 M_LSUB(REG_ZERO, s1, d);
830 M_AND(d, REG_ITMP2, d);
832 M_LSUB(REG_ZERO, d, d);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
846 /* sx.val.i = constant */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 M_ISLL_IMM(s1, iptr->sx.val.i, d);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
864 /* sx.val.i = constant */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 M_ISRA_IMM(s1, iptr->sx.val.i, d);
869 emit_store_dst(jd, iptr, d);
872 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
875 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
882 /* sx.val.i = constant */
884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
886 M_ISRL_IMM(s1, iptr->sx.val.i, d);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
892 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
893 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896 emit_store_dst(jd, iptr, d);
899 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
900 /* sx.val.i = constant */
902 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
903 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
904 M_LSLL_IMM(s1, iptr->sx.val.i, d);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
918 /* sx.val.i = constant */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
922 M_LSRA_IMM(s1, iptr->sx.val.i, d);
923 emit_store_dst(jd, iptr, d);
926 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
929 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
930 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932 emit_store_dst(jd, iptr, d);
935 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
936 /* sx.val.i = constant */
938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
939 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
940 M_LSRL_IMM(s1, iptr->sx.val.i, d);
941 emit_store_dst(jd, iptr, d);
944 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
948 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951 emit_store_dst(jd, iptr, d);
954 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
955 /* sx.val.i = constant */
957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
958 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
959 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
960 M_AND_IMM(s1, iptr->sx.val.i, d);
962 ICONST(REG_ITMP2, iptr->sx.val.i);
963 M_AND(s1, REG_ITMP2, d);
965 emit_store_dst(jd, iptr, d);
968 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
969 /* sx.val.l = constant */
971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
972 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
974 M_AND_IMM(s1, iptr->sx.val.l, d);
976 LCONST(REG_ITMP2, iptr->sx.val.l);
977 M_AND(s1, REG_ITMP2, d);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
987 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
989 emit_store_dst(jd, iptr, d);
992 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
993 /* sx.val.i = constant */
995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
996 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
997 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
998 M_OR_IMM(s1, iptr->sx.val.i, d);
1000 ICONST(REG_ITMP2, iptr->sx.val.i);
1001 M_OR(s1, REG_ITMP2, d);
1003 emit_store_dst(jd, iptr, d);
1006 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1007 /* sx.val.l = constant */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1011 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1012 M_OR_IMM(s1, iptr->sx.val.l, d);
1014 LCONST(REG_ITMP2, iptr->sx.val.l);
1015 M_OR(s1, REG_ITMP2, d);
1017 emit_store_dst(jd, iptr, d);
1020 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1024 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1025 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1027 emit_store_dst(jd, iptr, d);
1030 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1031 /* sx.val.i = constant */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1035 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1036 M_XOR_IMM(s1, iptr->sx.val.i, d);
1038 ICONST(REG_ITMP2, iptr->sx.val.i);
1039 M_XOR(s1, REG_ITMP2, d);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1045 /* sx.val.l = constant */
1047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1048 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1049 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1050 M_XOR_IMM(s1, iptr->sx.val.l, d);
1052 LCONST(REG_ITMP2, iptr->sx.val.l);
1053 M_XOR(s1, REG_ITMP2, d);
1055 emit_store_dst(jd, iptr, d);
1059 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1061 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1062 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1064 M_CMPLT(s1, s2, REG_ITMP3);
1065 M_CMPLT(s2, s1, REG_ITMP1);
1066 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1067 emit_store_dst(jd, iptr, d);
1071 /* floating operations ************************************************/
1073 case ICMD_FNEG: /* ..., value ==> ..., - value */
1075 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1076 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_DNEG: /* ..., value ==> ..., - value */
1083 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1084 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1091 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1092 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1093 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1100 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1101 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1102 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1109 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1118 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1119 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1120 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1127 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1128 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1129 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1131 emit_store_dst(jd, iptr, d);
1134 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1136 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1137 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1146 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1147 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1154 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1155 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1158 emit_store_dst(jd, iptr, d);
1162 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1164 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1165 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1166 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1167 M_FDIV(s1,s2, REG_FTMP3);
1168 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1169 M_CVTLF(REG_FTMP3, REG_FTMP3);
1170 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1171 M_FSUB(s1, REG_FTMP3, d);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_DREM: /* ..., 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_DDIV(s1,s2, REG_FTMP3);
1181 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1182 M_CVTLD(REG_FTMP3, REG_FTMP3);
1183 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1184 M_DSUB(s1, REG_FTMP3, d);
1185 emit_store_dst(jd, iptr, d);
1189 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1191 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1195 emit_store_dst(jd, iptr, d);
1198 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1204 emit_store_dst(jd, iptr, d);
1208 /* XXX these do not work correctly */
1210 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1212 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1213 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1214 M_TRUNCFI(s1, REG_FTMP1);
1215 M_MOVDI(REG_FTMP1, d);
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1222 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1223 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1224 M_TRUNCDI(s1, REG_FTMP1);
1225 M_MOVDI(REG_FTMP1, d);
1227 emit_store_dst(jd, iptr, d);
1230 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1232 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1233 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1234 M_TRUNCFL(s1, REG_FTMP1);
1235 M_MOVDL(REG_FTMP1, d);
1237 emit_store_dst(jd, iptr, d);
1240 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1242 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1243 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1244 M_TRUNCDL(s1, REG_FTMP1);
1245 M_MOVDL(REG_FTMP1, d);
1247 emit_store_dst(jd, iptr, d);
1251 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1253 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1254 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1261 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1262 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1264 emit_store_dst(jd, iptr, d);
1267 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1269 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1270 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1271 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1274 M_LADD_IMM(REG_ZERO, 1, d);
1278 M_LSUB_IMM(REG_ZERO, 1, d);
1279 M_CMOVT(REG_ZERO, d);
1280 emit_store_dst(jd, iptr, d);
1283 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1285 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1286 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1287 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1290 M_LADD_IMM(REG_ZERO, 1, d);
1294 M_LSUB_IMM(REG_ZERO, 1, d);
1295 M_CMOVT(REG_ZERO, d);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1301 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1302 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1306 M_LSUB_IMM(REG_ZERO, 1, d);
1310 M_LADD_IMM(REG_ZERO, 1, d);
1311 M_CMOVT(REG_ZERO, d);
1312 emit_store_dst(jd, iptr, d);
1315 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1317 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1318 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1319 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1322 M_LSUB_IMM(REG_ZERO, 1, d);
1326 M_LADD_IMM(REG_ZERO, 1, d);
1327 M_CMOVT(REG_ZERO, d);
1328 emit_store_dst(jd, iptr, d);
1332 /* memory operations **************************************************/
1334 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1337 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1338 emit_nullpointer_check(cd, iptr, s1);
1339 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1340 emit_store_dst(jd, iptr, d);
1343 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1346 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1347 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1348 emit_array_checks(cd, iptr, s1, s2);
1349 M_AADD(s2, s1, REG_ITMP3);
1350 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1351 emit_store_dst(jd, iptr, d);
1354 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1357 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1358 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1359 emit_array_checks(cd, iptr, s1, s2);
1360 M_AADD(s2, s1, REG_ITMP3);
1361 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1362 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1363 emit_store_dst(jd, iptr, d);
1366 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1369 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1371 emit_array_checks(cd, iptr, s1, s2);
1372 M_AADD(s2, s1, REG_ITMP3);
1373 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1374 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1375 emit_store_dst(jd, iptr, d);
1378 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1380 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1381 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1382 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1383 emit_array_checks(cd, iptr, s1, s2);
1384 M_ASLL_IMM(s2, 2, REG_ITMP3);
1385 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1386 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1387 emit_store_dst(jd, iptr, d);
1390 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1392 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1393 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1394 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1395 emit_array_checks(cd, iptr, s1, s2);
1396 M_ASLL_IMM(s2, 3, REG_ITMP3);
1397 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1398 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1399 emit_store_dst(jd, iptr, d);
1402 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1405 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1407 emit_array_checks(cd, iptr, s1, s2);
1408 M_ASLL_IMM(s2, 2, REG_ITMP3);
1409 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1410 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1411 emit_store_dst(jd, iptr, d);
1414 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1416 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1417 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1418 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1419 emit_array_checks(cd, iptr, s1, s2);
1420 M_ASLL_IMM(s2, 3, REG_ITMP3);
1421 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1422 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1423 emit_store_dst(jd, iptr, d);
1426 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1431 emit_array_checks(cd, iptr, s1, s2);
1432 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1433 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1434 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1435 emit_store_dst(jd, iptr, d);
1439 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1442 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1443 emit_array_checks(cd, iptr, s1, s2);
1444 M_AADD(s2, s1, REG_ITMP1);
1445 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1446 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1449 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1450 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1452 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1454 emit_array_checks(cd, iptr, s1, s2);
1455 M_AADD(s2, s1, REG_ITMP1);
1456 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1457 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1458 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1461 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1464 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1465 emit_array_checks(cd, iptr, s1, s2);
1466 M_ASLL_IMM(s2, 2, REG_ITMP2);
1467 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1468 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1469 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1472 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1474 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1475 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1476 emit_array_checks(cd, iptr, s1, s2);
1477 M_ASLL_IMM(s2, 3, REG_ITMP2);
1478 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1479 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1480 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1483 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1485 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1486 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1487 emit_array_checks(cd, iptr, s1, s2);
1488 M_ASLL_IMM(s2, 2, REG_ITMP2);
1489 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1490 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1491 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1494 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1496 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1497 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1498 emit_array_checks(cd, iptr, s1, s2);
1499 M_ASLL_IMM(s2, 3, REG_ITMP2);
1500 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1501 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1502 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1506 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1509 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1510 emit_array_checks(cd, iptr, s1, s2);
1511 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1515 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1516 M_ALD(REG_ITMP3, REG_PV, disp);
1517 M_JSR(REG_RA, REG_ITMP3);
1520 /* M_BEQZ(REG_RESULT, 0); */
1521 /* codegen_add_arraystoreexception_ref(cd); */
1523 emit_arraystore_check(cd, iptr, REG_RESULT);
1525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1528 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1529 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1530 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1534 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1537 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1538 emit_array_checks(cd, iptr, s1, s2);
1539 M_AADD(s2, s1, REG_ITMP1);
1540 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1543 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1544 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1548 emit_array_checks(cd, iptr, s1, s2);
1549 M_AADD(s2, s1, REG_ITMP1);
1550 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1551 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1554 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1557 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1558 emit_array_checks(cd, iptr, s1, s2);
1559 M_ASLL_IMM(s2, 2, REG_ITMP2);
1560 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1561 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1564 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1568 emit_array_checks(cd, iptr, s1, s2);
1569 M_ASLL_IMM(s2, 3, REG_ITMP2);
1570 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1571 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1574 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1578 emit_array_checks(cd, iptr, s1, s2);
1579 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1580 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1581 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1585 case ICMD_GETSTATIC: /* ... ==> ..., value */
1587 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1588 uf = iptr->sx.s23.s3.uf;
1589 fieldtype = uf->fieldref->parseddesc.fd->type;
1590 disp = dseg_add_unique_address(cd, uf);
1592 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1595 fi = iptr->sx.s23.s3.fmiref->p.field;
1596 fieldtype = fi->type;
1597 disp = dseg_add_address(cd, &(fi->value));
1599 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1600 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1603 M_ALD(REG_ITMP1, REG_PV, disp);
1605 switch (fieldtype) {
1607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1608 M_ILD_INTERN(d, REG_ITMP1, 0);
1611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1612 M_LLD_INTERN(d, REG_ITMP1, 0);
1615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1616 M_ALD_INTERN(d, REG_ITMP1, 0);
1619 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1620 M_FLD_INTERN(d, REG_ITMP1, 0);
1623 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1624 M_DLD_INTERN(d, REG_ITMP1, 0);
1627 emit_store_dst(jd, iptr, d);
1630 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1632 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1633 uf = iptr->sx.s23.s3.uf;
1634 fieldtype = uf->fieldref->parseddesc.fd->type;
1635 disp = dseg_add_unique_address(cd, uf);
1637 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1640 fi = iptr->sx.s23.s3.fmiref->p.field;
1641 fieldtype = fi->type;
1642 disp = dseg_add_address(cd, &(fi->value));
1644 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1645 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1648 M_ALD(REG_ITMP1, REG_PV, disp);
1650 switch (fieldtype) {
1652 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1653 M_IST_INTERN(s1, REG_ITMP1, 0);
1656 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1657 M_LST_INTERN(s1, REG_ITMP1, 0);
1660 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1661 M_AST_INTERN(s1, REG_ITMP1, 0);
1664 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1665 M_FST_INTERN(s1, REG_ITMP1, 0);
1668 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1669 M_DST_INTERN(s1, REG_ITMP1, 0);
1674 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1675 /* val = value (in current instruction) */
1676 /* following NOP) */
1678 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1679 uf = iptr->sx.s23.s3.uf;
1680 fieldtype = uf->fieldref->parseddesc.fd->type;
1681 disp = dseg_add_unique_address(cd, uf);
1683 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1686 fi = iptr->sx.s23.s3.fmiref->p.field;
1687 fieldtype = fi->type;
1688 disp = dseg_add_address(cd, &(fi->value));
1690 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1691 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1694 M_ALD(REG_ITMP1, REG_PV, disp);
1696 switch (fieldtype) {
1698 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1701 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
1704 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1707 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1710 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1716 case ICMD_GETFIELD: /* ... ==> ..., value */
1718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1719 emit_nullpointer_check(cd, iptr, s1);
1721 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1722 uf = iptr->sx.s23.s3.uf;
1723 fieldtype = uf->fieldref->parseddesc.fd->type;
1726 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1729 fi = iptr->sx.s23.s3.fmiref->p.field;
1730 fieldtype = fi->type;
1734 switch (fieldtype) {
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1748 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1752 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1756 emit_store_dst(jd, iptr, d);
1759 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1762 emit_nullpointer_check(cd, iptr, s1);
1764 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1765 uf = iptr->sx.s23.s3.uf;
1766 fieldtype = uf->fieldref->parseddesc.fd->type;
1770 fi = iptr->sx.s23.s3.fmiref->p.field;
1771 fieldtype = fi->type;
1775 if (IS_INT_LNG_TYPE(fieldtype))
1776 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1778 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
1780 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1781 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1783 switch (fieldtype) {
1785 M_IST(s2, s1, disp);
1788 M_LST(s2, s1, disp);
1791 M_AST(s2, s1, disp);
1794 M_FST(s2, s1, disp);
1797 M_DST(s2, s1, disp);
1802 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 emit_nullpointer_check(cd, iptr, s1);
1807 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1808 unresolved_field *uf = iptr->sx.s23.s3.uf;
1810 fieldtype = uf->fieldref->parseddesc.fd->type;
1813 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1816 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1817 fieldtype = fi->type;
1821 switch (fieldtype) {
1823 M_IST(REG_ZERO, s1, disp);
1826 M_LST(REG_ZERO, s1, disp);
1829 M_AST(REG_ZERO, s1, disp);
1832 M_FST(REG_ZERO, s1, disp);
1835 M_DST(REG_ZERO, s1, disp);
1841 /* branch operations **************************************************/
1843 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1846 M_INTMOVE(s1, REG_ITMP1_XPTR);
1848 #ifdef ENABLE_VERIFIER
1849 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1850 uc = iptr->sx.s23.s2.uc;
1852 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1854 #endif /* ENABLE_VERIFIER */
1856 disp = dseg_add_functionptr(cd, asm_handle_exception);
1857 M_ALD(REG_ITMP2, REG_PV, disp);
1858 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
1860 M_NOP; /* nop ensures that XPC is less than the end */
1861 /* of basic block */
1865 case ICMD_GOTO: /* ... ==> ... */
1866 case ICMD_RET: /* ... ==> ... */
1869 codegen_add_branch_ref(cd, iptr->dst.block);
1874 case ICMD_JSR: /* ... ==> ... */
1877 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
1882 case ICMD_IFNULL: /* ..., value ==> ... */
1884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1886 codegen_add_branch_ref(cd, iptr->dst.block);
1890 case ICMD_IFNONNULL: /* ..., value ==> ... */
1892 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1894 codegen_add_branch_ref(cd, iptr->dst.block);
1898 case ICMD_IFEQ: /* ..., value ==> ... */
1900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901 if (iptr->sx.val.i == 0) {
1904 ICONST(REG_ITMP2, iptr->sx.val.i);
1905 M_BEQ(s1, REG_ITMP2, 0);
1907 codegen_add_branch_ref(cd, iptr->dst.block);
1911 case ICMD_IFLT: /* ..., value ==> ... */
1913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1914 if (iptr->sx.val.i == 0) {
1917 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
1918 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1920 ICONST(REG_ITMP2, iptr->sx.val.i);
1921 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1923 M_BNEZ(REG_ITMP1, 0);
1925 codegen_add_branch_ref(cd, iptr->dst.block);
1929 case ICMD_IFLE: /* ..., value ==> ... */
1931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932 if (iptr->sx.val.i == 0) {
1936 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
1937 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
1938 M_BNEZ(REG_ITMP1, 0);
1941 ICONST(REG_ITMP2, iptr->sx.val.i);
1942 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
1943 M_BEQZ(REG_ITMP1, 0);
1946 codegen_add_branch_ref(cd, iptr->dst.block);
1950 case ICMD_IFNE: /* ..., value ==> ... */
1952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 if (iptr->sx.val.i == 0) {
1957 ICONST(REG_ITMP2, iptr->sx.val.i);
1958 M_BNE(s1, REG_ITMP2, 0);
1960 codegen_add_branch_ref(cd, iptr->dst.block);
1964 case ICMD_IFGT: /* ..., value ==> ... */
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967 if (iptr->sx.val.i == 0) {
1971 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
1972 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
1973 M_BEQZ(REG_ITMP1, 0);
1976 ICONST(REG_ITMP2, iptr->sx.val.i);
1977 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
1978 M_BNEZ(REG_ITMP1, 0);
1981 codegen_add_branch_ref(cd, iptr->dst.block);
1985 case ICMD_IFGE: /* ..., value ==> ... */
1987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1988 if (iptr->sx.val.i == 0) {
1992 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
1993 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
1996 ICONST(REG_ITMP2, iptr->sx.val.i);
1997 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
1999 M_BEQZ(REG_ITMP1, 0);
2001 codegen_add_branch_ref(cd, iptr->dst.block);
2005 case ICMD_IF_LEQ: /* ..., value ==> ... */
2007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2008 if (iptr->sx.val.l == 0) {
2012 LCONST(REG_ITMP2, iptr->sx.val.l);
2013 M_BEQ(s1, REG_ITMP2, 0);
2015 codegen_add_branch_ref(cd, iptr->dst.block);
2019 case ICMD_IF_LLT: /* ..., value ==> ... */
2021 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2022 if (iptr->sx.val.l == 0) {
2026 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2027 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2030 LCONST(REG_ITMP2, iptr->sx.val.l);
2031 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2033 M_BNEZ(REG_ITMP1, 0);
2035 codegen_add_branch_ref(cd, iptr->dst.block);
2039 case ICMD_IF_LLE: /* ..., value ==> ... */
2041 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2042 if (iptr->sx.val.l == 0) {
2046 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2047 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2048 M_BNEZ(REG_ITMP1, 0);
2051 LCONST(REG_ITMP2, iptr->sx.val.l);
2052 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2053 M_BEQZ(REG_ITMP1, 0);
2056 codegen_add_branch_ref(cd, iptr->dst.block);
2060 case ICMD_IF_LNE: /* ..., value ==> ... */
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063 if (iptr->sx.val.l == 0) {
2067 LCONST(REG_ITMP2, iptr->sx.val.l);
2068 M_BNE(s1, REG_ITMP2, 0);
2070 codegen_add_branch_ref(cd, iptr->dst.block);
2074 case ICMD_IF_LGT: /* ..., value ==> ... */
2076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2077 if (iptr->sx.val.l == 0) {
2081 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2082 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2083 M_BEQZ(REG_ITMP1, 0);
2086 LCONST(REG_ITMP2, iptr->sx.val.l);
2087 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2088 M_BNEZ(REG_ITMP1, 0);
2091 codegen_add_branch_ref(cd, iptr->dst.block);
2095 case ICMD_IF_LGE: /* ..., value ==> ... */
2097 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2098 if (iptr->sx.val.l == 0) {
2102 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2103 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2106 LCONST(REG_ITMP2, iptr->sx.val.l);
2107 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2109 M_BEQZ(REG_ITMP1, 0);
2111 codegen_add_branch_ref(cd, iptr->dst.block);
2115 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2116 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2117 case ICMD_IF_ACMPEQ:
2119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2120 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2122 codegen_add_branch_ref(cd, iptr->dst.block);
2126 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2127 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2128 case ICMD_IF_ACMPNE:
2130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2133 codegen_add_branch_ref(cd, iptr->dst.block);
2137 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2138 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2142 M_CMPLT(s1, s2, REG_ITMP1);
2143 M_BNEZ(REG_ITMP1, 0);
2144 codegen_add_branch_ref(cd, iptr->dst.block);
2148 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2149 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2151 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2152 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2153 M_CMPGT(s1, s2, REG_ITMP1);
2154 M_BNEZ(REG_ITMP1, 0);
2155 codegen_add_branch_ref(cd, iptr->dst.block);
2159 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2160 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2164 M_CMPGT(s1, s2, REG_ITMP1);
2165 M_BEQZ(REG_ITMP1, 0);
2166 codegen_add_branch_ref(cd, iptr->dst.block);
2170 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2171 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2174 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2175 M_CMPLT(s1, s2, REG_ITMP1);
2176 M_BEQZ(REG_ITMP1, 0);
2177 codegen_add_branch_ref(cd, iptr->dst.block);
2182 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2185 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2186 M_INTMOVE(s1, REG_RESULT);
2187 goto nowperformreturn;
2189 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2191 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2192 M_INTMOVE(s1, REG_RESULT);
2194 #ifdef ENABLE_VERIFIER
2195 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2196 uc = iptr->sx.s23.s2.uc;
2198 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2200 #endif /* ENABLE_VERIFIER */
2201 goto nowperformreturn;
2203 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2205 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2206 M_FLTMOVE(s1, REG_FRESULT);
2207 goto nowperformreturn;
2209 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2211 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2212 M_DBLMOVE(s1, REG_FRESULT);
2213 goto nowperformreturn;
2215 case ICMD_RETURN: /* ... ==> ... */
2221 p = cd->stackframesize;
2223 #if !defined(NDEBUG)
2224 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2225 emit_verbosecall_exit(jd);
2228 #if defined(ENABLE_THREADS)
2229 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2230 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2231 M_ALD(REG_ITMP3, REG_PV, disp);
2233 /* we need to save the proper return value */
2235 switch (iptr->opc) {
2239 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2240 M_JSR(REG_RA, REG_ITMP3);
2241 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2245 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2246 M_JSR(REG_RA, REG_ITMP3);
2247 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2250 M_JSR(REG_RA, REG_ITMP3);
2251 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2255 /* and now restore the proper return value */
2257 switch (iptr->opc) {
2261 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2265 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2271 /* restore return address */
2273 if (!jd->isleafmethod) {
2274 p--; M_ALD(REG_RA, REG_SP, p * 8);
2277 /* restore saved registers */
2279 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2280 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2282 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2283 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2286 /* deallocate stack and return */
2288 if (cd->stackframesize) {
2291 disp = cd->stackframesize * 8;
2292 lo = (short) (disp);
2293 hi = (short) (((disp) - lo) >> 16);
2297 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2299 M_LUI(REG_ITMP3,hi);
2300 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2302 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2315 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2318 branch_target_t *table;
2320 table = iptr->dst.table;
2322 l = iptr->sx.s23.s2.tablelow;
2323 i = iptr->sx.s23.s3.tablehigh;
2325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2327 {M_INTMOVE(s1, REG_ITMP1);}
2328 else if (l <= 32768) {
2329 M_IADD_IMM(s1, -l, REG_ITMP1);
2332 ICONST(REG_ITMP2, l);
2333 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2336 /* number of targets */
2341 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2342 M_BEQZ(REG_ITMP2, 0);
2343 codegen_add_branch_ref(cd, table[0].block); /* default target */
2344 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2346 /* build jump table top down and use address of lowest entry */
2351 dseg_add_target(cd, table->block);
2356 /* length of dataseg after last dseg_add_target is used by load */
2358 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2359 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2366 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2369 lookup_target_t *lookup;
2371 lookup = iptr->dst.lookup;
2373 i = iptr->sx.s23.s2.lookupcount;
2375 MCODECHECK((i<<2)+8);
2376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2379 ICONST(REG_ITMP2, lookup->value);
2380 M_BEQ(s1, REG_ITMP2, 0);
2381 codegen_add_branch_ref(cd, lookup->target.block);
2387 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2394 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2396 bte = iptr->sx.s23.s3.bte;
2400 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2402 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2403 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2404 case ICMD_INVOKEINTERFACE:
2406 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2408 um = iptr->sx.s23.s3.um;
2409 md = um->methodref->parseddesc.md;
2412 lm = iptr->sx.s23.s3.fmiref->p.method;
2414 md = lm->parseddesc;
2418 s3 = md->paramcount;
2420 MCODECHECK((s3 << 1) + 64);
2422 /* copy arguments to registers or stack location */
2424 for (s3 = s3 - 1; s3 >= 0; s3--) {
2425 var = VAR(iptr->sx.s23.s2.args[s3]);
2427 if (var->flags & PREALLOC)
2430 if (IS_INT_LNG_TYPE(var->type)) {
2431 if (!md->params[s3].inmemory) {
2432 s1 = rd->argintregs[md->params[s3].regoff];
2433 d = emit_load(jd, iptr, var, s1);
2437 d = emit_load(jd, iptr, var, REG_ITMP1);
2438 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2442 if (!md->params[s3].inmemory) {
2443 s1 = rd->argfltregs[md->params[s3].regoff];
2444 d = emit_load(jd, iptr, var, s1);
2445 if (IS_2_WORD_TYPE(var->type))
2451 d = emit_load(jd, iptr, var, REG_FTMP1);
2452 if (IS_2_WORD_TYPE(var->type))
2453 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2455 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2460 switch (iptr->opc) {
2462 disp = dseg_add_functionptr(cd, bte->fp);
2464 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2466 /* TWISTI: i actually don't know the reason for using
2467 REG_ITMP3 here instead of REG_PV. */
2471 case ICMD_INVOKESPECIAL:
2472 /* emit_nullpointer_check(cd, REG_A0); */
2476 M_LUI(REG_ITMP3, 0);
2477 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
2478 codegen_add_nullpointerexception_ref(cd);
2479 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
2485 case ICMD_INVOKESTATIC:
2487 disp = dseg_add_unique_address(cd, um);
2489 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
2493 disp = dseg_add_address(cd, lm->stubroutine);
2495 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2499 case ICMD_INVOKEVIRTUAL:
2500 emit_nullpointer_check(cd, iptr, REG_A0);
2503 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2508 s1 = OFFSET(vftbl_t, table[0]) +
2509 sizeof(methodptr) * lm->vftblindex;
2511 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2512 M_ALD(REG_PV, REG_METHODPTR, s1);
2516 case ICMD_INVOKEINTERFACE:
2517 emit_nullpointer_check(cd, iptr, REG_A0);
2520 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2526 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2527 sizeof(methodptr*) * lm->class->index;
2529 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2532 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2533 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2534 M_ALD(REG_PV, REG_METHODPTR, s2);
2539 /* generate the actual call */
2543 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2544 M_LDA(REG_PV, REG_RA, -disp);
2546 /* actually only used for ICMD_BUILTIN */
2548 emit_exception_check(cd, iptr);
2550 /* store return value */
2552 d = md->returntype.type;
2554 if (d != TYPE_VOID) {
2555 if (IS_INT_LNG_TYPE(d)) {
2556 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2557 M_INTMOVE(REG_RESULT, s1);
2560 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2561 if (IS_2_WORD_TYPE(d))
2562 M_DMOV(REG_FRESULT, s1);
2564 M_FMOV(REG_FRESULT, s1);
2566 emit_store_dst(jd, iptr, s1);
2571 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2572 /* val.a: (classinfo*) superclass */
2574 /* superclass is an interface:
2576 * OK if ((sub == NULL) ||
2577 * (sub->vftbl->interfacetablelength > super->index) &&
2578 * (sub->vftbl->interfacetable[-super->index] != NULL));
2580 * superclass is a class:
2582 * OK if ((sub == NULL) || (0
2583 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2584 * super->vftbl->diffvall));
2587 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2591 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2596 super = iptr->sx.s23.s3.c.cls;
2597 superindex = super->index;
2600 #if defined(ENABLE_THREADS)
2601 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2606 /* calculate interface checkcast code size */
2608 /* s2 = 3 + 2 + 1 + 2; */
2611 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2613 /* calculate class checkcast code size */
2615 /* s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */
2616 s3 = 2 + 1 + 4 + 1 + 7;
2618 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2620 /* if class is not resolved, check which code to call */
2622 if (super == NULL) {
2623 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
2626 cr = iptr->sx.s23.s3.c.ref;
2627 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2629 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2632 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2633 M_ILD(REG_ITMP2, REG_PV, disp);
2634 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2635 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2639 /* interface checkcast code */
2641 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2642 if (super == NULL) {
2643 cr = iptr->sx.s23.s3.c.ref;
2645 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2653 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2654 M_ILD(REG_ITMP3, REG_ITMP2,
2655 OFFSET(vftbl_t, interfacetablelength));
2656 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2657 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
2659 M_ALD(REG_ITMP3, REG_ITMP2,
2660 OFFSET(vftbl_t, interfacetable[0]) -
2661 superindex * sizeof(methodptr*));
2662 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
2664 if (super == NULL) {
2670 /* class checkcast code */
2672 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2673 if (super == NULL) {
2674 cr = iptr->sx.s23.s3.c.ref;
2675 disp = dseg_add_unique_address(cd, NULL);
2677 codegen_add_patch_ref(cd,
2678 PATCHER_checkcast_instanceof_class,
2682 disp = dseg_add_address(cd, super->vftbl);
2688 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2689 M_ALD(REG_ITMP3, REG_PV, disp);
2690 #if defined(ENABLE_THREADS)
2691 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2693 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2694 /* if (s1 != REG_ITMP1) { */
2695 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2696 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2697 /* #if defined(ENABLE_THREADS) */
2698 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
2700 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2702 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2703 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2704 M_ALD(REG_ITMP3, REG_PV, disp);
2705 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2706 #if defined(ENABLE_THREADS)
2707 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2710 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2711 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
2714 d = codegen_reg_of_dst(jd, iptr, s1);
2717 s1 = emit_load_s1(jd, iptr, REG_A0);
2718 M_INTMOVE(s1, REG_A0);
2720 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2721 cr = iptr->sx.s23.s3.c.ref;
2722 disp = dseg_add_unique_address(cd, NULL);
2724 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2728 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2730 M_ALD(REG_A1, REG_PV, disp);
2731 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2732 M_ALD(REG_ITMP3, REG_PV, disp);
2733 M_JSR(REG_RA, REG_ITMP3);
2736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2737 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
2739 d = codegen_reg_of_dst(jd, iptr, s1);
2743 emit_store_dst(jd, iptr, d);
2746 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2747 /* val.a: (classinfo*) superclass */
2749 /* superclass is an interface:
2751 * return (sub != NULL) &&
2752 * (sub->vftbl->interfacetablelength > super->index) &&
2753 * (sub->vftbl->interfacetable[-super->index] != NULL);
2755 * superclass is a class:
2757 * return ((sub != NULL) && (0
2758 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2759 * super->vftbl->diffvall));
2766 super = iptr->sx.s23.s3.c.cls;
2768 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2773 super = iptr->sx.s23.s3.c.cls;
2774 superindex = super->index;
2777 #if defined(ENABLE_THREADS)
2778 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2781 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2784 M_MOV(s1, REG_ITMP1);
2788 /* calculate interface instanceof code size */
2792 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2794 /* calculate class instanceof code size */
2798 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2802 /* if class is not resolved, check which code to call */
2804 if (super == NULL) {
2805 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
2808 cr = iptr->sx.s23.s3.c.ref;
2809 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2811 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2814 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
2815 M_ILD(REG_ITMP3, REG_PV, disp);
2816 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2817 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
2821 /* interface instanceof code */
2823 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2824 if (super == NULL) {
2825 cr = iptr->sx.s23.s3.c.ref;
2827 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2835 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2836 M_ILD(REG_ITMP3, REG_ITMP1,
2837 OFFSET(vftbl_t, interfacetablelength));
2838 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2839 M_BLEZ(REG_ITMP3, 3);
2841 M_ALD(REG_ITMP1, REG_ITMP1,
2842 OFFSET(vftbl_t, interfacetable[0]) -
2843 superindex * sizeof(methodptr*));
2844 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2846 if (super == NULL) {
2852 /* class instanceof code */
2854 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2855 if (super == NULL) {
2856 cr = iptr->sx.s23.s3.c.ref;
2857 disp = dseg_add_unique_address(cd, NULL);
2859 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2863 disp = dseg_add_address(cd, super->vftbl);
2869 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2870 M_ALD(REG_ITMP2, REG_PV, disp);
2871 #if defined(ENABLE_THREADS)
2872 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2874 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2875 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2876 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2877 #if defined(ENABLE_THREADS)
2878 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2880 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2881 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
2884 emit_store_dst(jd, iptr, d);
2888 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2890 /* check for negative sizes and copy sizes to stack if necessary */
2892 MCODECHECK((iptr->s1.argcount << 1) + 64);
2894 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2896 var = VAR(iptr->sx.s23.s2.args[s1]);
2898 /* copy SAVEDVAR sizes to stack */
2900 if (!(var->flags & PREALLOC)) {
2901 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2902 M_LST(s2, REG_SP, s1 * 8);
2906 /* a0 = dimension count */
2908 ICONST(REG_A0, iptr->s1.argcount);
2910 /* is patcher function set? */
2912 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2913 cr = iptr->sx.s23.s3.c.ref;
2914 disp = dseg_add_unique_address(cd, NULL);
2916 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2920 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2922 /* a1 = arraydescriptor */
2924 M_ALD(REG_A1, REG_PV, disp);
2926 /* a2 = pointer to dimensions = stack pointer */
2928 M_INTMOVE(REG_SP, REG_A2);
2930 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2931 M_ALD(REG_ITMP3, REG_PV, disp);
2932 M_JSR(REG_RA, REG_ITMP3);
2935 /* check for exception before result assignment */
2937 emit_exception_check(cd, iptr);
2939 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2940 M_INTMOVE(REG_RESULT, d);
2941 emit_store_dst(jd, iptr, d);
2945 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2949 } /* for instruction */
2951 MCODECHECK(64); /* XXX require smaller number? */
2953 /* At the end of a basic block we may have to append some nops,
2954 because the patcher stub calling code might be longer than the
2955 actual instruction. So codepatching does not change the
2956 following block unintentionally. */
2958 if (cd->mcodeptr < cd->lastmcodeptr) {
2959 while (cd->mcodeptr < cd->lastmcodeptr)
2963 } /* if (bptr -> flags >= BBREACHED) */
2964 } /* for basic block */
2966 dseg_createlinenumbertable(cd);
2968 /* generate exception and patcher stubs */
2970 emit_exception_stubs(jd);
2971 emit_patcher_stubs(jd);
2974 emit_replacement_stubs(jd);
2979 /* everything's ok */
2985 /* createcompilerstub **********************************************************
2987 Creates a stub routine which calls the compiler.
2989 *******************************************************************************/
2991 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
2992 #define COMPILERSTUB_CODESIZE 4 * 4
2994 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2997 u1 *createcompilerstub(methodinfo *m)
2999 u1 *s; /* memory to hold the stub */
3005 s = CNEW(u1, COMPILERSTUB_SIZE);
3007 /* set data pointer and code pointer */
3010 s = s + COMPILERSTUB_DATASIZE;
3012 /* mark start of dump memory area */
3014 dumpsize = dump_size();
3016 cd = DNEW(codegendata);
3019 /* Store the codeinfo pointer in the same place as in the
3020 methodheader for compiled methods. */
3022 code = code_codeinfo_new(m);
3024 d[0] = (ptrint) asm_call_jit_compiler;
3026 d[2] = (ptrint) code;
3028 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3029 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3033 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3035 #if defined(ENABLE_STATISTICS)
3037 count_cstub_len += COMPILERSTUB_SIZE;
3040 /* release dump area */
3042 dump_release(dumpsize);
3048 /* createnativestub ************************************************************
3050 Creates a stub routine which calls a native method.
3052 *******************************************************************************/
3054 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3062 s4 i, j; /* count variables */
3065 s4 funcdisp; /* displacement of the function */
3067 /* get required compiler data */
3074 /* initialize variables */
3077 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3079 /* calculate stack frame size */
3081 cd->stackframesize =
3082 1 + /* return address */
3083 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3084 sizeof(localref_table) / SIZEOF_VOID_P +
3085 md->paramcount + /* for saving arguments over calls */
3086 1 + /* for saving return address */
3089 /* create method header */
3091 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3092 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3093 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3094 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3095 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3096 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3097 (void) dseg_addlinenumbertablesize(cd);
3098 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3100 /* generate stub code */
3102 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3103 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3105 #if !defined(NDEBUG)
3106 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3107 emit_verbosecall_enter(jd);
3110 /* get function address (this must happen before the stackframeinfo) */
3112 funcdisp = dseg_add_functionptr(cd, f);
3114 #if !defined(WITH_STATIC_CLASSPATH)
3116 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3119 /* save integer and float argument registers */
3121 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3122 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3123 M_LST(rd->argintregs[i], REG_SP, j * 8);
3128 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3129 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3130 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3135 /* prepare data structures for native function call */
3137 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3138 M_MOV(REG_PV, REG_A1);
3139 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3140 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3141 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3142 M_ALD(REG_ITMP3, REG_PV, disp);
3143 M_JSR(REG_RA, REG_ITMP3);
3144 M_NOP; /* XXX fill me! */
3146 /* restore integer and float argument registers */
3148 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3149 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3150 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3155 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3156 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3157 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3162 /* copy or spill arguments to new locations */
3164 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3165 t = md->paramtypes[i].type;
3167 if (IS_INT_LNG_TYPE(t)) {
3168 if (!md->params[i].inmemory) {
3169 s1 = rd->argintregs[md->params[i].regoff];
3171 if (!nmd->params[j].inmemory) {
3172 s2 = rd->argintregs[nmd->params[j].regoff];
3175 s2 = nmd->params[j].regoff;
3176 M_AST(s1, REG_SP, s2 * 8);
3180 s1 = md->params[i].regoff + cd->stackframesize;
3181 s2 = nmd->params[j].regoff;
3182 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3183 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3187 if (!md->params[i].inmemory) {
3188 s1 = rd->argfltregs[md->params[i].regoff];
3190 if (!nmd->params[j].inmemory) {
3191 s2 = rd->argfltregs[nmd->params[j].regoff];
3192 if (IS_2_WORD_TYPE(t))
3198 s2 = nmd->params[j].regoff;
3199 if (IS_2_WORD_TYPE(t))
3200 M_DST(s1, REG_SP, s2 * 8);
3202 M_FST(s1, REG_SP, s2 * 8);
3206 s1 = md->params[i].regoff + cd->stackframesize;
3207 s2 = nmd->params[j].regoff;
3208 if (IS_2_WORD_TYPE(t)) {
3209 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3210 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3212 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3213 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3219 /* put class into second argument register */
3221 if (m->flags & ACC_STATIC) {
3222 disp = dseg_add_address(cd, m->class);
3223 M_ALD(REG_A1, REG_PV, disp);
3226 /* put env into first argument register */
3228 disp = dseg_add_address(cd, _Jv_env);
3229 M_ALD(REG_A0, REG_PV, disp);
3231 /* do the native function call */
3233 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3234 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3235 M_NOP; /* delay slot */
3237 /* save return value */
3239 if (md->returntype.type != TYPE_VOID) {
3240 if (IS_INT_LNG_TYPE(md->returntype.type))
3241 M_LST(REG_RESULT, REG_SP, 0 * 8);
3243 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3246 #if !defined(NDEBUG)
3247 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3248 emit_verbosecall_exit(jd);
3251 /* remove native stackframe info */
3253 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3254 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3255 M_ALD(REG_ITMP3, REG_PV, disp);
3256 M_JSR(REG_RA, REG_ITMP3);
3257 M_NOP; /* XXX fill me! */
3258 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3260 /* restore return value */
3262 if (md->returntype.type != TYPE_VOID) {
3263 if (IS_INT_LNG_TYPE(md->returntype.type))
3264 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3266 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3269 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3271 /* check for exception */
3273 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3274 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3276 M_RET(REG_RA); /* return to caller */
3277 M_NOP; /* DELAY SLOT */
3279 /* handle exception */
3281 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3282 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3283 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3284 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3286 /* generate patcher stubs */
3288 emit_patcher_stubs(jd);
3292 return code->entrypoint;
3297 * These are local overrides for various environment variables in Emacs.
3298 * Please do not remove this and leave it at the end of the file, where
3299 * Emacs will automagically detect them.
3300 * ---------------------------------------------------------------------
3303 * indent-tabs-mode: t
3307 * vim:noexpandtab:sw=4:ts=4: