1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 7723 2007-04-16 18:03:08Z michi $
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
42 #include "mm/memory.h"
44 #include "native/native.h"
46 #if defined(ENABLE_THREADS)
47 # include "threads/native/lock.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
54 #include "vm/jit/abi.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/md.h"
61 #include "vm/jit/patcher.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
65 #if defined(ENABLE_LSRA)
66 # include "vm/jit/allocator/lsra.h"
69 #include "vmcore/class.h"
70 #include "vmcore/options.h"
73 /* codegen_emit ****************************************************************
75 Generates machine code.
77 *******************************************************************************/
79 bool codegen_emit(jitdata *jd)
85 s4 len, s1, s2, s3, d, disp;
91 constant_classref *cr;
93 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
94 unresolved_method *um;
95 builtintable_entry *bte;
102 /* get required compiler data */
109 /* prevent compiler warnings */
124 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
126 /* space to save used callee saved registers */
128 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
129 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
131 cd->stackframesize = rd->memuse + savedregs_num;
133 #if defined(ENABLE_THREADS)
134 /* space to save argument of monitor_enter */
136 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
137 # if SIZEOF_VOID_P == 8
138 cd->stackframesize++;
141 cd->stackframesize += 2;
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)
219 s1 = md->params[p].regoff;
221 if (IS_INT_LNG_TYPE(t)) { /* integer args */
222 if (!md->params[p].inmemory) { /* register arguments */
223 #if SIZEOF_VOID_P == 8
224 if (!(var->flags & INMEMORY))
225 M_INTMOVE(s1, var->vv.regoff);
227 M_LST(s1, REG_SP, var->vv.regoff * 8);
229 if (IS_2_WORD_TYPE(t)) {
230 if (!(var->flags & INMEMORY))
231 M_LNGMOVE(s1, var->vv.regoff);
233 M_LST(s1, REG_SP, var->vv.regoff * 8);
236 if (!(var->flags & INMEMORY))
237 M_INTMOVE(s1, var->vv.regoff);
239 M_IST(s1, REG_SP, var->vv.regoff * 8);
243 else { /* stack arguments */
244 if (!(var->flags & INMEMORY)) {
245 #if SIZEOF_VOID_P == 8
246 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
248 if (IS_2_WORD_TYPE(t))
249 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
251 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
255 var->vv.regoff = cd->stackframesize + s1;
258 else { /* floating args */
259 if (!md->params[p].inmemory) {
260 #if SIZEOF_VOID_P == 8
261 if (!(var->flags & INMEMORY)) {
262 if (IS_2_WORD_TYPE(t))
263 M_DMOV(s1, var->vv.regoff);
265 M_FMOV(s1, var->vv.regoff);
268 if (IS_2_WORD_TYPE(t))
269 M_DST(s1, REG_SP, var->vv.regoff * 8);
271 M_FST(s1, REG_SP, var->vv.regoff * 8);
275 ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
276 if (!(var->flags & INMEMORY)) {
277 if (IS_2_WORD_TYPE(t))
278 M_DBLMOVE(s1, var->vv.regoff);
280 M_FLTMOVE(s1, var->vv.regoff);
283 if (IS_2_WORD_TYPE(t))
284 M_DST(s1, REG_SP, var->vv.regoff * 8);
286 M_FST(s1, REG_SP, var->vv.regoff * 8);
290 if (IS_2_WORD_TYPE(t)) {
291 if (!(var->flags & INMEMORY)) {
292 M_MTC1(GET_LOW_REG(s1), var->vv.regoff);
293 M_MTC1(GET_HIGH_REG(s1), var->vv.regoff + 1);
297 M_LST(s1, REG_SP, var->vv.regoff * 8);
300 if (!(var->flags & INMEMORY)) {
301 M_MTC1(s1, var->vv.regoff);
305 M_IST(s1, REG_SP, var->vv.regoff * 8);
311 if (!(var->flags & INMEMORY)) {
312 if (IS_2_WORD_TYPE(t))
313 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
315 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
318 var->vv.regoff = cd->stackframesize + s1;
323 /* call monitorenter function */
325 #if defined(ENABLE_THREADS)
326 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
327 /* stack offset for monitor argument */
331 # if !defined(NDEBUG)
332 if (opt_verbosecall) {
333 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
335 for (p = 0; p < INT_ARG_CNT; p++)
336 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
338 for (p = 0; p < FLT_ARG_CNT; p++)
339 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
341 s1 += INT_ARG_CNT + FLT_ARG_CNT;
345 /* get correct lock object */
347 if (m->flags & ACC_STATIC) {
348 disp = dseg_add_address(cd, &m->class->object.header);
349 M_ALD(REG_A0, REG_PV, disp);
350 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
351 M_ALD(REG_ITMP3, REG_PV, disp);
354 /* emit_nullpointer_check(cd, iptr, REG_A0); */
356 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
357 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
358 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
361 M_JSR(REG_RA, REG_ITMP3);
362 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
364 # if !defined(NDEBUG)
365 if (opt_verbosecall) {
366 for (p = 0; p < INT_ARG_CNT; p++)
367 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
369 for (p = 0; p < FLT_ARG_CNT; p++)
370 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
373 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
381 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
382 emit_verbosecall_enter(jd);
385 /* end of header generation */
387 /* create replacement points */
389 REPLACEMENT_POINTS_INIT(cd, jd);
391 /* walk through all basic blocks */
393 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
395 /* handle replacement points */
397 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
399 /* store relative start of block */
401 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
403 if (bptr->flags >= BBREACHED) {
404 /* branch resolving */
406 codegen_resolve_branchrefs(cd, bptr);
408 /* copy interface registers to their destination */
412 #if defined(ENABLE_LSRA)
416 src = bptr->invars[len];
417 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
418 /* d = reg_of_var(m, src, REG_ITMP1); */
419 if (!(src->flags & INMEMORY))
423 M_INTMOVE(REG_ITMP1, d);
424 emit_store(jd, NULL, src, d);
431 var = VAR(bptr->invars[len]);
432 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
433 d = codegen_reg_of_var(0, var, REG_ITMP1);
434 M_INTMOVE(REG_ITMP1, d);
435 emit_store(jd, NULL, var, d);
438 assert((var->flags & INOUT));
441 #if defined(ENABLE_LSRA)
444 /* walk through all instructions */
447 /* currentline = 0; */
449 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
450 if (iptr->line != currentline) {
451 dseg_addlinenumber(cd, iptr->line);
452 currentline = iptr->line;
455 MCODECHECK(64); /* an instruction usually needs < 64 words */
459 case ICMD_NOP: /* ... ==> ... */
460 case ICMD_POP: /* ..., value ==> ... */
461 case ICMD_POP2: /* ..., value, value ==> ... */
464 case ICMD_INLINE_START:
466 REPLACEMENT_POINT_INLINE_START(cd, iptr);
469 case ICMD_INLINE_BODY:
471 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
472 dseg_addlinenumber_inline_start(cd, iptr);
473 dseg_addlinenumber(cd, iptr->line);
476 case ICMD_INLINE_END:
478 dseg_addlinenumber_inline_end(cd, iptr);
479 dseg_addlinenumber(cd, iptr->line);
482 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
485 emit_nullpointer_check(cd, iptr, s1);
488 /* constant operations ************************************************/
490 case ICMD_ICONST: /* ... ==> ..., constant */
492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
493 ICONST(d, iptr->sx.val.i);
494 emit_store_dst(jd, iptr, d);
497 case ICMD_LCONST: /* ... ==> ..., constant */
499 #if SIZEOF_VOID_P == 8
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
502 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
504 LCONST(d, iptr->sx.val.l);
505 emit_store_dst(jd, iptr, d);
508 case ICMD_FCONST: /* ... ==> ..., constant */
510 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
511 disp = dseg_add_float(cd, iptr->sx.val.f);
512 M_FLD(d, REG_PV, disp);
513 emit_store_dst(jd, iptr, d);
516 case ICMD_DCONST: /* ... ==> ..., constant */
518 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
519 disp = dseg_add_double(cd, iptr->sx.val.d);
520 M_DLD(d, REG_PV, disp);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_ACONST: /* ... ==> ..., constant */
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
529 cr = iptr->sx.val.c.ref;
530 disp = dseg_add_unique_address(cd, cr);
532 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
534 M_ALD(d, REG_PV, disp);
537 if (iptr->sx.val.anyptr == NULL)
538 M_INTMOVE(REG_ZERO, d);
540 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
541 M_ALD(d, REG_PV, disp);
544 emit_store_dst(jd, iptr, d);
548 /* load/store/copy/move operations ************************************/
550 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
551 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
552 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
553 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
554 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
555 case ICMD_ISTORE: /* ..., value ==> ... */
556 case ICMD_LSTORE: /* ..., value ==> ... */
557 case ICMD_FSTORE: /* ..., value ==> ... */
558 case ICMD_DSTORE: /* ..., value ==> ... */
562 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
566 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
567 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
571 /* integer operations *************************************************/
573 case ICMD_INEG: /* ..., value ==> ..., - value */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
577 M_ISUB(REG_ZERO, s1, d);
578 emit_store_dst(jd, iptr, d);
581 case ICMD_LNEG: /* ..., value ==> ..., - value */
583 #if SIZEOF_VOID_P == 8
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586 M_LSUB(REG_ZERO, s1, d);
588 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
590 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
591 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
592 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
593 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
595 emit_store_dst(jd, iptr, d);
598 case ICMD_I2L: /* ..., value ==> ..., value */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 #if SIZEOF_VOID_P == 8
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
606 M_INTMOVE(s1, GET_LOW_REG(d));
607 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
609 emit_store_dst(jd, iptr, d);
612 case ICMD_L2I: /* ..., value ==> ..., value */
614 #if SIZEOF_VOID_P == 8
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
617 M_ISLL_IMM(s1, 0, d);
619 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
621 M_INTMOVE(GET_LOW_REG(s1), d);
623 emit_store_dst(jd, iptr, d);
626 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630 #if SIZEOF_VOID_P == 8
631 M_LSLL_IMM(s1, 56, d);
632 M_LSRA_IMM( d, 56, d);
634 M_ISLL_IMM(s1, 24, d);
635 M_ISRA_IMM( d, 24, d);
637 emit_store_dst(jd, iptr, d);
640 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 M_AND_IMM(s1, 0xffff, d);
645 emit_store_dst(jd, iptr, d);
648 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
650 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
652 #if SIZEOF_VOID_P == 8
653 M_LSLL_IMM(s1, 48, d);
654 M_LSRA_IMM( d, 48, d);
656 M_ISLL_IMM(s1, 16, d);
657 M_ISRA_IMM( d, 16, d);
659 emit_store_dst(jd, iptr, d);
663 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669 emit_store_dst(jd, iptr, d);
673 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
674 /* sx.val.i = constant */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
678 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
679 M_IADD_IMM(s1, iptr->sx.val.i, d);
681 ICONST(REG_ITMP2, iptr->sx.val.i);
682 M_IADD(s1, REG_ITMP2, d);
684 emit_store_dst(jd, iptr, d);
687 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
689 #if SIZEOF_VOID_P == 8
690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
696 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
698 M_IADD(s1, s2, GET_HIGH_REG(d));
699 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
700 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
701 if (s1 == GET_LOW_REG(d)) {
702 M_MOV(s1, REG_ITMP3);
705 M_IADD(s1, s2, GET_LOW_REG(d));
706 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
707 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
709 emit_store_dst(jd, iptr, d);
712 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
713 /* sx.val.l = constant */
715 #if SIZEOF_VOID_P == 8
716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
719 M_LADD_IMM(s1, iptr->sx.val.l, d);
721 LCONST(REG_ITMP2, iptr->sx.val.l);
722 M_LADD(s1, REG_ITMP2, d);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
726 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
727 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
728 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
729 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
730 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
732 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
733 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
734 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
735 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
736 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
737 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
738 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
741 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
742 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
743 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
744 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
745 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
746 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
747 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
748 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
751 emit_store_dst(jd, iptr, d);
754 case ICMD_ISUB: /* ..., 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);
760 emit_store_dst(jd, iptr, d);
763 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
764 /* sx.val.i = constant */
766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
769 M_IADD_IMM(s1, -iptr->sx.val.i, d);
771 ICONST(REG_ITMP2, iptr->sx.val.i);
772 M_ISUB(s1, REG_ITMP2, d);
774 emit_store_dst(jd, iptr, d);
777 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
779 #if SIZEOF_VOID_P == 8
780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
786 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
787 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
788 M_ISUB(s1, s2, GET_HIGH_REG(d));
789 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
790 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
791 M_CMPULT(s1, s2, REG_ITMP3);
792 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
793 /* if s1 is equal to REG_ITMP3 we have to reload it, since
794 the CMPULT instruction destroyed it */
796 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
797 M_ISUB(s1, s2, GET_LOW_REG(d));
800 emit_store_dst(jd, iptr, d);
803 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
804 /* sx.val.l = constant */
806 #if SIZEOF_VOID_P == 8
807 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
810 M_LADD_IMM(s1, -iptr->sx.val.l, d);
812 LCONST(REG_ITMP2, iptr->sx.val.l);
813 M_LSUB(s1, REG_ITMP2, d);
816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
817 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
818 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
819 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
820 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
821 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
822 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
823 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
825 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
826 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
827 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
828 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
829 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
832 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
833 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
834 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
835 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
836 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
837 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
838 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
839 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
842 emit_store_dst(jd, iptr, d);
845 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
854 emit_store_dst(jd, iptr, d);
857 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
858 /* sx.val.i = constant */
860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
862 ICONST(REG_ITMP2, iptr->sx.val.i);
863 M_IMUL(s1, REG_ITMP2);
867 emit_store_dst(jd, iptr, d);
870 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
872 #if SIZEOF_VOID_P == 8
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);
881 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
882 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
883 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
888 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
890 M_MFHI(GET_HIGH_REG(d));
891 M_MFLO(GET_LOW_REG(d));
894 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
896 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
897 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
900 /* XXX do we need nops here? */
902 emit_store_dst(jd, iptr, d);
905 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
906 /* sx.val.l = constant */
908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
910 LCONST(REG_ITMP2, iptr->sx.val.l);
911 M_LMUL(s1, REG_ITMP2);
915 emit_store_dst(jd, iptr, d);
918 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
923 emit_arithmetic_check(cd, iptr, s2);
928 emit_store_dst(jd, iptr, d);
931 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
933 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
934 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
935 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
936 emit_arithmetic_check(cd, iptr, s2);
941 emit_store_dst(jd, iptr, d);
944 #if SIZEOF_VOID_P == 8
946 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951 emit_arithmetic_check(cd, iptr, s2);
956 emit_store_dst(jd, iptr, d);
959 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
963 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
964 emit_arithmetic_check(cd, iptr, s2);
969 emit_store_dst(jd, iptr, d);
972 #else /* SIZEOF_VOID_P == 8 */
974 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
975 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
977 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
978 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
980 /* XXX TODO: only do this if arithmetic check is really done! */
981 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
982 emit_arithmetic_check(cd, iptr, REG_ITMP3);
984 M_LNGMOVE(s1, REG_A0_A1_PACKED);
985 M_LNGMOVE(s2, REG_A2_A3_PACKED);
987 bte = iptr->sx.s23.s3.bte;
988 disp = dseg_add_functionptr(cd, bte->fp);
989 M_ALD(REG_ITMP3, REG_PV, disp);
990 M_JSR(REG_RA, REG_ITMP3);
993 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
994 M_LNGMOVE(REG_RESULT_PACKED, d);
995 emit_store_dst(jd, iptr, d);
998 #endif /* SIZEOF_VOID_P == 8 */
1000 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1001 /* val.i = constant */
1003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1004 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1005 #if SIZEOF_VOID_P == 8
1006 M_LSRA_IMM(s1, 63, REG_ITMP2);
1007 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1008 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1009 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1011 M_ISRA_IMM(s1, 31, REG_ITMP2);
1012 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
1013 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1014 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1016 emit_store_dst(jd, iptr, d);
1019 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1020 /* val.i = constant */
1022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1025 M_MOV(s1, REG_ITMP1);
1028 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1029 M_AND_IMM(s1, iptr->sx.val.i, d);
1032 M_ISUB(REG_ZERO, s1, d);
1033 M_AND_IMM(d, iptr->sx.val.i, d);
1036 ICONST(REG_ITMP2, iptr->sx.val.i);
1037 M_AND(s1, REG_ITMP2, d);
1040 M_ISUB(REG_ZERO, s1, d);
1041 M_AND(d, REG_ITMP2, d);
1043 M_ISUB(REG_ZERO, d, d);
1044 emit_store_dst(jd, iptr, d);
1047 #if SIZEOF_VOID_P == 8
1049 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1050 /* val.i = constant */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 M_LSRA_IMM(s1, 63, REG_ITMP2);
1055 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1056 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1057 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1058 emit_store_dst(jd, iptr, d);
1061 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1062 /* val.l = constant */
1064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1065 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1067 M_MOV(s1, REG_ITMP1);
1070 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1071 M_AND_IMM(s1, iptr->sx.val.l, d);
1074 M_LSUB(REG_ZERO, s1, d);
1075 M_AND_IMM(d, iptr->sx.val.l, d);
1078 LCONST(REG_ITMP2, iptr->sx.val.l);
1079 M_AND(s1, REG_ITMP2, d);
1082 M_LSUB(REG_ZERO, s1, d);
1083 M_AND(d, REG_ITMP2, d);
1085 M_LSUB(REG_ZERO, d, d);
1086 emit_store_dst(jd, iptr, d);
1089 #endif /* SIZEOF_VOID_P == 8 */
1091 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1094 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1095 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1097 emit_store_dst(jd, iptr, d);
1100 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1101 /* sx.val.i = constant */
1103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1104 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1105 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1106 emit_store_dst(jd, iptr, d);
1109 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1113 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1115 emit_store_dst(jd, iptr, d);
1118 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1119 /* sx.val.i = constant */
1121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1122 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1123 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1124 emit_store_dst(jd, iptr, d);
1127 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1130 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1137 /* sx.val.i = constant */
1139 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1141 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1147 #if SIZEOF_VOID_P == 8
1148 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1149 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1154 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1157 M_ISLL(s2, 26, REG_ITMP1);
1158 M_BGEZ(REG_ITMP1, 3);
1161 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1163 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1166 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1168 M_BEQZ(REG_ITMP1, 4);
1169 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1171 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1172 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1173 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1176 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1179 emit_store_dst(jd, iptr, d);
1182 #if SIZEOF_VOID_P == 8
1184 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1185 /* sx.val.i = constant */
1187 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1188 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1189 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1196 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1197 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1199 emit_store_dst(jd, iptr, d);
1202 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1203 /* sx.val.i = constant */
1205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1206 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1207 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1214 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1215 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1221 /* sx.val.i = constant */
1223 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1224 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1225 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1226 emit_store_dst(jd, iptr, d);
1229 #endif /* SIZEOF_VOID_P == 8 */
1231 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1237 emit_store_dst(jd, iptr, d);
1240 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1241 /* sx.val.i = constant */
1243 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1244 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1245 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1246 M_AND_IMM(s1, iptr->sx.val.i, d);
1248 ICONST(REG_ITMP2, iptr->sx.val.i);
1249 M_AND(s1, REG_ITMP2, d);
1251 emit_store_dst(jd, iptr, d);
1254 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1256 #if SIZEOF_VOID_P == 8
1257 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1258 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1259 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1262 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1263 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1265 M_AND(s1, s2, GET_LOW_REG(d));
1266 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1267 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1268 M_AND(s1, s2, GET_HIGH_REG(d));
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1274 /* sx.val.l = constant */
1276 #if SIZEOF_VOID_P == 8
1277 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1279 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1280 M_AND_IMM(s1, iptr->sx.val.l, d);
1282 LCONST(REG_ITMP2, iptr->sx.val.l);
1283 M_AND(s1, REG_ITMP2, d);
1286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1287 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1288 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1289 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1290 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1293 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1294 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1295 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1296 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1297 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1306 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1307 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1309 emit_store_dst(jd, iptr, d);
1312 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1313 /* sx.val.i = constant */
1315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1317 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1318 M_OR_IMM(s1, iptr->sx.val.i, d);
1320 ICONST(REG_ITMP2, iptr->sx.val.i);
1321 M_OR(s1, REG_ITMP2, d);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1328 #if SIZEOF_VOID_P == 8
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1331 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1334 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1335 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1337 M_OR(s1, s2, GET_LOW_REG(d));
1338 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1339 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1340 M_OR(s1, s2, GET_HIGH_REG(d));
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1346 /* sx.val.l = constant */
1348 #if SIZEOF_VOID_P == 8
1349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1351 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1352 M_OR_IMM(s1, iptr->sx.val.l, d);
1354 LCONST(REG_ITMP2, iptr->sx.val.l);
1355 M_OR(s1, REG_ITMP2, d);
1358 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1359 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1360 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1361 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1362 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1365 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1366 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1367 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1368 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1369 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1372 emit_store_dst(jd, iptr, d);
1375 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1377 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1378 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1379 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1381 emit_store_dst(jd, iptr, d);
1384 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1385 /* sx.val.i = constant */
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1389 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1390 M_XOR_IMM(s1, iptr->sx.val.i, d);
1392 ICONST(REG_ITMP2, iptr->sx.val.i);
1393 M_XOR(s1, REG_ITMP2, d);
1395 emit_store_dst(jd, iptr, d);
1398 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1400 #if SIZEOF_VOID_P == 8
1401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1402 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1406 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1407 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1408 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1409 M_XOR(s1, s2, GET_LOW_REG(d));
1410 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1411 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1412 M_XOR(s1, s2, GET_HIGH_REG(d));
1414 emit_store_dst(jd, iptr, d);
1417 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1418 /* sx.val.l = constant */
1420 #if SIZEOF_VOID_P == 8
1421 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1423 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1424 M_XOR_IMM(s1, iptr->sx.val.l, d);
1426 LCONST(REG_ITMP2, iptr->sx.val.l);
1427 M_XOR(s1, REG_ITMP2, d);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1431 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1433 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1434 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1437 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1438 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1439 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1440 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1441 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1444 emit_store_dst(jd, iptr, d);
1448 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1450 #if SIZEOF_VOID_P == 8
1451 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1452 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1454 M_CMPLT(s1, s2, REG_ITMP3);
1455 M_CMPLT(s2, s1, REG_ITMP1);
1456 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1458 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1459 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1460 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1461 M_CMPLT(s1, s2, REG_ITMP3);
1462 M_CMPLT(s2, s1, REG_ITMP1);
1463 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1466 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1467 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1468 M_CMPULT(s1, s2, REG_ITMP3);
1469 M_CMPULT(s2, s1, REG_ITMP1);
1470 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1472 emit_store_dst(jd, iptr, d);
1476 /* floating operations ************************************************/
1478 case ICMD_FNEG: /* ..., value ==> ..., - value */
1480 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1481 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1483 emit_store_dst(jd, iptr, d);
1486 case ICMD_DNEG: /* ..., value ==> ..., - value */
1488 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1489 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1491 emit_store_dst(jd, iptr, d);
1494 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1496 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1497 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1498 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1505 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1509 emit_store_dst(jd, iptr, d);
1512 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1514 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1515 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1518 emit_store_dst(jd, iptr, d);
1521 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1523 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1524 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1525 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1527 emit_store_dst(jd, iptr, d);
1530 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1532 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1533 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1534 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1536 emit_store_dst(jd, iptr, d);
1539 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1541 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1543 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1545 emit_store_dst(jd, iptr, d);
1548 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1550 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1552 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1554 emit_store_dst(jd, iptr, d);
1557 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1559 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1561 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1563 emit_store_dst(jd, iptr, d);
1567 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1569 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1570 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1571 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1572 M_FDIV(s1,s2, REG_FTMP3);
1573 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1574 M_CVTLF(REG_FTMP3, REG_FTMP3);
1575 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1576 M_FSUB(s1, REG_FTMP3, d);
1577 emit_store_dst(jd, iptr, d);
1580 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1582 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1583 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1584 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1585 M_DDIV(s1,s2, REG_FTMP3);
1586 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1587 M_CVTLD(REG_FTMP3, REG_FTMP3);
1588 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1589 M_DSUB(s1, REG_FTMP3, d);
1590 emit_store_dst(jd, iptr, d);
1594 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1597 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1600 emit_store_dst(jd, iptr, d);
1603 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1609 emit_store_dst(jd, iptr, d);
1613 /* XXX these do not work correctly */
1615 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1617 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1619 M_TRUNCFI(s1, REG_FTMP1);
1620 M_MOVDI(REG_FTMP1, d);
1622 emit_store_dst(jd, iptr, d);
1625 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1627 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1629 M_TRUNCDI(s1, REG_FTMP1);
1630 M_MOVDI(REG_FTMP1, d);
1632 emit_store_dst(jd, iptr, d);
1635 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1637 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1639 M_TRUNCFL(s1, REG_FTMP1);
1640 M_MOVDL(REG_FTMP1, d);
1642 emit_store_dst(jd, iptr, d);
1645 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1647 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1649 M_TRUNCDL(s1, REG_FTMP1);
1650 M_MOVDL(REG_FTMP1, d);
1652 emit_store_dst(jd, iptr, d);
1656 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1658 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1659 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1661 emit_store_dst(jd, iptr, d);
1664 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1666 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1667 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1669 emit_store_dst(jd, iptr, d);
1672 #if SUPPORT_FLOAT_CMP
1673 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1675 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1676 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1680 M_AADD_IMM(REG_ZERO, 1, d);
1684 M_ASUB_IMM(REG_ZERO, 1, d);
1685 M_CMOVT(REG_ZERO, d);
1686 emit_store_dst(jd, iptr, d);
1689 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1691 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1692 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1693 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1696 M_ASUB_IMM(REG_ZERO, 1, d);
1700 M_AADD_IMM(REG_ZERO, 1, d);
1701 M_CMOVT(REG_ZERO, d);
1702 emit_store_dst(jd, iptr, d);
1706 #if SUPPORT_DOUBLE_CMP
1707 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1709 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1714 M_AADD_IMM(REG_ZERO, 1, d);
1718 M_ASUB_IMM(REG_ZERO, 1, d);
1719 M_CMOVT(REG_ZERO, d);
1720 emit_store_dst(jd, iptr, d);
1723 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1725 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1726 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1730 M_ASUB_IMM(REG_ZERO, 1, d);
1734 M_AADD_IMM(REG_ZERO, 1, d);
1735 M_CMOVT(REG_ZERO, d);
1736 emit_store_dst(jd, iptr, d);
1741 /* memory operations **************************************************/
1743 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1747 /* implicit null-pointer check */
1748 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1749 emit_store_dst(jd, iptr, d);
1752 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1755 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1757 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1758 M_AADD(s2, s1, REG_ITMP3);
1759 /* implicit null-pointer check */
1760 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1761 emit_store_dst(jd, iptr, d);
1764 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1769 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1770 M_AADD(s2, s1, REG_ITMP3);
1771 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1772 /* implicit null-pointer check */
1773 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1774 emit_store_dst(jd, iptr, d);
1777 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1780 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1782 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1783 M_AADD(s2, s1, REG_ITMP3);
1784 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1785 /* implicit null-pointer check */
1786 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1787 emit_store_dst(jd, iptr, d);
1790 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1793 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1795 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1796 M_ASLL_IMM(s2, 2, REG_ITMP3);
1797 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1798 /* implicit null-pointer check */
1799 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1800 emit_store_dst(jd, iptr, d);
1803 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1807 #if SIZEOF_VOID_P == 8
1808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1812 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1813 M_ASLL_IMM(s2, 3, REG_ITMP3);
1814 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1815 /* implicit null-pointer check */
1816 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1817 emit_store_dst(jd, iptr, d);
1820 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1823 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1824 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1825 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1826 M_ASLL_IMM(s2, 2, REG_ITMP3);
1827 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1828 /* implicit null-pointer check */
1829 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1830 emit_store_dst(jd, iptr, d);
1833 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1836 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1837 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1838 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1839 M_ASLL_IMM(s2, 3, REG_ITMP3);
1840 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1841 /* implicit null-pointer check */
1842 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1843 emit_store_dst(jd, iptr, d);
1846 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1851 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1852 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1853 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1854 /* implicit null-pointer check */
1855 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1856 emit_store_dst(jd, iptr, d);
1860 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1863 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1864 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1865 M_AADD(s2, s1, REG_ITMP1);
1866 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1867 /* implicit null-pointer check */
1868 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1871 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1872 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1875 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1876 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1877 M_AADD(s2, s1, REG_ITMP1);
1878 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1879 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1880 /* implicit null-pointer check */
1881 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1884 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1887 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1888 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1889 M_ASLL_IMM(s2, 2, REG_ITMP2);
1890 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1891 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1892 /* implicit null-pointer check */
1893 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1896 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1900 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1901 M_ASLL_IMM(s2, 3, REG_ITMP2);
1902 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1903 #if SIZEOF_VOID_P == 8
1904 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1906 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1908 /* implicit null-pointer check */
1909 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1912 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1915 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1916 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1917 M_ASLL_IMM(s2, 2, REG_ITMP2);
1918 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1919 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1920 /* implicit null-pointer check */
1921 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1924 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1928 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1929 M_ASLL_IMM(s2, 3, REG_ITMP2);
1930 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1931 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1932 /* implicit null-pointer check */
1933 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1937 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1940 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1941 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1942 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1944 M_INTMOVE(s1, REG_A0);
1945 M_INTMOVE(s3, REG_A1);
1946 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1947 M_ALD(REG_ITMP3, REG_PV, disp);
1948 M_JSR(REG_RA, REG_ITMP3);
1950 emit_exception_check(cd, iptr);
1952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1954 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1955 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1956 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1957 /* implicit null-pointer check */
1958 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1962 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1965 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1966 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1967 M_AADD(s2, s1, REG_ITMP1);
1968 /* implicit null-pointer check */
1969 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1972 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1973 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1976 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1977 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1978 M_AADD(s2, s1, REG_ITMP1);
1979 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1980 /* implicit null-pointer check */
1981 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1984 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1988 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1989 M_ASLL_IMM(s2, 2, REG_ITMP2);
1990 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1991 /* implicit null-pointer check */
1992 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1995 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1999 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2000 M_ASLL_IMM(s2, 3, REG_ITMP2);
2001 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2002 /* implicit null-pointer check */
2003 #if SIZEOF_VOID_P == 8
2004 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2006 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
2010 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2012 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2013 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2014 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2015 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
2016 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2017 /* implicit null-pointer check */
2018 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2022 case ICMD_GETSTATIC: /* ... ==> ..., value */
2024 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2025 uf = iptr->sx.s23.s3.uf;
2026 fieldtype = uf->fieldref->parseddesc.fd->type;
2027 disp = dseg_add_unique_address(cd, uf);
2029 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2032 fi = iptr->sx.s23.s3.fmiref->p.field;
2033 fieldtype = fi->type;
2034 disp = dseg_add_address(cd, &(fi->value));
2036 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2037 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2040 M_ALD(REG_ITMP1, REG_PV, disp);
2042 switch (fieldtype) {
2044 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2045 M_ILD_INTERN(d, REG_ITMP1, 0);
2048 #if SIZEOF_VOID_P == 8
2049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2053 M_LLD_INTERN(d, REG_ITMP1, 0);
2056 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2057 M_ALD_INTERN(d, REG_ITMP1, 0);
2060 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2061 M_FLD_INTERN(d, REG_ITMP1, 0);
2064 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2065 M_DLD_INTERN(d, REG_ITMP1, 0);
2068 emit_store_dst(jd, iptr, d);
2071 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2073 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2074 uf = iptr->sx.s23.s3.uf;
2075 fieldtype = uf->fieldref->parseddesc.fd->type;
2076 disp = dseg_add_unique_address(cd, uf);
2078 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2081 fi = iptr->sx.s23.s3.fmiref->p.field;
2082 fieldtype = fi->type;
2083 disp = dseg_add_address(cd, &(fi->value));
2085 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2086 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2089 M_ALD(REG_ITMP1, REG_PV, disp);
2091 switch (fieldtype) {
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2094 M_IST_INTERN(s1, REG_ITMP1, 0);
2097 #if SIZEOF_VOID_P == 8
2098 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2100 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2102 M_LST_INTERN(s1, REG_ITMP1, 0);
2105 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2106 M_AST_INTERN(s1, REG_ITMP1, 0);
2109 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2110 M_FST_INTERN(s1, REG_ITMP1, 0);
2113 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2114 M_DST_INTERN(s1, REG_ITMP1, 0);
2119 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2120 /* val = value (in current instruction) */
2121 /* following NOP) */
2123 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2124 uf = iptr->sx.s23.s3.uf;
2125 fieldtype = uf->fieldref->parseddesc.fd->type;
2126 disp = dseg_add_unique_address(cd, uf);
2128 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2131 fi = iptr->sx.s23.s3.fmiref->p.field;
2132 fieldtype = fi->type;
2133 disp = dseg_add_address(cd, &(fi->value));
2135 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2136 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2139 M_ALD(REG_ITMP1, REG_PV, disp);
2141 switch (fieldtype) {
2143 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2146 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2149 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2152 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2155 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2161 case ICMD_GETFIELD: /* ... ==> ..., value */
2163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2164 emit_nullpointer_check(cd, iptr, s1);
2166 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2167 uf = iptr->sx.s23.s3.uf;
2168 fieldtype = uf->fieldref->parseddesc.fd->type;
2171 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2174 fi = iptr->sx.s23.s3.fmiref->p.field;
2175 fieldtype = fi->type;
2179 switch (fieldtype) {
2181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2185 #if SIZEOF_VOID_P == 8
2186 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2189 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2190 M_LLD_GETFIELD(d, s1, disp);
2194 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2198 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2202 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2206 emit_store_dst(jd, iptr, d);
2209 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2212 emit_nullpointer_check(cd, iptr, s1);
2214 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2215 uf = iptr->sx.s23.s3.uf;
2216 fieldtype = uf->fieldref->parseddesc.fd->type;
2220 fi = iptr->sx.s23.s3.fmiref->p.field;
2221 fieldtype = fi->type;
2225 #if SIZEOF_VOID_P == 8
2226 if (IS_INT_LNG_TYPE(fieldtype))
2227 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2229 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2231 if (IS_INT_LNG_TYPE(fieldtype)) {
2232 if (IS_2_WORD_TYPE(fieldtype))
2233 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2235 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2238 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2241 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2242 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2244 switch (fieldtype) {
2246 M_IST(s2, s1, disp);
2249 M_LST(s2, s1, disp);
2252 M_AST(s2, s1, disp);
2255 M_FST(s2, s1, disp);
2258 M_DST(s2, s1, disp);
2263 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2266 emit_nullpointer_check(cd, iptr, s1);
2268 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2269 unresolved_field *uf = iptr->sx.s23.s3.uf;
2271 fieldtype = uf->fieldref->parseddesc.fd->type;
2274 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2277 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2278 fieldtype = fi->type;
2282 switch (fieldtype) {
2284 M_IST(REG_ZERO, s1, disp);
2287 M_LST(REG_ZERO, s1, disp);
2290 M_AST(REG_ZERO, s1, disp);
2293 M_FST(REG_ZERO, s1, disp);
2296 M_DST(REG_ZERO, s1, disp);
2302 /* branch operations **************************************************/
2304 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2307 M_INTMOVE(s1, REG_ITMP1_XPTR);
2309 #ifdef ENABLE_VERIFIER
2310 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2311 uc = iptr->sx.s23.s2.uc;
2313 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2315 #endif /* ENABLE_VERIFIER */
2317 disp = dseg_add_functionptr(cd, asm_handle_exception);
2318 M_ALD(REG_ITMP2, REG_PV, disp);
2319 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2321 M_NOP; /* nop ensures that XPC is less than the end */
2322 /* of basic block */
2326 case ICMD_GOTO: /* ... ==> ... */
2327 case ICMD_RET: /* ... ==> ... */
2329 emit_br(cd, iptr->dst.block);
2333 case ICMD_JSR: /* ... ==> ... */
2335 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2339 case ICMD_IFNULL: /* ..., value ==> ... */
2340 case ICMD_IFNONNULL:
2342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2343 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2346 case ICMD_IFEQ: /* ..., value ==> ... */
2348 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2349 if (iptr->sx.val.i == 0)
2350 emit_beqz(cd, iptr->dst.block, s1);
2352 ICONST(REG_ITMP2, iptr->sx.val.i);
2353 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2357 case ICMD_IFLT: /* ..., value ==> ... */
2359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360 if (iptr->sx.val.i == 0)
2361 emit_bltz(cd, iptr->dst.block, s1);
2363 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2364 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2366 ICONST(REG_ITMP2, iptr->sx.val.i);
2367 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2369 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2373 case ICMD_IFLE: /* ..., value ==> ... */
2375 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2376 if (iptr->sx.val.i == 0)
2377 emit_blez(cd, iptr->dst.block, s1);
2379 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2380 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2381 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2384 ICONST(REG_ITMP2, iptr->sx.val.i);
2385 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2386 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2391 case ICMD_IFNE: /* ..., value ==> ... */
2393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2394 if (iptr->sx.val.i == 0)
2395 emit_bnez(cd, iptr->dst.block, s1);
2397 ICONST(REG_ITMP2, iptr->sx.val.i);
2398 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2402 case ICMD_IFGT: /* ..., value ==> ... */
2404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2405 if (iptr->sx.val.i == 0)
2406 emit_bgtz(cd, iptr->dst.block, s1);
2408 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2409 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2410 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2413 ICONST(REG_ITMP2, iptr->sx.val.i);
2414 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2415 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2420 case ICMD_IFGE: /* ..., value ==> ... */
2422 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2423 if (iptr->sx.val.i == 0)
2424 emit_bgez(cd, iptr->dst.block, s1);
2426 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2427 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2429 ICONST(REG_ITMP2, iptr->sx.val.i);
2430 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2432 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2436 case ICMD_IF_LEQ: /* ..., value ==> ... */
2438 #if SIZEOF_VOID_P == 8
2439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2440 if (iptr->sx.val.l == 0)
2441 emit_beqz(cd, iptr->dst.block, s1);
2443 LCONST(REG_ITMP2, iptr->sx.val.l);
2444 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2447 if (iptr->sx.val.l == 0) {
2448 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2449 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2450 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2453 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2454 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2455 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2456 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2457 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2458 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2459 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2460 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2465 case ICMD_IF_LLT: /* ..., value ==> ... */
2467 #if SIZEOF_VOID_P == 8
2468 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2469 if (iptr->sx.val.l == 0)
2470 emit_bltz(cd, iptr->dst.block, s1);
2472 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2473 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2475 LCONST(REG_ITMP2, iptr->sx.val.l);
2476 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2478 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2481 if (iptr->sx.val.l == 0) {
2482 /* if high word is less than zero, the whole long is too */
2483 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2484 emit_bltz(cd, iptr->dst.block, s1);
2487 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2488 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2489 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2490 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2491 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2492 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2494 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2495 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2496 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2501 case ICMD_IF_LLE: /* ..., value ==> ... */
2503 #if SIZEOF_VOID_P == 8
2504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2505 if (iptr->sx.val.l == 0)
2506 emit_blez(cd, iptr->dst.block, s1);
2508 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2509 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2510 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2513 LCONST(REG_ITMP2, iptr->sx.val.l);
2514 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2515 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2519 if (iptr->sx.val.l == 0) {
2520 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2521 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2523 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2524 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2527 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2528 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2529 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2530 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2531 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2532 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2534 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2535 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2536 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2541 case ICMD_IF_LNE: /* ..., value ==> ... */
2543 #if SIZEOF_VOID_P == 8
2544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2545 if (iptr->sx.val.l == 0)
2546 emit_bnez(cd, iptr->dst.block, s1);
2548 LCONST(REG_ITMP2, iptr->sx.val.l);
2549 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2552 if (iptr->sx.val.l == 0) {
2553 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2554 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2555 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2558 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2559 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2560 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2561 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2562 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2563 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2564 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2565 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2570 case ICMD_IF_LGT: /* ..., value ==> ... */
2572 #if SIZEOF_VOID_P == 8
2573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2574 if (iptr->sx.val.l == 0)
2575 emit_bgtz(cd, iptr->dst.block, s1);
2577 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2578 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2579 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2582 LCONST(REG_ITMP2, iptr->sx.val.l);
2583 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2584 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2588 if (iptr->sx.val.l == 0) {
2589 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2590 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2591 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2593 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2596 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2597 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2598 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2599 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2600 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2601 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2603 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2604 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2605 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2610 case ICMD_IF_LGE: /* ..., value ==> ... */
2612 #if SIZEOF_VOID_P == 8
2613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2614 if (iptr->sx.val.l == 0)
2615 emit_bgez(cd, iptr->dst.block, s1);
2617 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2618 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2621 LCONST(REG_ITMP2, iptr->sx.val.l);
2622 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2624 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2627 if (iptr->sx.val.l == 0) {
2628 /* if high word is greater equal zero, the whole long is too */
2629 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2630 emit_bgez(cd, iptr->dst.block, s1);
2633 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2634 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2635 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2636 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2637 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2638 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2640 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2641 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2642 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2647 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2648 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2649 #if SIZEOF_VOID_P == 8
2650 case ICMD_IF_LCMPEQ:
2653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2655 emit_beq(cd, iptr->dst.block, s1, s2);
2658 #if SIZEOF_VOID_P == 4
2659 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2660 /* op1 = target JavaVM pc */
2662 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2663 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2664 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2666 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2667 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2668 emit_beq(cd, iptr->dst.block, s1, s2);
2672 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2673 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2674 #if SIZEOF_VOID_P == 8
2675 case ICMD_IF_LCMPNE:
2678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2680 emit_bne(cd, iptr->dst.block, s1, s2);
2683 #if SIZEOF_VOID_P == 4
2684 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2686 /* TODO: could be optimized (XOR or SUB) */
2687 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2688 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2689 emit_bne(cd, iptr->dst.block, s1, s2);
2690 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2691 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2692 emit_bne(cd, iptr->dst.block, s1, s2);
2696 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2697 #if SIZEOF_VOID_P == 8
2698 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2703 M_CMPLT(s1, s2, REG_ITMP3);
2704 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2707 #if SIZEOF_VOID_P == 4
2708 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2710 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2711 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2712 M_CMPLT(s1, s2, REG_ITMP3);
2713 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2714 M_CMPGT(s1, s2, REG_ITMP3);
2715 /* load low-bits before the branch, so we know the distance */
2716 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2717 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2718 M_BNEZ(REG_ITMP3, 4); /* XXX */
2720 M_CMPULT(s1, s2, REG_ITMP3);
2721 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2725 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2726 #if SIZEOF_VOID_P == 8
2727 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2732 M_CMPGT(s1, s2, REG_ITMP3);
2733 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2736 #if SIZEOF_VOID_P == 4
2737 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2739 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2740 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2741 M_CMPGT(s1, s2, REG_ITMP3);
2742 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2743 M_CMPLT(s1, s2, REG_ITMP3);
2744 /* load low-bits before the branch, so we know the distance */
2745 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2746 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2747 M_BNEZ(REG_ITMP3, 4); /* XXX */
2749 M_CMPUGT(s1, s2, REG_ITMP3);
2750 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2754 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2755 #if SIZEOF_VOID_P == 8
2756 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2760 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2761 M_CMPGT(s1, s2, REG_ITMP3);
2762 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2765 #if SIZEOF_VOID_P == 4
2766 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2768 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2769 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2770 M_CMPLT(s1, s2, REG_ITMP3);
2771 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2772 M_CMPGT(s1, s2, REG_ITMP3);
2773 /* load low-bits before the branch, so we know the distance */
2774 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2775 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2776 M_BNEZ(REG_ITMP3, 4); /* XXX */
2778 M_CMPUGT(s1, s2, REG_ITMP3);
2779 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2783 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2784 #if SIZEOF_VOID_P == 8
2785 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2789 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2790 M_CMPLT(s1, s2, REG_ITMP3);
2791 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2794 #if SIZEOF_VOID_P == 4
2795 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2797 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2798 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2799 M_CMPGT(s1, s2, REG_ITMP3);
2800 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2801 M_CMPLT(s1, s2, REG_ITMP3);
2802 /* load low-bits before the branch, so we know the distance */
2803 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2804 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2805 M_BNEZ(REG_ITMP3, 4); /* XXX */
2807 M_CMPULT(s1, s2, REG_ITMP3);
2808 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2812 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2813 #if SIZEOF_VOID_P == 8
2817 REPLACEMENT_POINT_RETURN(cd, iptr);
2818 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2819 M_INTMOVE(s1, REG_RESULT);
2820 goto nowperformreturn;
2822 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2824 REPLACEMENT_POINT_RETURN(cd, iptr);
2825 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2826 M_INTMOVE(s1, REG_RESULT);
2828 #ifdef ENABLE_VERIFIER
2829 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2830 uc = iptr->sx.s23.s2.uc;
2832 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2834 #endif /* ENABLE_VERIFIER */
2835 goto nowperformreturn;
2837 #if SIZEOF_VOID_P == 4
2838 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2840 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2841 M_LNGMOVE(s1, REG_RESULT_PACKED);
2842 goto nowperformreturn;
2845 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2846 REPLACEMENT_POINT_RETURN(cd, iptr);
2847 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2848 M_FLTMOVE(s1, REG_FRESULT);
2849 goto nowperformreturn;
2851 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2853 REPLACEMENT_POINT_RETURN(cd, iptr);
2854 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2855 M_DBLMOVE(s1, REG_FRESULT);
2856 goto nowperformreturn;
2858 case ICMD_RETURN: /* ... ==> ... */
2860 REPLACEMENT_POINT_RETURN(cd, iptr);
2866 p = cd->stackframesize;
2868 #if !defined(NDEBUG)
2869 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2870 emit_verbosecall_exit(jd);
2873 #if defined(ENABLE_THREADS)
2874 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2875 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2876 M_ALD(REG_ITMP3, REG_PV, disp);
2878 /* we need to save the proper return value */
2880 switch (iptr->opc) {
2883 #if SIZEOF_VOID_P == 8
2886 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2887 M_JSR(REG_RA, REG_ITMP3);
2888 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2890 #if SIZEOF_VOID_P == 4
2892 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2893 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2894 M_JSR(REG_RA, REG_ITMP3);
2900 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2901 M_JSR(REG_RA, REG_ITMP3);
2902 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2905 M_JSR(REG_RA, REG_ITMP3);
2906 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2910 /* and now restore the proper return value */
2912 switch (iptr->opc) {
2915 #if SIZEOF_VOID_P == 8
2918 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2920 #if SIZEOF_VOID_P == 4
2922 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2927 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2933 /* restore return address */
2935 if (!jd->isleafmethod) {
2936 p--; M_ALD(REG_RA, REG_SP, p * 8);
2939 /* restore saved registers */
2941 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2942 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2944 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2945 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2948 /* deallocate stack and return */
2950 if (cd->stackframesize) {
2953 disp = cd->stackframesize * 8;
2954 lo = (short) (disp);
2955 hi = (short) (((disp) - lo) >> 16);
2959 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2961 M_LUI(REG_ITMP3,hi);
2962 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2964 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2977 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2980 branch_target_t *table;
2982 table = iptr->dst.table;
2984 l = iptr->sx.s23.s2.tablelow;
2985 i = iptr->sx.s23.s3.tablehigh;
2987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2989 {M_INTMOVE(s1, REG_ITMP1);}
2990 else if (l <= 32768) {
2991 M_IADD_IMM(s1, -l, REG_ITMP1);
2994 ICONST(REG_ITMP2, l);
2995 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2998 /* number of targets */
3003 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3004 emit_beqz(cd, table[0].block, REG_ITMP2);
3006 /* build jump table top down and use address of lowest entry */
3011 dseg_add_target(cd, table->block);
3016 /* length of dataseg after last dseg_add_target is used by load */
3018 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
3019 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3020 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3027 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3030 lookup_target_t *lookup;
3032 lookup = iptr->dst.lookup;
3034 i = iptr->sx.s23.s2.lookupcount;
3036 MCODECHECK((i<<2)+8);
3037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3040 ICONST(REG_ITMP2, lookup->value);
3041 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3045 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3051 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3053 bte = iptr->sx.s23.s3.bte;
3057 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3059 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3060 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3061 case ICMD_INVOKEINTERFACE:
3063 REPLACEMENT_POINT_INVOKE(cd, iptr);
3065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3067 um = iptr->sx.s23.s3.um;
3068 md = um->methodref->parseddesc.md;
3071 lm = iptr->sx.s23.s3.fmiref->p.method;
3073 md = lm->parseddesc;
3077 s3 = md->paramcount;
3079 MCODECHECK((s3 << 1) + 64);
3081 /* copy arguments to registers or stack location */
3083 for (s3 = s3 - 1; s3 >= 0; s3--) {
3084 var = VAR(iptr->sx.s23.s2.args[s3]);
3085 d = md->params[s3].regoff;
3087 if (var->flags & PREALLOC)
3090 if (IS_INT_LNG_TYPE(var->type)) {
3091 #if SIZEOF_VOID_P == 8
3092 if (!md->params[s3].inmemory) {
3093 s1 = emit_load(jd, iptr, var, d);
3097 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3098 M_LST(s1, REG_SP, d * 8);
3101 if (!md->params[s3].inmemory) {
3102 s1 = emit_load(jd, iptr, var, d);
3104 if (IS_2_WORD_TYPE(var->type))
3110 if (IS_2_WORD_TYPE(var->type)) {
3111 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3112 M_LST(s1, REG_SP, d * 8);
3115 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3116 M_IST(s1, REG_SP, d * 8);
3122 if (!md->params[s3].inmemory) {
3123 #if SIZEOF_VOID_P == 8
3124 s1 = emit_load(jd, iptr, var, d);
3125 if (IS_2_WORD_TYPE(var->type))
3131 ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3132 s1 = emit_load(jd, iptr, var, d);
3133 if (IS_2_WORD_TYPE(var->type))
3139 if (IS_2_WORD_TYPE(var->type)) {
3140 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3141 M_MFC1(GET_LOW_REG(d), s1);
3142 M_MFC1(GET_HIGH_REG(d), s1 + 1);
3146 s1 = emit_load(jd, iptr, var, d);
3154 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3155 if (IS_2_WORD_TYPE(var->type))
3156 M_DST(s1, REG_SP, d * 8);
3158 M_FST(s1, REG_SP, d * 8);
3163 switch (iptr->opc) {
3165 disp = dseg_add_functionptr(cd, bte->fp);
3167 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3169 /* generate the actual call */
3171 /* TWISTI: i actually don't know the reason for using
3172 REG_ITMP3 here instead of REG_PV. */
3174 M_JSR(REG_RA, REG_ITMP3);
3176 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3177 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3178 M_LDA(REG_PV, REG_RA, -disp);
3180 emit_exception_check(cd, iptr);
3183 case ICMD_INVOKESPECIAL:
3184 emit_nullpointer_check(cd, iptr, REG_A0);
3187 case ICMD_INVOKESTATIC:
3189 disp = dseg_add_unique_address(cd, um);
3191 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3195 disp = dseg_add_address(cd, lm->stubroutine);
3197 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3199 /* generate the actual call */
3201 M_JSR(REG_RA, REG_PV);
3203 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3204 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3205 M_LDA(REG_PV, REG_RA, -disp);
3208 case ICMD_INVOKEVIRTUAL:
3209 emit_nullpointer_check(cd, iptr, REG_A0);
3212 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3217 s1 = OFFSET(vftbl_t, table[0]) +
3218 sizeof(methodptr) * lm->vftblindex;
3220 /* implicit null-pointer check */
3221 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3222 M_ALD(REG_PV, REG_METHODPTR, s1);
3224 /* generate the actual call */
3226 M_JSR(REG_RA, REG_PV);
3228 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3229 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3230 M_LDA(REG_PV, REG_RA, -disp);
3233 case ICMD_INVOKEINTERFACE:
3234 emit_nullpointer_check(cd, iptr, REG_A0);
3237 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3243 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3244 sizeof(methodptr*) * lm->class->index;
3246 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3249 /* implicit null-pointer check */
3250 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3251 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3252 M_ALD(REG_PV, REG_METHODPTR, s2);
3254 /* generate the actual call */
3256 M_JSR(REG_RA, REG_PV);
3258 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3259 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3260 M_LDA(REG_PV, REG_RA, -disp);
3264 /* store return value */
3266 d = md->returntype.type;
3268 if (d != TYPE_VOID) {
3269 if (IS_INT_LNG_TYPE(d)) {
3270 #if SIZEOF_VOID_P == 8
3271 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3272 M_INTMOVE(REG_RESULT, s1);
3274 if (IS_2_WORD_TYPE(d)) {
3275 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3276 M_LNGMOVE(REG_RESULT_PACKED, s1);
3279 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3280 M_INTMOVE(REG_RESULT, s1);
3285 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3286 if (IS_2_WORD_TYPE(d))
3287 M_DMOV(REG_FRESULT, s1);
3289 M_FMOV(REG_FRESULT, s1);
3291 emit_store_dst(jd, iptr, s1);
3296 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3297 /* val.a: (classinfo*) superclass */
3299 /* superclass is an interface:
3301 * OK if ((sub == NULL) ||
3302 * (sub->vftbl->interfacetablelength > super->index) &&
3303 * (sub->vftbl->interfacetable[-super->index] != NULL));
3305 * superclass is a class:
3307 * OK if ((sub == NULL) || (0
3308 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3309 * super->vftbl->diffvall));
3312 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3316 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3321 super = iptr->sx.s23.s3.c.cls;
3322 superindex = super->index;
3325 #if defined(ENABLE_THREADS)
3326 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3331 /* if class is not resolved, check which code to call */
3333 if (super == NULL) {
3334 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3336 cr = iptr->sx.s23.s3.c.ref;
3337 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3339 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3342 M_ILD(REG_ITMP2, REG_PV, disp);
3343 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3344 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3347 /* interface checkcast code */
3349 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3350 if (super == NULL) {
3351 cr = iptr->sx.s23.s3.c.ref;
3353 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3357 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3360 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3361 M_ILD(REG_ITMP3, REG_ITMP2,
3362 OFFSET(vftbl_t, interfacetablelength));
3363 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3364 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3366 M_ALD(REG_ITMP3, REG_ITMP2,
3367 OFFSET(vftbl_t, interfacetable[0]) -
3368 superindex * sizeof(methodptr*));
3369 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3372 emit_label_br(cd, BRANCH_LABEL_4);
3374 emit_label(cd, BRANCH_LABEL_3);
3377 /* class checkcast code */
3379 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3380 if (super == NULL) {
3381 emit_label(cd, BRANCH_LABEL_2);
3383 cr = iptr->sx.s23.s3.c.ref;
3384 disp = dseg_add_unique_address(cd, NULL);
3386 codegen_add_patch_ref(cd,
3387 PATCHER_checkcast_instanceof_class,
3391 disp = dseg_add_address(cd, super->vftbl);
3393 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3396 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3397 M_ALD(REG_ITMP3, REG_PV, disp);
3398 #if defined(ENABLE_THREADS)
3399 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3401 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3402 /* if (s1 != REG_ITMP1) { */
3403 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3404 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3405 /* #if defined(ENABLE_THREADS) */
3406 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3408 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3410 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3411 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3412 M_ALD(REG_ITMP3, REG_PV, disp);
3413 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3414 #if defined(ENABLE_THREADS)
3415 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3418 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3419 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3422 emit_label(cd, BRANCH_LABEL_5);
3425 if (super == NULL) {
3426 emit_label(cd, BRANCH_LABEL_1);
3427 emit_label(cd, BRANCH_LABEL_4);
3430 d = codegen_reg_of_dst(jd, iptr, s1);
3433 s1 = emit_load_s1(jd, iptr, REG_A0);
3434 M_INTMOVE(s1, REG_A0);
3436 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3437 cr = iptr->sx.s23.s3.c.ref;
3438 disp = dseg_add_unique_address(cd, NULL);
3440 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3444 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3446 M_ALD(REG_A1, REG_PV, disp);
3447 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3448 M_ALD(REG_ITMP3, REG_PV, disp);
3449 M_JSR(REG_RA, REG_ITMP3);
3452 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3453 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3455 d = codegen_reg_of_dst(jd, iptr, s1);
3459 emit_store_dst(jd, iptr, d);
3462 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3463 /* val.a: (classinfo*) superclass */
3465 /* superclass is an interface:
3467 * return (sub != NULL) &&
3468 * (sub->vftbl->interfacetablelength > super->index) &&
3469 * (sub->vftbl->interfacetable[-super->index] != NULL);
3471 * superclass is a class:
3473 * return ((sub != NULL) && (0
3474 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3475 * super->vftbl->diffvall));
3482 super = iptr->sx.s23.s3.c.cls;
3484 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3489 super = iptr->sx.s23.s3.c.cls;
3490 superindex = super->index;
3493 #if defined(ENABLE_THREADS)
3494 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3501 M_MOV(s1, REG_ITMP1);
3507 /* if class is not resolved, check which code to call */
3509 if (super == NULL) {
3510 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3512 cr = iptr->sx.s23.s3.c.ref;
3513 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3515 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3518 M_ILD(REG_ITMP3, REG_PV, disp);
3519 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3520 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3523 /* interface instanceof code */
3525 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3526 if (super == NULL) {
3527 cr = iptr->sx.s23.s3.c.ref;
3529 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3533 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3536 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3537 M_ILD(REG_ITMP3, REG_ITMP1,
3538 OFFSET(vftbl_t, interfacetablelength));
3539 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3540 M_BLEZ(REG_ITMP3, 3);
3542 M_ALD(REG_ITMP1, REG_ITMP1,
3543 OFFSET(vftbl_t, interfacetable[0]) -
3544 superindex * sizeof(methodptr*));
3545 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3548 emit_label_br(cd, BRANCH_LABEL_4);
3550 emit_label(cd, BRANCH_LABEL_3);
3553 /* class instanceof code */
3555 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3556 if (super == NULL) {
3557 emit_label(cd, BRANCH_LABEL_2);
3559 cr = iptr->sx.s23.s3.c.ref;
3560 disp = dseg_add_unique_address(cd, NULL);
3562 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3566 disp = dseg_add_address(cd, super->vftbl);
3568 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3571 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3572 M_ALD(REG_ITMP2, REG_PV, disp);
3573 #if defined(ENABLE_THREADS)
3574 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3576 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3577 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3578 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3579 #if defined(ENABLE_THREADS)
3580 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3582 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3583 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3587 emit_label(cd, BRANCH_LABEL_5);
3590 if (super == NULL) {
3591 emit_label(cd, BRANCH_LABEL_1);
3592 emit_label(cd, BRANCH_LABEL_4);
3595 emit_store_dst(jd, iptr, d);
3599 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3601 /* check for negative sizes and copy sizes to stack if necessary */
3603 MCODECHECK((iptr->s1.argcount << 1) + 64);
3605 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3607 var = VAR(iptr->sx.s23.s2.args[s1]);
3609 /* copy SAVEDVAR sizes to stack */
3611 if (!(var->flags & PREALLOC)) {
3612 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3613 #if SIZEOF_VOID_P == 8
3614 M_LST(s2, REG_SP, s1 * 8);
3616 M_IST(s2, REG_SP, (s1 + 2) * 8);
3621 /* a0 = dimension count */
3623 ICONST(REG_A0, iptr->s1.argcount);
3625 /* is patcher function set? */
3627 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3628 cr = iptr->sx.s23.s3.c.ref;
3629 disp = dseg_add_unique_address(cd, NULL);
3631 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3635 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3637 /* a1 = arraydescriptor */
3639 M_ALD(REG_A1, REG_PV, disp);
3641 /* a2 = pointer to dimensions = stack pointer */
3643 #if SIZEOF_VOID_P == 8
3644 M_MOV(REG_SP, REG_A2);
3646 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3649 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3650 M_ALD(REG_ITMP3, REG_PV, disp);
3651 M_JSR(REG_RA, REG_ITMP3);
3654 /* check for exception before result assignment */
3656 emit_exception_check(cd, iptr);
3658 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3659 M_INTMOVE(REG_RESULT, d);
3660 emit_store_dst(jd, iptr, d);
3664 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3669 } /* for instruction */
3671 MCODECHECK(64); /* XXX require smaller number? */
3673 /* At the end of a basic block we may have to append some nops,
3674 because the patcher stub calling code might be longer than the
3675 actual instruction. So codepatching does not change the
3676 following block unintentionally. */
3678 if (cd->mcodeptr < cd->lastmcodeptr) {
3679 while (cd->mcodeptr < cd->lastmcodeptr)
3683 } /* if (bptr -> flags >= BBREACHED) */
3684 } /* for basic block */
3686 dseg_createlinenumbertable(cd);
3688 /* generate stubs */
3690 emit_patcher_stubs(jd);
3691 REPLACEMENT_EMIT_STUBS(jd);
3693 /* everything's ok */
3699 /* codegen_emit_stub_compiler **************************************************
3701 Emits a stub routine which calls the compiler.
3703 *******************************************************************************/
3705 void codegen_emit_stub_compiler(jitdata *jd)
3710 /* get required compiler data */
3715 /* code for the stub */
3717 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3718 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3724 /* codegen_emit_stub_native ****************************************************
3726 Emits a stub routine which calls a native method.
3728 *******************************************************************************/
3730 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3740 s4 funcdisp; /* displacement of the function */
3742 /* get required compiler data */
3748 /* initialize variables */
3751 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3753 /* calculate stack frame size */
3755 cd->stackframesize =
3756 1 + /* return address */
3757 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3758 sizeof(localref_table) / SIZEOF_VOID_P +
3759 md->paramcount + /* for saving arguments over calls */
3760 #if SIZEOF_VOID_P == 4
3761 5 + /* additional save space (MIPS32) */
3763 1 + /* for saving return address */
3766 /* adjust stackframe size for 16-byte alignment */
3768 if (cd->stackframesize & 1)
3769 cd->stackframesize++;
3771 /* create method header */
3773 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3774 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3775 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3776 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3777 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3778 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3779 (void) dseg_addlinenumbertablesize(cd);
3780 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3782 /* generate stub code */
3784 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3785 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3787 #if !defined(NDEBUG)
3788 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3789 emit_verbosecall_enter(jd);
3792 /* get function address (this must happen before the stackframeinfo) */
3794 funcdisp = dseg_add_functionptr(cd, f);
3796 #if !defined(WITH_STATIC_CLASSPATH)
3798 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3801 /* save integer and float argument registers */
3803 #if SIZEOF_VOID_P == 8
3804 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3805 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3806 s1 = md->params[i].regoff;
3807 M_AST(s1, REG_SP, j * 8);
3812 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3813 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3814 if (!md->params[i].inmemory) {
3815 s1 = md->params[i].regoff;
3817 if (IS_2_WORD_TYPE(md->params[i].type))
3818 M_LST(s1, REG_SP, j * 8);
3820 M_IST(s1, REG_SP, j * 8);
3828 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3829 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3830 s1 = md->params[i].regoff;
3832 if (IS_2_WORD_TYPE(md->params[i].type))
3833 M_DST(s1, REG_SP, j * 8);
3835 M_FST(s1, REG_SP, j * 8);
3841 /* prepare data structures for native function call */
3843 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3844 M_MOV(REG_PV, REG_A1);
3845 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3846 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3847 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3848 M_ALD(REG_ITMP3, REG_PV, disp);
3849 M_JSR(REG_RA, REG_ITMP3);
3850 M_NOP; /* XXX fill me! */
3852 /* restore integer and float argument registers */
3854 #if SIZEOF_VOID_P == 8
3855 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3856 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3857 s1 = md->params[i].regoff;
3858 M_LLD(s1, REG_SP, j * 8);
3863 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3864 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3865 if (!md->params[i].inmemory) {
3866 s1 = md->params[i].regoff;
3868 if (IS_2_WORD_TYPE(md->params[i].type))
3869 M_LLD(s1, REG_SP, j * 8);
3871 M_ILD(s1, REG_SP, j * 8);
3879 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3880 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3881 s1 = md->params[i].regoff;
3883 if (IS_2_WORD_TYPE(md->params[i].type))
3884 M_DLD(s1, REG_SP, j * 8);
3886 M_FLD(s1, REG_SP, j * 8);
3892 /* copy or spill arguments to new locations */
3894 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3895 t = md->params[i].type;
3897 if (IS_INT_LNG_TYPE(t)) {
3898 if (!md->params[i].inmemory) {
3899 s1 = md->params[i].regoff;
3900 s2 = nmd->params[j].regoff;
3902 if (!nmd->params[j].inmemory) {
3903 #if SIZEOF_VOID_P == 8
3906 if (IS_2_WORD_TYPE(t))
3913 #if SIZEOF_VOID_P == 8
3914 M_LST(s1, REG_SP, s2 * 8);
3916 if (IS_2_WORD_TYPE(t))
3917 M_LST(s1, REG_SP, s2 * 4);
3919 M_IST(s1, REG_SP, s2 * 4);
3924 s1 = md->params[i].regoff + cd->stackframesize;
3925 s2 = nmd->params[j].regoff;
3927 #if SIZEOF_VOID_P == 8
3928 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3929 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3931 if (IS_2_WORD_TYPE(t)) {
3932 M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 8);
3933 M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
3936 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
3937 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3943 if (!md->params[i].inmemory) {
3944 s1 = md->params[i].regoff;
3945 s2 = nmd->params[j].regoff;
3947 if (!nmd->params[j].inmemory) {
3948 #if SIZEOF_VOID_P == 8
3949 if (IS_2_WORD_TYPE(t))
3954 /* On MIPS32 float arguments for native functions
3955 can never be in float argument registers, since
3956 the first argument is _always_ an integer
3957 argument (JNIenv) */
3959 if (IS_2_WORD_TYPE(t)) {
3960 /* double high/low order is endian
3961 independent: even numbered holds low
3962 32-bits, odd numbered high 32-bits */
3964 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3965 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3972 #if SIZEOF_VOID_P == 8
3973 if (IS_2_WORD_TYPE(t))
3974 M_DST(s1, REG_SP, s2 * 8);
3976 M_FST(s1, REG_SP, s2 * 8);
3978 /* s1 may have been originally in 2 int registers,
3979 but was moved out by the native function
3980 argument(s), just get low register */
3982 if (IS_2_WORD_TYPE(t))
3983 M_DST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3985 M_FST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3990 s1 = md->params[i].regoff + cd->stackframesize;
3991 s2 = nmd->params[j].regoff;
3993 if (IS_2_WORD_TYPE(t)) {
3994 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3995 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3998 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3999 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4005 /* put class into second argument register */
4007 if (m->flags & ACC_STATIC) {
4008 disp = dseg_add_address(cd, m->class);
4009 M_ALD(REG_A1, REG_PV, disp);
4012 /* put env into first argument register */
4014 disp = dseg_add_address(cd, _Jv_env);
4015 M_ALD(REG_A0, REG_PV, disp);
4017 /* do the native function call */
4019 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4020 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4021 M_NOP; /* delay slot */
4023 /* save return value */
4025 switch (md->returntype.type) {
4026 #if SIZEOF_VOID_P == 8
4030 M_LST(REG_RESULT, REG_SP, 0 * 8);
4034 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4039 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4042 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4046 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4053 #if !defined(NDEBUG)
4054 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4055 emit_verbosecall_exit(jd);
4058 /* remove native stackframe info */
4060 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4061 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4062 M_ALD(REG_ITMP3, REG_PV, disp);
4063 M_JSR(REG_RA, REG_ITMP3);
4064 M_NOP; /* XXX fill me! */
4065 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4067 /* restore return value */
4069 switch (md->returntype.type) {
4070 #if SIZEOF_VOID_P == 8
4074 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4078 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4083 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4086 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4090 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4097 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4099 /* check for exception */
4101 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4102 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4104 M_RET(REG_RA); /* return to caller */
4105 M_NOP; /* DELAY SLOT */
4107 /* handle exception */
4109 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4110 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4111 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4112 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4114 /* generate patcher stubs */
4116 emit_patcher_stubs(jd);
4121 * These are local overrides for various environment variables in Emacs.
4122 * Please do not remove this and leave it at the end of the file, where
4123 * Emacs will automagically detect them.
4124 * ---------------------------------------------------------------------
4127 * indent-tabs-mode: t
4131 * vim:noexpandtab:sw=4:ts=4: