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 7880 2007-05-07 14:13:45Z twisti $
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 #include "threads/lock-common.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/md.h"
59 #include "vm/jit/patcher.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
63 #if defined(ENABLE_LSRA)
64 # include "vm/jit/allocator/lsra.h"
67 #include "vmcore/class.h"
68 #include "vmcore/options.h"
71 /* codegen_emit ****************************************************************
73 Generates machine code.
75 *******************************************************************************/
77 bool codegen_emit(jitdata *jd)
83 s4 len, s1, s2, s3, d, disp;
89 constant_classref *cr;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 unresolved_method *um;
93 builtintable_entry *bte;
100 /* get required compiler data */
107 /* prevent compiler warnings */
122 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
124 /* space to save used callee saved registers */
126 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
127 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
129 cd->stackframesize = rd->memuse + savedregs_num;
131 #if defined(ENABLE_THREADS)
132 /* space to save argument of monitor_enter */
134 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
135 # if SIZEOF_VOID_P == 8
136 cd->stackframesize++;
139 cd->stackframesize += 2;
144 /* keep stack 16-byte aligned */
146 if (cd->stackframesize & 1)
147 cd->stackframesize++;
149 /* create method header */
151 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
152 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
154 #if defined(ENABLE_THREADS)
155 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
161 if (checksync && (m->flags & ACC_SYNCHRONIZED))
162 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
165 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
167 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
168 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
169 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 dseg_addlinenumbertablesize(cd);
171 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
173 /* create exception table */
175 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
176 dseg_add_target(cd, ex->start);
177 dseg_add_target(cd, ex->end);
178 dseg_add_target(cd, ex->handler);
179 (void) dseg_add_unique_address(cd, ex->catchtype.any);
182 /* create stack frame (if necessary) */
184 if (cd->stackframesize)
185 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
187 /* save return address and used callee saved registers */
189 p = cd->stackframesize;
190 if (!jd->isleafmethod) {
191 p--; M_AST(REG_RA, REG_SP, p * 8);
193 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
194 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
196 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
197 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
200 /* take arguments out of register or stack frame */
204 for (p = 0, l = 0; p < md->paramcount; p++) {
205 t = md->paramtypes[p].type;
207 varindex = jd->local_map[l * 5 + t];
210 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
213 if (varindex == UNUSED)
217 s1 = md->params[p].regoff;
219 if (IS_INT_LNG_TYPE(t)) { /* integer args */
220 if (!md->params[p].inmemory) { /* register arguments */
221 #if SIZEOF_VOID_P == 8
222 if (!(var->flags & INMEMORY))
223 M_INTMOVE(s1, var->vv.regoff);
225 M_LST(s1, REG_SP, var->vv.regoff * 8);
227 if (IS_2_WORD_TYPE(t)) {
228 if (!(var->flags & INMEMORY))
229 M_LNGMOVE(s1, var->vv.regoff);
231 M_LST(s1, REG_SP, var->vv.regoff * 8);
234 if (!(var->flags & INMEMORY))
235 M_INTMOVE(s1, var->vv.regoff);
237 M_IST(s1, REG_SP, var->vv.regoff * 8);
241 else { /* stack arguments */
242 if (!(var->flags & INMEMORY)) {
243 #if SIZEOF_VOID_P == 8
244 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
246 if (IS_2_WORD_TYPE(t))
247 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
249 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
253 var->vv.regoff = cd->stackframesize + s1;
256 else { /* floating args */
257 if (!md->params[p].inmemory) {
258 #if SIZEOF_VOID_P == 8
259 if (!(var->flags & INMEMORY)) {
260 if (IS_2_WORD_TYPE(t))
261 M_DMOV(s1, var->vv.regoff);
263 M_FMOV(s1, var->vv.regoff);
266 if (IS_2_WORD_TYPE(t))
267 M_DST(s1, REG_SP, var->vv.regoff * 8);
269 M_FST(s1, REG_SP, var->vv.regoff * 8);
273 ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
274 if (!(var->flags & INMEMORY)) {
275 if (IS_2_WORD_TYPE(t))
276 M_DBLMOVE(s1, var->vv.regoff);
278 M_FLTMOVE(s1, var->vv.regoff);
281 if (IS_2_WORD_TYPE(t))
282 M_DST(s1, REG_SP, var->vv.regoff * 8);
284 M_FST(s1, REG_SP, var->vv.regoff * 8);
288 if (IS_2_WORD_TYPE(t)) {
289 if (!(var->flags & INMEMORY)) {
290 M_MTC1(GET_LOW_REG(s1), var->vv.regoff);
291 M_MTC1(GET_HIGH_REG(s1), var->vv.regoff + 1);
295 M_LST(s1, REG_SP, var->vv.regoff * 8);
298 if (!(var->flags & INMEMORY)) {
299 M_MTC1(s1, var->vv.regoff);
303 M_IST(s1, REG_SP, var->vv.regoff * 8);
309 if (!(var->flags & INMEMORY)) {
310 if (IS_2_WORD_TYPE(t))
311 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
313 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
316 var->vv.regoff = cd->stackframesize + s1;
321 /* call monitorenter function */
323 #if defined(ENABLE_THREADS)
324 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
325 /* stack offset for monitor argument */
329 # if !defined(NDEBUG)
330 if (opt_verbosecall) {
331 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
333 for (p = 0; p < INT_ARG_CNT; p++)
334 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
336 for (p = 0; p < FLT_ARG_CNT; p++)
337 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
339 s1 += INT_ARG_CNT + FLT_ARG_CNT;
343 /* get correct lock object */
345 if (m->flags & ACC_STATIC) {
346 disp = dseg_add_address(cd, &m->class->object.header);
347 M_ALD(REG_A0, REG_PV, disp);
348 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
349 M_ALD(REG_ITMP3, REG_PV, disp);
352 /* emit_nullpointer_check(cd, iptr, REG_A0); */
354 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
355 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
356 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
359 M_JSR(REG_RA, REG_ITMP3);
360 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
362 # if !defined(NDEBUG)
363 if (opt_verbosecall) {
364 for (p = 0; p < INT_ARG_CNT; p++)
365 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
367 for (p = 0; p < FLT_ARG_CNT; p++)
368 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
371 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
379 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
380 emit_verbosecall_enter(jd);
383 /* end of header generation */
385 /* create replacement points */
387 REPLACEMENT_POINTS_INIT(cd, jd);
389 /* walk through all basic blocks */
391 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
393 /* handle replacement points */
395 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
397 /* store relative start of block */
399 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
401 if (bptr->flags >= BBREACHED) {
402 /* branch resolving */
404 codegen_resolve_branchrefs(cd, bptr);
406 /* copy interface registers to their destination */
410 #if defined(ENABLE_LSRA)
414 src = bptr->invars[len];
415 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
416 /* d = reg_of_var(m, src, REG_ITMP1); */
417 if (!(src->flags & INMEMORY))
421 M_INTMOVE(REG_ITMP1, d);
422 emit_store(jd, NULL, src, d);
429 var = VAR(bptr->invars[len]);
430 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
431 d = codegen_reg_of_var(0, var, REG_ITMP1);
432 M_INTMOVE(REG_ITMP1, d);
433 emit_store(jd, NULL, var, d);
436 assert((var->flags & INOUT));
439 #if defined(ENABLE_LSRA)
442 /* walk through all instructions */
445 /* currentline = 0; */
447 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
448 if (iptr->line != currentline) {
449 dseg_addlinenumber(cd, iptr->line);
450 currentline = iptr->line;
453 MCODECHECK(64); /* an instruction usually needs < 64 words */
457 case ICMD_NOP: /* ... ==> ... */
458 case ICMD_POP: /* ..., value ==> ... */
459 case ICMD_POP2: /* ..., value, value ==> ... */
462 case ICMD_INLINE_START:
464 REPLACEMENT_POINT_INLINE_START(cd, iptr);
467 case ICMD_INLINE_BODY:
469 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
470 dseg_addlinenumber_inline_start(cd, iptr);
471 dseg_addlinenumber(cd, iptr->line);
474 case ICMD_INLINE_END:
476 dseg_addlinenumber_inline_end(cd, iptr);
477 dseg_addlinenumber(cd, iptr->line);
480 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
483 emit_nullpointer_check(cd, iptr, s1);
486 /* constant operations ************************************************/
488 case ICMD_ICONST: /* ... ==> ..., constant */
490 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
491 ICONST(d, iptr->sx.val.i);
492 emit_store_dst(jd, iptr, d);
495 case ICMD_LCONST: /* ... ==> ..., constant */
497 #if SIZEOF_VOID_P == 8
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
502 LCONST(d, iptr->sx.val.l);
503 emit_store_dst(jd, iptr, d);
506 case ICMD_FCONST: /* ... ==> ..., constant */
508 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
509 disp = dseg_add_float(cd, iptr->sx.val.f);
510 M_FLD(d, REG_PV, disp);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_DCONST: /* ... ==> ..., constant */
516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
517 disp = dseg_add_double(cd, iptr->sx.val.d);
518 M_DLD(d, REG_PV, disp);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_ACONST: /* ... ==> ..., constant */
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
526 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
527 cr = iptr->sx.val.c.ref;
528 disp = dseg_add_unique_address(cd, cr);
530 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
532 M_ALD(d, REG_PV, disp);
535 if (iptr->sx.val.anyptr == NULL)
536 M_INTMOVE(REG_ZERO, d);
538 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
539 M_ALD(d, REG_PV, disp);
542 emit_store_dst(jd, iptr, d);
546 /* load/store/copy/move operations ************************************/
548 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
553 case ICMD_ISTORE: /* ..., value ==> ... */
564 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
569 /* integer operations *************************************************/
571 case ICMD_INEG: /* ..., value ==> ..., - value */
573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
575 M_ISUB(REG_ZERO, s1, d);
576 emit_store_dst(jd, iptr, d);
579 case ICMD_LNEG: /* ..., value ==> ..., - value */
581 #if SIZEOF_VOID_P == 8
582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
584 M_LSUB(REG_ZERO, s1, d);
586 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
588 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
589 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
590 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
591 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
593 emit_store_dst(jd, iptr, d);
596 case ICMD_I2L: /* ..., value ==> ..., value */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 #if SIZEOF_VOID_P == 8
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
604 M_INTMOVE(s1, GET_LOW_REG(d));
605 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
607 emit_store_dst(jd, iptr, d);
610 case ICMD_L2I: /* ..., value ==> ..., value */
612 #if SIZEOF_VOID_P == 8
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615 M_ISLL_IMM(s1, 0, d);
617 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
619 M_INTMOVE(GET_LOW_REG(s1), d);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628 #if SIZEOF_VOID_P == 8
629 M_LSLL_IMM(s1, 56, d);
630 M_LSRA_IMM( d, 56, d);
632 M_ISLL_IMM(s1, 24, d);
633 M_ISRA_IMM( d, 24, d);
635 emit_store_dst(jd, iptr, d);
638 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
642 M_AND_IMM(s1, 0xffff, d);
643 emit_store_dst(jd, iptr, d);
646 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 #if SIZEOF_VOID_P == 8
651 M_LSLL_IMM(s1, 48, d);
652 M_LSRA_IMM( d, 48, d);
654 M_ISLL_IMM(s1, 16, d);
655 M_ISRA_IMM( d, 16, d);
657 emit_store_dst(jd, iptr, d);
661 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
667 emit_store_dst(jd, iptr, d);
671 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
672 /* sx.val.i = constant */
674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
676 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
677 M_IADD_IMM(s1, iptr->sx.val.i, d);
679 ICONST(REG_ITMP2, iptr->sx.val.i);
680 M_IADD(s1, REG_ITMP2, d);
682 emit_store_dst(jd, iptr, d);
685 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
687 #if SIZEOF_VOID_P == 8
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
693 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
694 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
696 M_IADD(s1, s2, GET_HIGH_REG(d));
697 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
698 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
699 if (s1 == GET_LOW_REG(d)) {
700 M_MOV(s1, REG_ITMP3);
703 M_IADD(s1, s2, GET_LOW_REG(d));
704 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
705 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
707 emit_store_dst(jd, iptr, d);
710 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
711 /* sx.val.l = constant */
713 #if SIZEOF_VOID_P == 8
714 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
715 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
716 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
717 M_LADD_IMM(s1, iptr->sx.val.l, d);
719 LCONST(REG_ITMP2, iptr->sx.val.l);
720 M_LADD(s1, REG_ITMP2, d);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
724 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
725 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
726 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
727 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
728 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
730 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
731 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
732 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
733 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
734 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
735 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
736 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
739 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
740 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
741 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
742 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
743 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
744 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
745 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
746 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
749 emit_store_dst(jd, iptr, d);
752 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
755 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
758 emit_store_dst(jd, iptr, d);
761 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
762 /* sx.val.i = constant */
764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
767 M_IADD_IMM(s1, -iptr->sx.val.i, d);
769 ICONST(REG_ITMP2, iptr->sx.val.i);
770 M_ISUB(s1, REG_ITMP2, d);
772 emit_store_dst(jd, iptr, d);
775 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
777 #if SIZEOF_VOID_P == 8
778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
780 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
783 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
784 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
786 M_ISUB(s1, s2, GET_HIGH_REG(d));
787 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
788 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
789 M_CMPULT(s1, s2, REG_ITMP3);
790 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
791 /* if s1 is equal to REG_ITMP3 we have to reload it, since
792 the CMPULT instruction destroyed it */
794 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
795 M_ISUB(s1, s2, GET_LOW_REG(d));
798 emit_store_dst(jd, iptr, d);
801 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
802 /* sx.val.l = constant */
804 #if SIZEOF_VOID_P == 8
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
807 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
808 M_LADD_IMM(s1, -iptr->sx.val.l, d);
810 LCONST(REG_ITMP2, iptr->sx.val.l);
811 M_LSUB(s1, REG_ITMP2, d);
814 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
815 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
816 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
817 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
818 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
819 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
820 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
821 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
823 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
824 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
825 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
826 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
827 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
830 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
831 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
832 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
833 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
834 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
835 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
836 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
837 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
840 emit_store_dst(jd, iptr, d);
843 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
856 /* sx.val.i = constant */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 ICONST(REG_ITMP2, iptr->sx.val.i);
861 M_IMUL(s1, REG_ITMP2);
865 emit_store_dst(jd, iptr, d);
868 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
870 #if SIZEOF_VOID_P == 8
871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
872 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
880 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
886 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
888 M_MFHI(GET_HIGH_REG(d));
889 M_MFLO(GET_LOW_REG(d));
892 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
894 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
895 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
898 /* XXX do we need nops here? */
900 emit_store_dst(jd, iptr, d);
903 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
904 /* sx.val.l = constant */
906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
907 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
908 LCONST(REG_ITMP2, iptr->sx.val.l);
909 M_LMUL(s1, REG_ITMP2);
913 emit_store_dst(jd, iptr, d);
916 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
919 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
920 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
921 emit_arithmetic_check(cd, iptr, s2);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
932 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
934 emit_arithmetic_check(cd, iptr, s2);
939 emit_store_dst(jd, iptr, d);
942 #if SIZEOF_VOID_P == 8
944 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
947 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
948 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
949 emit_arithmetic_check(cd, iptr, s2);
954 emit_store_dst(jd, iptr, d);
957 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
960 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
961 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
962 emit_arithmetic_check(cd, iptr, s2);
967 emit_store_dst(jd, iptr, d);
970 #else /* SIZEOF_VOID_P == 8 */
972 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
973 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
975 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
976 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
978 /* XXX TODO: only do this if arithmetic check is really done! */
979 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
980 emit_arithmetic_check(cd, iptr, REG_ITMP3);
982 M_LNGMOVE(s1, REG_A0_A1_PACKED);
983 M_LNGMOVE(s2, REG_A2_A3_PACKED);
985 bte = iptr->sx.s23.s3.bte;
986 disp = dseg_add_functionptr(cd, bte->fp);
987 M_ALD(REG_ITMP3, REG_PV, disp);
988 M_JSR(REG_RA, REG_ITMP3);
991 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
992 M_LNGMOVE(REG_RESULT_PACKED, d);
993 emit_store_dst(jd, iptr, d);
996 #endif /* SIZEOF_VOID_P == 8 */
998 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
999 /* val.i = constant */
1001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 #if SIZEOF_VOID_P == 8
1004 M_LSRA_IMM(s1, 63, REG_ITMP2);
1005 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1006 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1007 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1009 M_ISRA_IMM(s1, 31, REG_ITMP2);
1010 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
1011 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1012 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1014 emit_store_dst(jd, iptr, d);
1017 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1018 /* val.i = constant */
1020 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1021 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1023 M_MOV(s1, REG_ITMP1);
1026 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1027 M_AND_IMM(s1, iptr->sx.val.i, d);
1030 M_ISUB(REG_ZERO, s1, d);
1031 M_AND_IMM(d, iptr->sx.val.i, d);
1034 ICONST(REG_ITMP2, iptr->sx.val.i);
1035 M_AND(s1, REG_ITMP2, d);
1038 M_ISUB(REG_ZERO, s1, d);
1039 M_AND(d, REG_ITMP2, d);
1041 M_ISUB(REG_ZERO, d, d);
1042 emit_store_dst(jd, iptr, d);
1045 #if SIZEOF_VOID_P == 8
1047 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1048 /* val.i = constant */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1052 M_LSRA_IMM(s1, 63, REG_ITMP2);
1053 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1054 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1055 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1060 /* val.l = constant */
1062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 M_MOV(s1, REG_ITMP1);
1068 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1069 M_AND_IMM(s1, iptr->sx.val.l, d);
1072 M_LSUB(REG_ZERO, s1, d);
1073 M_AND_IMM(d, iptr->sx.val.l, d);
1076 LCONST(REG_ITMP2, iptr->sx.val.l);
1077 M_AND(s1, REG_ITMP2, d);
1080 M_LSUB(REG_ZERO, s1, d);
1081 M_AND(d, REG_ITMP2, d);
1083 M_LSUB(REG_ZERO, d, d);
1084 emit_store_dst(jd, iptr, d);
1087 #endif /* SIZEOF_VOID_P == 8 */
1089 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1099 /* sx.val.i = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1103 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1117 /* sx.val.i = constant */
1119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1120 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1121 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1128 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1129 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1131 emit_store_dst(jd, iptr, d);
1134 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1135 /* sx.val.i = constant */
1137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1138 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1139 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1145 #if SIZEOF_VOID_P == 8
1146 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1147 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1148 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1151 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1152 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1155 M_ISLL(s2, 26, REG_ITMP1);
1156 M_BGEZ(REG_ITMP1, 3);
1159 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1161 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1164 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1166 M_BEQZ(REG_ITMP1, 4);
1167 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1169 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1170 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1171 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1174 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1177 emit_store_dst(jd, iptr, d);
1180 #if SIZEOF_VOID_P == 8
1182 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1183 /* sx.val.i = constant */
1185 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1186 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1187 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1193 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1194 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1195 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1197 emit_store_dst(jd, iptr, d);
1200 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1201 /* sx.val.i = constant */
1203 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1204 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1205 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1206 emit_store_dst(jd, iptr, d);
1209 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1212 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1213 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1215 emit_store_dst(jd, iptr, d);
1218 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1219 /* sx.val.i = constant */
1221 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1222 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1223 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1224 emit_store_dst(jd, iptr, d);
1227 #endif /* SIZEOF_VOID_P == 8 */
1229 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1231 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1232 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1233 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1235 emit_store_dst(jd, iptr, d);
1238 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1239 /* sx.val.i = constant */
1241 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1243 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1244 M_AND_IMM(s1, iptr->sx.val.i, d);
1246 ICONST(REG_ITMP2, iptr->sx.val.i);
1247 M_AND(s1, REG_ITMP2, d);
1249 emit_store_dst(jd, iptr, d);
1252 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1254 #if SIZEOF_VOID_P == 8
1255 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1256 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1257 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1260 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1261 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1262 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1263 M_AND(s1, s2, GET_LOW_REG(d));
1264 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1265 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1266 M_AND(s1, s2, GET_HIGH_REG(d));
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1272 /* sx.val.l = constant */
1274 #if SIZEOF_VOID_P == 8
1275 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1276 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1277 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1278 M_AND_IMM(s1, iptr->sx.val.l, d);
1280 LCONST(REG_ITMP2, iptr->sx.val.l);
1281 M_AND(s1, REG_ITMP2, d);
1284 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1285 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1286 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1287 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1288 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1291 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1292 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1293 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1294 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1295 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1303 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1304 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1305 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1311 /* sx.val.i = constant */
1313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1314 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1315 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1316 M_OR_IMM(s1, iptr->sx.val.i, d);
1318 ICONST(REG_ITMP2, iptr->sx.val.i);
1319 M_OR(s1, REG_ITMP2, d);
1321 emit_store_dst(jd, iptr, d);
1324 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1326 #if SIZEOF_VOID_P == 8
1327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1329 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1332 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1333 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1334 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1335 M_OR(s1, s2, GET_LOW_REG(d));
1336 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1337 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1338 M_OR(s1, s2, GET_HIGH_REG(d));
1340 emit_store_dst(jd, iptr, d);
1343 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1344 /* sx.val.l = constant */
1346 #if SIZEOF_VOID_P == 8
1347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1348 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1349 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1350 M_OR_IMM(s1, iptr->sx.val.l, d);
1352 LCONST(REG_ITMP2, iptr->sx.val.l);
1353 M_OR(s1, REG_ITMP2, d);
1356 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1357 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1358 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1359 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1360 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1363 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1364 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1365 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1366 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1367 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1375 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1376 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1383 /* sx.val.i = constant */
1385 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1387 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1388 M_XOR_IMM(s1, iptr->sx.val.i, d);
1390 ICONST(REG_ITMP2, iptr->sx.val.i);
1391 M_XOR(s1, REG_ITMP2, d);
1393 emit_store_dst(jd, iptr, d);
1396 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1398 #if SIZEOF_VOID_P == 8
1399 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1400 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1404 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1405 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1406 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1407 M_XOR(s1, s2, GET_LOW_REG(d));
1408 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1409 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1410 M_XOR(s1, s2, GET_HIGH_REG(d));
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1416 /* sx.val.l = constant */
1418 #if SIZEOF_VOID_P == 8
1419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1421 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1422 M_XOR_IMM(s1, iptr->sx.val.l, d);
1424 LCONST(REG_ITMP2, iptr->sx.val.l);
1425 M_XOR(s1, REG_ITMP2, d);
1428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1429 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1430 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1431 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1432 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1435 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1436 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1437 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1438 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1439 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1442 emit_store_dst(jd, iptr, d);
1446 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1448 #if SIZEOF_VOID_P == 8
1449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1452 M_CMPLT(s1, s2, REG_ITMP3);
1453 M_CMPLT(s2, s1, REG_ITMP1);
1454 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1456 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1457 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1459 M_CMPLT(s1, s2, REG_ITMP3);
1460 M_CMPLT(s2, s1, REG_ITMP1);
1461 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1464 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1465 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1466 M_CMPULT(s1, s2, REG_ITMP3);
1467 M_CMPULT(s2, s1, REG_ITMP1);
1468 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1470 emit_store_dst(jd, iptr, d);
1474 /* floating operations ************************************************/
1476 case ICMD_FNEG: /* ..., value ==> ..., - value */
1478 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1481 emit_store_dst(jd, iptr, d);
1484 case ICMD_DNEG: /* ..., value ==> ..., - value */
1486 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1487 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1489 emit_store_dst(jd, iptr, d);
1492 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1494 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1495 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1496 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1498 emit_store_dst(jd, iptr, d);
1501 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1503 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1504 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1505 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1507 emit_store_dst(jd, iptr, d);
1510 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1512 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1513 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1514 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1521 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1523 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1525 emit_store_dst(jd, iptr, d);
1528 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1530 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1534 emit_store_dst(jd, iptr, d);
1537 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1539 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1541 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1543 emit_store_dst(jd, iptr, d);
1546 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1548 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1550 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1552 emit_store_dst(jd, iptr, d);
1555 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1557 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1558 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1559 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1561 emit_store_dst(jd, iptr, d);
1565 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1567 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1568 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1569 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1570 M_FDIV(s1,s2, REG_FTMP3);
1571 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1572 M_CVTLF(REG_FTMP3, REG_FTMP3);
1573 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1574 M_FSUB(s1, REG_FTMP3, d);
1575 emit_store_dst(jd, iptr, d);
1578 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1580 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1581 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1582 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1583 M_DDIV(s1,s2, REG_FTMP3);
1584 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1585 M_CVTLD(REG_FTMP3, REG_FTMP3);
1586 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1587 M_DSUB(s1, REG_FTMP3, d);
1588 emit_store_dst(jd, iptr, d);
1592 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1595 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1598 emit_store_dst(jd, iptr, d);
1601 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1607 emit_store_dst(jd, iptr, d);
1611 /* XXX these do not work correctly */
1613 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1615 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1617 M_TRUNCFI(s1, REG_FTMP1);
1618 M_MOVDI(REG_FTMP1, d);
1620 emit_store_dst(jd, iptr, d);
1623 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1625 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1627 M_TRUNCDI(s1, REG_FTMP1);
1628 M_MOVDI(REG_FTMP1, d);
1630 emit_store_dst(jd, iptr, d);
1633 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1635 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1637 M_TRUNCFL(s1, REG_FTMP1);
1638 M_MOVDL(REG_FTMP1, d);
1640 emit_store_dst(jd, iptr, d);
1643 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1645 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1647 M_TRUNCDL(s1, REG_FTMP1);
1648 M_MOVDL(REG_FTMP1, d);
1650 emit_store_dst(jd, iptr, d);
1654 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1656 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1657 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1659 emit_store_dst(jd, iptr, d);
1662 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1664 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1665 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1667 emit_store_dst(jd, iptr, d);
1670 #if SUPPORT_FLOAT_CMP
1671 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1673 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1674 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1678 M_AADD_IMM(REG_ZERO, 1, d);
1682 M_ASUB_IMM(REG_ZERO, 1, d);
1683 M_CMOVT(REG_ZERO, d);
1684 emit_store_dst(jd, iptr, d);
1687 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1689 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1694 M_ASUB_IMM(REG_ZERO, 1, d);
1698 M_AADD_IMM(REG_ZERO, 1, d);
1699 M_CMOVT(REG_ZERO, d);
1700 emit_store_dst(jd, iptr, d);
1704 #if SUPPORT_DOUBLE_CMP
1705 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1707 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1708 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1712 M_AADD_IMM(REG_ZERO, 1, d);
1716 M_ASUB_IMM(REG_ZERO, 1, d);
1717 M_CMOVT(REG_ZERO, d);
1718 emit_store_dst(jd, iptr, d);
1721 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1723 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1724 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1728 M_ASUB_IMM(REG_ZERO, 1, d);
1732 M_AADD_IMM(REG_ZERO, 1, d);
1733 M_CMOVT(REG_ZERO, d);
1734 emit_store_dst(jd, iptr, d);
1739 /* memory operations **************************************************/
1741 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1743 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1745 /* implicit null-pointer check */
1746 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1747 emit_store_dst(jd, iptr, d);
1750 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1753 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1755 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1756 M_AADD(s2, s1, REG_ITMP3);
1757 /* implicit null-pointer check */
1758 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1759 emit_store_dst(jd, iptr, d);
1762 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1767 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1768 M_AADD(s2, s1, REG_ITMP3);
1769 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1770 /* implicit null-pointer check */
1771 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1772 emit_store_dst(jd, iptr, d);
1775 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1780 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1781 M_AADD(s2, s1, REG_ITMP3);
1782 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1783 /* implicit null-pointer check */
1784 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1785 emit_store_dst(jd, iptr, d);
1788 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1793 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1794 M_ASLL_IMM(s2, 2, REG_ITMP3);
1795 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1796 /* implicit null-pointer check */
1797 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1798 emit_store_dst(jd, iptr, d);
1801 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1804 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1805 #if SIZEOF_VOID_P == 8
1806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1810 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1811 M_ASLL_IMM(s2, 3, REG_ITMP3);
1812 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1813 /* implicit null-pointer check */
1814 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1815 emit_store_dst(jd, iptr, d);
1818 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1822 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1823 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1824 M_ASLL_IMM(s2, 2, REG_ITMP3);
1825 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1826 /* implicit null-pointer check */
1827 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1828 emit_store_dst(jd, iptr, d);
1831 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1834 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1835 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1836 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1837 M_ASLL_IMM(s2, 3, REG_ITMP3);
1838 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1839 /* implicit null-pointer check */
1840 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1841 emit_store_dst(jd, iptr, d);
1844 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1849 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1850 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1851 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1852 /* implicit null-pointer check */
1853 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1854 emit_store_dst(jd, iptr, d);
1858 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1861 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1862 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1863 M_AADD(s2, s1, REG_ITMP1);
1864 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1865 /* implicit null-pointer check */
1866 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1869 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1870 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1873 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1874 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1875 M_AADD(s2, s1, REG_ITMP1);
1876 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1877 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1878 /* implicit null-pointer check */
1879 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1882 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1886 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1887 M_ASLL_IMM(s2, 2, REG_ITMP2);
1888 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1889 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1890 /* implicit null-pointer check */
1891 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1894 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1897 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1898 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1899 M_ASLL_IMM(s2, 3, REG_ITMP2);
1900 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1901 #if SIZEOF_VOID_P == 8
1902 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1904 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1906 /* implicit null-pointer check */
1907 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1910 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1914 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1915 M_ASLL_IMM(s2, 2, REG_ITMP2);
1916 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1917 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1918 /* implicit null-pointer check */
1919 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1922 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1925 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1926 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1927 M_ASLL_IMM(s2, 3, REG_ITMP2);
1928 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1929 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1930 /* implicit null-pointer check */
1931 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1935 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1938 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1939 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1940 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1942 M_INTMOVE(s1, REG_A0);
1943 M_INTMOVE(s3, REG_A1);
1944 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1945 M_ALD(REG_ITMP3, REG_PV, disp);
1946 M_JSR(REG_RA, REG_ITMP3);
1948 emit_exception_check(cd, iptr);
1950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1951 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1952 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1953 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1954 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1955 /* implicit null-pointer check */
1956 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1960 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1962 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1963 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1964 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1965 M_AADD(s2, s1, REG_ITMP1);
1966 /* implicit null-pointer check */
1967 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1970 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1971 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1974 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1975 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1976 M_AADD(s2, s1, REG_ITMP1);
1977 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1978 /* implicit null-pointer check */
1979 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1982 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1985 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1986 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1987 M_ASLL_IMM(s2, 2, REG_ITMP2);
1988 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1989 /* implicit null-pointer check */
1990 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1993 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1996 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1997 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1998 M_ASLL_IMM(s2, 3, REG_ITMP2);
1999 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2000 /* implicit null-pointer check */
2001 #if SIZEOF_VOID_P == 8
2002 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2004 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
2008 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2011 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2012 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2013 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
2014 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2015 /* implicit null-pointer check */
2016 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2020 case ICMD_GETSTATIC: /* ... ==> ..., value */
2022 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2023 uf = iptr->sx.s23.s3.uf;
2024 fieldtype = uf->fieldref->parseddesc.fd->type;
2025 disp = dseg_add_unique_address(cd, uf);
2027 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2030 fi = iptr->sx.s23.s3.fmiref->p.field;
2031 fieldtype = fi->type;
2032 disp = dseg_add_address(cd, &(fi->value));
2034 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2035 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2038 M_ALD(REG_ITMP1, REG_PV, disp);
2040 switch (fieldtype) {
2042 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2043 M_ILD_INTERN(d, REG_ITMP1, 0);
2046 #if SIZEOF_VOID_P == 8
2047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2051 M_LLD_INTERN(d, REG_ITMP1, 0);
2054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2055 M_ALD_INTERN(d, REG_ITMP1, 0);
2058 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2059 M_FLD_INTERN(d, REG_ITMP1, 0);
2062 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2063 M_DLD_INTERN(d, REG_ITMP1, 0);
2066 emit_store_dst(jd, iptr, d);
2069 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2071 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2072 uf = iptr->sx.s23.s3.uf;
2073 fieldtype = uf->fieldref->parseddesc.fd->type;
2074 disp = dseg_add_unique_address(cd, uf);
2076 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2079 fi = iptr->sx.s23.s3.fmiref->p.field;
2080 fieldtype = fi->type;
2081 disp = dseg_add_address(cd, &(fi->value));
2083 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2084 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2087 M_ALD(REG_ITMP1, REG_PV, disp);
2089 switch (fieldtype) {
2091 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2092 M_IST_INTERN(s1, REG_ITMP1, 0);
2095 #if SIZEOF_VOID_P == 8
2096 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2098 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2100 M_LST_INTERN(s1, REG_ITMP1, 0);
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2104 M_AST_INTERN(s1, REG_ITMP1, 0);
2107 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2108 M_FST_INTERN(s1, REG_ITMP1, 0);
2111 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2112 M_DST_INTERN(s1, REG_ITMP1, 0);
2117 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2118 /* val = value (in current instruction) */
2119 /* following NOP) */
2121 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2122 uf = iptr->sx.s23.s3.uf;
2123 fieldtype = uf->fieldref->parseddesc.fd->type;
2124 disp = dseg_add_unique_address(cd, uf);
2126 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2129 fi = iptr->sx.s23.s3.fmiref->p.field;
2130 fieldtype = fi->type;
2131 disp = dseg_add_address(cd, &(fi->value));
2133 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2134 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2137 M_ALD(REG_ITMP1, REG_PV, disp);
2139 switch (fieldtype) {
2141 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2144 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2147 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2150 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2153 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2159 case ICMD_GETFIELD: /* ... ==> ..., value */
2161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2162 emit_nullpointer_check(cd, iptr, s1);
2164 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2165 uf = iptr->sx.s23.s3.uf;
2166 fieldtype = uf->fieldref->parseddesc.fd->type;
2169 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2172 fi = iptr->sx.s23.s3.fmiref->p.field;
2173 fieldtype = fi->type;
2177 switch (fieldtype) {
2179 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2183 #if SIZEOF_VOID_P == 8
2184 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2188 M_LLD_GETFIELD(d, s1, disp);
2192 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2204 emit_store_dst(jd, iptr, d);
2207 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2210 emit_nullpointer_check(cd, iptr, s1);
2212 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2213 uf = iptr->sx.s23.s3.uf;
2214 fieldtype = uf->fieldref->parseddesc.fd->type;
2218 fi = iptr->sx.s23.s3.fmiref->p.field;
2219 fieldtype = fi->type;
2223 #if SIZEOF_VOID_P == 8
2224 if (IS_INT_LNG_TYPE(fieldtype))
2225 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2227 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2229 if (IS_INT_LNG_TYPE(fieldtype)) {
2230 if (IS_2_WORD_TYPE(fieldtype))
2231 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2236 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2239 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2240 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2242 switch (fieldtype) {
2244 M_IST(s2, s1, disp);
2247 M_LST(s2, s1, disp);
2250 M_AST(s2, s1, disp);
2253 M_FST(s2, s1, disp);
2256 M_DST(s2, s1, disp);
2261 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2263 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2264 emit_nullpointer_check(cd, iptr, s1);
2266 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2267 unresolved_field *uf = iptr->sx.s23.s3.uf;
2269 fieldtype = uf->fieldref->parseddesc.fd->type;
2272 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2275 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2276 fieldtype = fi->type;
2280 switch (fieldtype) {
2282 M_IST(REG_ZERO, s1, disp);
2285 M_LST(REG_ZERO, s1, disp);
2288 M_AST(REG_ZERO, s1, disp);
2291 M_FST(REG_ZERO, s1, disp);
2294 M_DST(REG_ZERO, s1, disp);
2300 /* branch operations **************************************************/
2302 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2305 M_INTMOVE(s1, REG_ITMP1_XPTR);
2307 #ifdef ENABLE_VERIFIER
2308 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2309 uc = iptr->sx.s23.s2.uc;
2311 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2313 #endif /* ENABLE_VERIFIER */
2315 disp = dseg_add_functionptr(cd, asm_handle_exception);
2316 M_ALD(REG_ITMP2, REG_PV, disp);
2317 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2319 M_NOP; /* nop ensures that XPC is less than the end */
2320 /* of basic block */
2324 case ICMD_GOTO: /* ... ==> ... */
2325 case ICMD_RET: /* ... ==> ... */
2327 emit_br(cd, iptr->dst.block);
2331 case ICMD_JSR: /* ... ==> ... */
2333 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2337 case ICMD_IFNULL: /* ..., value ==> ... */
2338 case ICMD_IFNONNULL:
2340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2341 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2344 case ICMD_IFEQ: /* ..., value ==> ... */
2346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2347 if (iptr->sx.val.i == 0)
2348 emit_beqz(cd, iptr->dst.block, s1);
2350 ICONST(REG_ITMP2, iptr->sx.val.i);
2351 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2355 case ICMD_IFLT: /* ..., value ==> ... */
2357 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2358 if (iptr->sx.val.i == 0)
2359 emit_bltz(cd, iptr->dst.block, s1);
2361 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2362 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2364 ICONST(REG_ITMP2, iptr->sx.val.i);
2365 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2367 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2371 case ICMD_IFLE: /* ..., value ==> ... */
2373 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2374 if (iptr->sx.val.i == 0)
2375 emit_blez(cd, iptr->dst.block, s1);
2377 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2378 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2379 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2382 ICONST(REG_ITMP2, iptr->sx.val.i);
2383 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2384 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2389 case ICMD_IFNE: /* ..., value ==> ... */
2391 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2392 if (iptr->sx.val.i == 0)
2393 emit_bnez(cd, iptr->dst.block, s1);
2395 ICONST(REG_ITMP2, iptr->sx.val.i);
2396 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2400 case ICMD_IFGT: /* ..., value ==> ... */
2402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2403 if (iptr->sx.val.i == 0)
2404 emit_bgtz(cd, iptr->dst.block, s1);
2406 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2407 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2408 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2411 ICONST(REG_ITMP2, iptr->sx.val.i);
2412 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2413 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2418 case ICMD_IFGE: /* ..., value ==> ... */
2420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2421 if (iptr->sx.val.i == 0)
2422 emit_bgez(cd, iptr->dst.block, s1);
2424 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2425 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2427 ICONST(REG_ITMP2, iptr->sx.val.i);
2428 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2430 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2434 case ICMD_IF_LEQ: /* ..., value ==> ... */
2436 #if SIZEOF_VOID_P == 8
2437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2438 if (iptr->sx.val.l == 0)
2439 emit_beqz(cd, iptr->dst.block, s1);
2441 LCONST(REG_ITMP2, iptr->sx.val.l);
2442 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2445 if (iptr->sx.val.l == 0) {
2446 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2447 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2448 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2451 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2452 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2453 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2454 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2455 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2456 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2457 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2458 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2463 case ICMD_IF_LLT: /* ..., value ==> ... */
2465 #if SIZEOF_VOID_P == 8
2466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2467 if (iptr->sx.val.l == 0)
2468 emit_bltz(cd, iptr->dst.block, s1);
2470 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2471 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2473 LCONST(REG_ITMP2, iptr->sx.val.l);
2474 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2476 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2479 if (iptr->sx.val.l == 0) {
2480 /* if high word is less than zero, the whole long is too */
2481 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2482 emit_bltz(cd, iptr->dst.block, s1);
2485 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2486 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2487 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2488 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2489 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2490 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2492 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2493 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2494 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2499 case ICMD_IF_LLE: /* ..., value ==> ... */
2501 #if SIZEOF_VOID_P == 8
2502 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2503 if (iptr->sx.val.l == 0)
2504 emit_blez(cd, iptr->dst.block, s1);
2506 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2507 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2508 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2511 LCONST(REG_ITMP2, iptr->sx.val.l);
2512 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2513 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2517 if (iptr->sx.val.l == 0) {
2518 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2519 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2521 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2522 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2525 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2526 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2527 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2528 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2529 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2530 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2532 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2533 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2534 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2539 case ICMD_IF_LNE: /* ..., value ==> ... */
2541 #if SIZEOF_VOID_P == 8
2542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2543 if (iptr->sx.val.l == 0)
2544 emit_bnez(cd, iptr->dst.block, s1);
2546 LCONST(REG_ITMP2, iptr->sx.val.l);
2547 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2550 if (iptr->sx.val.l == 0) {
2551 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2552 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2553 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2556 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2557 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2558 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2559 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2560 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2561 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2562 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2563 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2568 case ICMD_IF_LGT: /* ..., value ==> ... */
2570 #if SIZEOF_VOID_P == 8
2571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2572 if (iptr->sx.val.l == 0)
2573 emit_bgtz(cd, iptr->dst.block, s1);
2575 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2576 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2577 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2580 LCONST(REG_ITMP2, iptr->sx.val.l);
2581 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2582 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2586 if (iptr->sx.val.l == 0) {
2587 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2588 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2589 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2591 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2594 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2595 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2596 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2597 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2598 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2599 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2601 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2602 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2603 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2608 case ICMD_IF_LGE: /* ..., value ==> ... */
2610 #if SIZEOF_VOID_P == 8
2611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2612 if (iptr->sx.val.l == 0)
2613 emit_bgez(cd, iptr->dst.block, s1);
2615 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2616 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2619 LCONST(REG_ITMP2, iptr->sx.val.l);
2620 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2622 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2625 if (iptr->sx.val.l == 0) {
2626 /* if high word is greater equal zero, the whole long is too */
2627 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2628 emit_bgez(cd, iptr->dst.block, s1);
2631 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2632 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2633 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2634 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2635 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2636 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2638 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2639 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2640 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2645 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2646 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2647 #if SIZEOF_VOID_P == 8
2648 case ICMD_IF_LCMPEQ:
2651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2653 emit_beq(cd, iptr->dst.block, s1, s2);
2656 #if SIZEOF_VOID_P == 4
2657 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2658 /* op1 = target JavaVM pc */
2660 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2661 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2662 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2664 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2665 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2666 emit_beq(cd, iptr->dst.block, s1, s2);
2670 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2671 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2672 #if SIZEOF_VOID_P == 8
2673 case ICMD_IF_LCMPNE:
2676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2678 emit_bne(cd, iptr->dst.block, s1, s2);
2681 #if SIZEOF_VOID_P == 4
2682 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2684 /* TODO: could be optimized (XOR or SUB) */
2685 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2686 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2687 emit_bne(cd, iptr->dst.block, s1, s2);
2688 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2689 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2690 emit_bne(cd, iptr->dst.block, s1, s2);
2694 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2695 #if SIZEOF_VOID_P == 8
2696 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2701 M_CMPLT(s1, s2, REG_ITMP3);
2702 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2705 #if SIZEOF_VOID_P == 4
2706 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2708 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2709 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2710 M_CMPLT(s1, s2, REG_ITMP3);
2711 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2712 M_CMPGT(s1, s2, REG_ITMP3);
2713 /* load low-bits before the branch, so we know the distance */
2714 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2715 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2716 M_BNEZ(REG_ITMP3, 4); /* XXX */
2718 M_CMPULT(s1, s2, REG_ITMP3);
2719 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2723 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2724 #if SIZEOF_VOID_P == 8
2725 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2730 M_CMPGT(s1, s2, REG_ITMP3);
2731 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2734 #if SIZEOF_VOID_P == 4
2735 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2737 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2738 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2739 M_CMPGT(s1, s2, REG_ITMP3);
2740 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2741 M_CMPLT(s1, s2, REG_ITMP3);
2742 /* load low-bits before the branch, so we know the distance */
2743 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2744 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2745 M_BNEZ(REG_ITMP3, 4); /* XXX */
2747 M_CMPUGT(s1, s2, REG_ITMP3);
2748 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2752 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2753 #if SIZEOF_VOID_P == 8
2754 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2757 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2758 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2759 M_CMPGT(s1, s2, REG_ITMP3);
2760 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2763 #if SIZEOF_VOID_P == 4
2764 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2766 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2767 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2768 M_CMPLT(s1, s2, REG_ITMP3);
2769 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2770 M_CMPGT(s1, s2, REG_ITMP3);
2771 /* load low-bits before the branch, so we know the distance */
2772 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2773 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2774 M_BNEZ(REG_ITMP3, 4); /* XXX */
2776 M_CMPUGT(s1, s2, REG_ITMP3);
2777 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2781 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2782 #if SIZEOF_VOID_P == 8
2783 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2786 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2787 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2788 M_CMPLT(s1, s2, REG_ITMP3);
2789 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2792 #if SIZEOF_VOID_P == 4
2793 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2795 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2796 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2797 M_CMPGT(s1, s2, REG_ITMP3);
2798 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2799 M_CMPLT(s1, s2, REG_ITMP3);
2800 /* load low-bits before the branch, so we know the distance */
2801 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2802 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2803 M_BNEZ(REG_ITMP3, 4); /* XXX */
2805 M_CMPULT(s1, s2, REG_ITMP3);
2806 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2810 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2811 #if SIZEOF_VOID_P == 8
2815 REPLACEMENT_POINT_RETURN(cd, iptr);
2816 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2817 M_INTMOVE(s1, REG_RESULT);
2818 goto nowperformreturn;
2820 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2822 REPLACEMENT_POINT_RETURN(cd, iptr);
2823 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2824 M_INTMOVE(s1, REG_RESULT);
2826 #ifdef ENABLE_VERIFIER
2827 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2828 uc = iptr->sx.s23.s2.uc;
2830 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2832 #endif /* ENABLE_VERIFIER */
2833 goto nowperformreturn;
2835 #if SIZEOF_VOID_P == 4
2836 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2838 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2839 M_LNGMOVE(s1, REG_RESULT_PACKED);
2840 goto nowperformreturn;
2843 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2844 REPLACEMENT_POINT_RETURN(cd, iptr);
2845 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2846 M_FLTMOVE(s1, REG_FRESULT);
2847 goto nowperformreturn;
2849 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2851 REPLACEMENT_POINT_RETURN(cd, iptr);
2852 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2853 M_DBLMOVE(s1, REG_FRESULT);
2854 goto nowperformreturn;
2856 case ICMD_RETURN: /* ... ==> ... */
2858 REPLACEMENT_POINT_RETURN(cd, iptr);
2864 p = cd->stackframesize;
2866 #if !defined(NDEBUG)
2867 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2868 emit_verbosecall_exit(jd);
2871 #if defined(ENABLE_THREADS)
2872 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2873 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2874 M_ALD(REG_ITMP3, REG_PV, disp);
2876 /* we need to save the proper return value */
2878 switch (iptr->opc) {
2881 #if SIZEOF_VOID_P == 8
2884 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2885 M_JSR(REG_RA, REG_ITMP3);
2886 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2888 #if SIZEOF_VOID_P == 4
2890 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2891 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2892 M_JSR(REG_RA, REG_ITMP3);
2898 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2899 M_JSR(REG_RA, REG_ITMP3);
2900 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2903 M_JSR(REG_RA, REG_ITMP3);
2904 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2908 /* and now restore the proper return value */
2910 switch (iptr->opc) {
2913 #if SIZEOF_VOID_P == 8
2916 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2918 #if SIZEOF_VOID_P == 4
2920 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2925 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2931 /* restore return address */
2933 if (!jd->isleafmethod) {
2934 p--; M_ALD(REG_RA, REG_SP, p * 8);
2937 /* restore saved registers */
2939 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2940 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2942 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2943 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2946 /* deallocate stack and return */
2948 if (cd->stackframesize) {
2951 disp = cd->stackframesize * 8;
2952 lo = (short) (disp);
2953 hi = (short) (((disp) - lo) >> 16);
2957 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2959 M_LUI(REG_ITMP3,hi);
2960 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2962 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2975 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2978 branch_target_t *table;
2980 table = iptr->dst.table;
2982 l = iptr->sx.s23.s2.tablelow;
2983 i = iptr->sx.s23.s3.tablehigh;
2985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2987 {M_INTMOVE(s1, REG_ITMP1);}
2988 else if (l <= 32768) {
2989 M_IADD_IMM(s1, -l, REG_ITMP1);
2992 ICONST(REG_ITMP2, l);
2993 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2996 /* number of targets */
3001 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3002 emit_beqz(cd, table[0].block, REG_ITMP2);
3004 /* build jump table top down and use address of lowest entry */
3009 dseg_add_target(cd, table->block);
3014 /* length of dataseg after last dseg_add_target is used by load */
3016 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
3017 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3018 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3025 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3028 lookup_target_t *lookup;
3030 lookup = iptr->dst.lookup;
3032 i = iptr->sx.s23.s2.lookupcount;
3034 MCODECHECK((i<<2)+8);
3035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3038 ICONST(REG_ITMP2, lookup->value);
3039 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3043 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3049 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3051 bte = iptr->sx.s23.s3.bte;
3055 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3057 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3058 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3059 case ICMD_INVOKEINTERFACE:
3061 REPLACEMENT_POINT_INVOKE(cd, iptr);
3063 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3065 um = iptr->sx.s23.s3.um;
3066 md = um->methodref->parseddesc.md;
3069 lm = iptr->sx.s23.s3.fmiref->p.method;
3071 md = lm->parseddesc;
3075 s3 = md->paramcount;
3077 MCODECHECK((s3 << 1) + 64);
3079 /* copy arguments to registers or stack location */
3081 for (s3 = s3 - 1; s3 >= 0; s3--) {
3082 var = VAR(iptr->sx.s23.s2.args[s3]);
3083 d = md->params[s3].regoff;
3085 if (var->flags & PREALLOC)
3088 if (IS_INT_LNG_TYPE(var->type)) {
3089 #if SIZEOF_VOID_P == 8
3090 if (!md->params[s3].inmemory) {
3091 s1 = emit_load(jd, iptr, var, d);
3095 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3096 M_LST(s1, REG_SP, d * 8);
3099 if (!md->params[s3].inmemory) {
3100 s1 = emit_load(jd, iptr, var, d);
3102 if (IS_2_WORD_TYPE(var->type))
3108 if (IS_2_WORD_TYPE(var->type)) {
3109 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3110 M_LST(s1, REG_SP, d * 8);
3113 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3114 M_IST(s1, REG_SP, d * 8);
3120 if (!md->params[s3].inmemory) {
3121 #if SIZEOF_VOID_P == 8
3122 s1 = emit_load(jd, iptr, var, d);
3123 if (IS_2_WORD_TYPE(var->type))
3129 ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3130 s1 = emit_load(jd, iptr, var, d);
3131 if (IS_2_WORD_TYPE(var->type))
3137 if (IS_2_WORD_TYPE(var->type)) {
3138 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3139 M_MFC1(GET_LOW_REG(d), s1);
3140 M_MFC1(GET_HIGH_REG(d), s1 + 1);
3144 s1 = emit_load(jd, iptr, var, d);
3152 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3153 if (IS_2_WORD_TYPE(var->type))
3154 M_DST(s1, REG_SP, d * 8);
3156 M_FST(s1, REG_SP, d * 8);
3161 switch (iptr->opc) {
3163 disp = dseg_add_functionptr(cd, bte->fp);
3165 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3167 /* generate the actual call */
3169 /* TWISTI: i actually don't know the reason for using
3170 REG_ITMP3 here instead of REG_PV. */
3172 M_JSR(REG_RA, REG_ITMP3);
3174 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3175 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3176 M_LDA(REG_PV, REG_RA, -disp);
3178 emit_exception_check(cd, iptr);
3181 case ICMD_INVOKESPECIAL:
3182 emit_nullpointer_check(cd, iptr, REG_A0);
3185 case ICMD_INVOKESTATIC:
3187 disp = dseg_add_unique_address(cd, um);
3189 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3193 disp = dseg_add_address(cd, lm->stubroutine);
3195 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3197 /* generate the actual call */
3199 M_JSR(REG_RA, REG_PV);
3201 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3202 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3203 M_LDA(REG_PV, REG_RA, -disp);
3206 case ICMD_INVOKEVIRTUAL:
3207 emit_nullpointer_check(cd, iptr, REG_A0);
3210 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3215 s1 = OFFSET(vftbl_t, table[0]) +
3216 sizeof(methodptr) * lm->vftblindex;
3218 /* implicit null-pointer check */
3219 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3220 M_ALD(REG_PV, REG_METHODPTR, s1);
3222 /* generate the actual call */
3224 M_JSR(REG_RA, REG_PV);
3226 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3227 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3228 M_LDA(REG_PV, REG_RA, -disp);
3231 case ICMD_INVOKEINTERFACE:
3232 emit_nullpointer_check(cd, iptr, REG_A0);
3235 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3241 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3242 sizeof(methodptr*) * lm->class->index;
3244 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3247 /* implicit null-pointer check */
3248 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3249 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3250 M_ALD(REG_PV, REG_METHODPTR, s2);
3252 /* generate the actual call */
3254 M_JSR(REG_RA, REG_PV);
3256 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3257 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3258 M_LDA(REG_PV, REG_RA, -disp);
3262 /* store return value */
3264 d = md->returntype.type;
3266 if (d != TYPE_VOID) {
3267 if (IS_INT_LNG_TYPE(d)) {
3268 #if SIZEOF_VOID_P == 8
3269 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3270 M_INTMOVE(REG_RESULT, s1);
3272 if (IS_2_WORD_TYPE(d)) {
3273 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3274 M_LNGMOVE(REG_RESULT_PACKED, s1);
3277 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3278 M_INTMOVE(REG_RESULT, s1);
3283 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3284 if (IS_2_WORD_TYPE(d))
3285 M_DMOV(REG_FRESULT, s1);
3287 M_FMOV(REG_FRESULT, s1);
3289 emit_store_dst(jd, iptr, s1);
3294 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3296 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3300 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3305 super = iptr->sx.s23.s3.c.cls;
3306 superindex = super->index;
3309 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3310 CODEGEN_CRITICAL_SECTION_NEW;
3312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3314 /* if class is not resolved, check which code to call */
3316 if (super == NULL) {
3317 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3319 cr = iptr->sx.s23.s3.c.ref;
3320 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3322 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3325 M_ILD(REG_ITMP2, REG_PV, disp);
3326 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3327 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3330 /* interface checkcast code */
3332 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3333 if (super == NULL) {
3334 cr = iptr->sx.s23.s3.c.ref;
3336 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3340 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3343 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3344 M_ILD(REG_ITMP3, REG_ITMP2,
3345 OFFSET(vftbl_t, interfacetablelength));
3346 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3347 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3349 M_ALD(REG_ITMP3, REG_ITMP2,
3350 OFFSET(vftbl_t, interfacetable[0]) -
3351 superindex * sizeof(methodptr*));
3352 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3355 emit_label_br(cd, BRANCH_LABEL_4);
3357 emit_label(cd, BRANCH_LABEL_3);
3360 /* class checkcast code */
3362 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3363 if (super == NULL) {
3364 emit_label(cd, BRANCH_LABEL_2);
3366 cr = iptr->sx.s23.s3.c.ref;
3367 disp = dseg_add_unique_address(cd, NULL);
3369 codegen_add_patch_ref(cd,
3370 PATCHER_checkcast_instanceof_class,
3374 disp = dseg_add_address(cd, super->vftbl);
3376 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3379 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3380 M_ALD(REG_ITMP3, REG_PV, disp);
3382 CODEGEN_CRITICAL_SECTION_START;
3384 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3385 /* if (s1 != REG_ITMP1) { */
3386 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3387 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3388 /* #if defined(ENABLE_THREADS) */
3389 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3391 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3393 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3394 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3395 M_ALD(REG_ITMP3, REG_PV, disp);
3396 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3398 CODEGEN_CRITICAL_SECTION_END;
3401 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3402 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3405 emit_label(cd, BRANCH_LABEL_5);
3408 if (super == NULL) {
3409 emit_label(cd, BRANCH_LABEL_1);
3410 emit_label(cd, BRANCH_LABEL_4);
3413 d = codegen_reg_of_dst(jd, iptr, s1);
3416 s1 = emit_load_s1(jd, iptr, REG_A0);
3417 M_INTMOVE(s1, REG_A0);
3419 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3420 cr = iptr->sx.s23.s3.c.ref;
3421 disp = dseg_add_unique_address(cd, NULL);
3423 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3427 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3429 M_ALD(REG_A1, REG_PV, disp);
3430 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3431 M_ALD(REG_ITMP3, REG_PV, disp);
3432 M_JSR(REG_RA, REG_ITMP3);
3435 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3436 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3438 d = codegen_reg_of_dst(jd, iptr, s1);
3442 emit_store_dst(jd, iptr, d);
3445 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3451 super = iptr->sx.s23.s3.c.cls;
3453 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3458 super = iptr->sx.s23.s3.c.cls;
3459 superindex = super->index;
3462 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3463 CODEGEN_CRITICAL_SECTION_NEW;
3465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3466 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3469 M_MOV(s1, REG_ITMP1);
3475 /* if class is not resolved, check which code to call */
3477 if (super == NULL) {
3478 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3480 cr = iptr->sx.s23.s3.c.ref;
3481 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3483 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3486 M_ILD(REG_ITMP3, REG_PV, disp);
3487 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3488 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3491 /* interface instanceof code */
3493 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3494 if (super == NULL) {
3495 cr = iptr->sx.s23.s3.c.ref;
3497 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3501 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3504 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3505 M_ILD(REG_ITMP3, REG_ITMP1,
3506 OFFSET(vftbl_t, interfacetablelength));
3507 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3508 M_BLEZ(REG_ITMP3, 3);
3510 M_ALD(REG_ITMP1, REG_ITMP1,
3511 OFFSET(vftbl_t, interfacetable[0]) -
3512 superindex * sizeof(methodptr*));
3513 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3516 emit_label_br(cd, BRANCH_LABEL_4);
3518 emit_label(cd, BRANCH_LABEL_3);
3521 /* class instanceof code */
3523 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3524 if (super == NULL) {
3525 emit_label(cd, BRANCH_LABEL_2);
3527 cr = iptr->sx.s23.s3.c.ref;
3528 disp = dseg_add_unique_address(cd, NULL);
3530 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3534 disp = dseg_add_address(cd, super->vftbl);
3536 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3539 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3540 M_ALD(REG_ITMP2, REG_PV, disp);
3542 CODEGEN_CRITICAL_SECTION_START;
3544 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3545 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3546 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3548 CODEGEN_CRITICAL_SECTION_END;
3550 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3551 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3555 emit_label(cd, BRANCH_LABEL_5);
3558 if (super == NULL) {
3559 emit_label(cd, BRANCH_LABEL_1);
3560 emit_label(cd, BRANCH_LABEL_4);
3563 emit_store_dst(jd, iptr, d);
3567 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3569 /* check for negative sizes and copy sizes to stack if necessary */
3571 MCODECHECK((iptr->s1.argcount << 1) + 64);
3573 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3575 var = VAR(iptr->sx.s23.s2.args[s1]);
3577 /* copy SAVEDVAR sizes to stack */
3579 if (!(var->flags & PREALLOC)) {
3580 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3581 #if SIZEOF_VOID_P == 8
3582 M_LST(s2, REG_SP, s1 * 8);
3584 M_IST(s2, REG_SP, (s1 + 2) * 8);
3589 /* a0 = dimension count */
3591 ICONST(REG_A0, iptr->s1.argcount);
3593 /* is patcher function set? */
3595 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3596 cr = iptr->sx.s23.s3.c.ref;
3597 disp = dseg_add_unique_address(cd, NULL);
3599 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3603 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3605 /* a1 = arraydescriptor */
3607 M_ALD(REG_A1, REG_PV, disp);
3609 /* a2 = pointer to dimensions = stack pointer */
3611 #if SIZEOF_VOID_P == 8
3612 M_MOV(REG_SP, REG_A2);
3614 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3617 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3618 M_ALD(REG_ITMP3, REG_PV, disp);
3619 M_JSR(REG_RA, REG_ITMP3);
3622 /* check for exception before result assignment */
3624 emit_exception_check(cd, iptr);
3626 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3627 M_INTMOVE(REG_RESULT, d);
3628 emit_store_dst(jd, iptr, d);
3632 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3637 } /* for instruction */
3639 MCODECHECK(64); /* XXX require smaller number? */
3641 /* At the end of a basic block we may have to append some nops,
3642 because the patcher stub calling code might be longer than the
3643 actual instruction. So codepatching does not change the
3644 following block unintentionally. */
3646 if (cd->mcodeptr < cd->lastmcodeptr) {
3647 while (cd->mcodeptr < cd->lastmcodeptr)
3651 } /* if (bptr -> flags >= BBREACHED) */
3652 } /* for basic block */
3654 dseg_createlinenumbertable(cd);
3656 /* generate stubs */
3658 emit_patcher_stubs(jd);
3659 REPLACEMENT_EMIT_STUBS(jd);
3661 /* everything's ok */
3667 /* codegen_emit_stub_compiler **************************************************
3669 Emits a stub routine which calls the compiler.
3671 *******************************************************************************/
3673 void codegen_emit_stub_compiler(jitdata *jd)
3678 /* get required compiler data */
3683 /* code for the stub */
3685 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3686 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3692 /* codegen_emit_stub_native ****************************************************
3694 Emits a stub routine which calls a native method.
3696 *******************************************************************************/
3698 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3708 s4 funcdisp; /* displacement of the function */
3710 /* get required compiler data */
3716 /* initialize variables */
3719 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3721 /* calculate stack frame size */
3723 cd->stackframesize =
3724 1 + /* return address */
3725 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3726 sizeof(localref_table) / SIZEOF_VOID_P +
3727 md->paramcount + /* for saving arguments over calls */
3728 #if SIZEOF_VOID_P == 4
3729 5 + /* additional save space (MIPS32) */
3731 1 + /* for saving return address */
3734 /* adjust stackframe size for 16-byte alignment */
3736 if (cd->stackframesize & 1)
3737 cd->stackframesize++;
3739 /* create method header */
3741 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3742 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3743 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3744 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3745 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3746 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3747 (void) dseg_addlinenumbertablesize(cd);
3748 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3750 /* generate stub code */
3752 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3753 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3755 #if !defined(NDEBUG)
3756 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3757 emit_verbosecall_enter(jd);
3760 /* get function address (this must happen before the stackframeinfo) */
3762 funcdisp = dseg_add_functionptr(cd, f);
3764 #if !defined(WITH_STATIC_CLASSPATH)
3766 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3769 /* save integer and float argument registers */
3771 #if SIZEOF_VOID_P == 8
3772 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3773 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3774 s1 = md->params[i].regoff;
3775 M_AST(s1, REG_SP, j * 8);
3780 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3781 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3782 if (!md->params[i].inmemory) {
3783 s1 = md->params[i].regoff;
3785 if (IS_2_WORD_TYPE(md->params[i].type))
3786 M_LST(s1, REG_SP, j * 8);
3788 M_IST(s1, REG_SP, j * 8);
3796 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3797 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3798 s1 = md->params[i].regoff;
3800 if (IS_2_WORD_TYPE(md->params[i].type))
3801 M_DST(s1, REG_SP, j * 8);
3803 M_FST(s1, REG_SP, j * 8);
3809 /* prepare data structures for native function call */
3811 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3812 M_MOV(REG_PV, REG_A1);
3813 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3814 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3815 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3816 M_ALD(REG_ITMP3, REG_PV, disp);
3817 M_JSR(REG_RA, REG_ITMP3);
3818 M_NOP; /* XXX fill me! */
3820 /* restore integer and float argument registers */
3822 #if SIZEOF_VOID_P == 8
3823 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3824 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3825 s1 = md->params[i].regoff;
3826 M_LLD(s1, REG_SP, j * 8);
3831 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3832 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3833 if (!md->params[i].inmemory) {
3834 s1 = md->params[i].regoff;
3836 if (IS_2_WORD_TYPE(md->params[i].type))
3837 M_LLD(s1, REG_SP, j * 8);
3839 M_ILD(s1, REG_SP, j * 8);
3847 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3848 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3849 s1 = md->params[i].regoff;
3851 if (IS_2_WORD_TYPE(md->params[i].type))
3852 M_DLD(s1, REG_SP, j * 8);
3854 M_FLD(s1, REG_SP, j * 8);
3860 /* copy or spill arguments to new locations */
3862 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3863 t = md->params[i].type;
3865 if (IS_INT_LNG_TYPE(t)) {
3866 if (!md->params[i].inmemory) {
3867 s1 = md->params[i].regoff;
3868 s2 = nmd->params[j].regoff;
3870 if (!nmd->params[j].inmemory) {
3871 #if SIZEOF_VOID_P == 8
3874 if (IS_2_WORD_TYPE(t))
3881 #if SIZEOF_VOID_P == 8
3882 M_LST(s1, REG_SP, s2 * 8);
3884 if (IS_2_WORD_TYPE(t))
3885 M_LST(s1, REG_SP, s2 * 4);
3887 M_IST(s1, REG_SP, s2 * 4);
3892 s1 = md->params[i].regoff + cd->stackframesize;
3893 s2 = nmd->params[j].regoff;
3895 #if SIZEOF_VOID_P == 8
3896 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3897 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3899 if (IS_2_WORD_TYPE(t)) {
3900 M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 8);
3901 M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
3904 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
3905 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3911 if (!md->params[i].inmemory) {
3912 s1 = md->params[i].regoff;
3913 s2 = nmd->params[j].regoff;
3915 if (!nmd->params[j].inmemory) {
3916 #if SIZEOF_VOID_P == 8
3917 if (IS_2_WORD_TYPE(t))
3922 /* On MIPS32 float arguments for native functions
3923 can never be in float argument registers, since
3924 the first argument is _always_ an integer
3925 argument (JNIenv) */
3927 if (IS_2_WORD_TYPE(t)) {
3928 /* double high/low order is endian
3929 independent: even numbered holds low
3930 32-bits, odd numbered high 32-bits */
3932 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3933 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3940 #if SIZEOF_VOID_P == 8
3941 if (IS_2_WORD_TYPE(t))
3942 M_DST(s1, REG_SP, s2 * 8);
3944 M_FST(s1, REG_SP, s2 * 8);
3946 /* s1 may have been originally in 2 int registers,
3947 but was moved out by the native function
3948 argument(s), just get low register */
3950 if (IS_2_WORD_TYPE(t))
3951 M_DST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3953 M_FST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3958 s1 = md->params[i].regoff + cd->stackframesize;
3959 s2 = nmd->params[j].regoff;
3961 if (IS_2_WORD_TYPE(t)) {
3962 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3963 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3966 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3967 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3973 /* put class into second argument register */
3975 if (m->flags & ACC_STATIC) {
3976 disp = dseg_add_address(cd, m->class);
3977 M_ALD(REG_A1, REG_PV, disp);
3980 /* put env into first argument register */
3982 disp = dseg_add_address(cd, _Jv_env);
3983 M_ALD(REG_A0, REG_PV, disp);
3985 /* do the native function call */
3987 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3988 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3989 M_NOP; /* delay slot */
3991 /* save return value */
3993 switch (md->returntype.type) {
3994 #if SIZEOF_VOID_P == 8
3998 M_LST(REG_RESULT, REG_SP, 0 * 8);
4002 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4007 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4010 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4014 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4021 #if !defined(NDEBUG)
4022 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4023 emit_verbosecall_exit(jd);
4026 /* remove native stackframe info */
4028 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4029 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4030 M_ALD(REG_ITMP3, REG_PV, disp);
4031 M_JSR(REG_RA, REG_ITMP3);
4032 M_NOP; /* XXX fill me! */
4033 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4035 /* restore return value */
4037 switch (md->returntype.type) {
4038 #if SIZEOF_VOID_P == 8
4042 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4046 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4051 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4054 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4058 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4065 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4067 /* check for exception */
4069 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4070 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4072 M_RET(REG_RA); /* return to caller */
4073 M_NOP; /* DELAY SLOT */
4075 /* handle exception */
4077 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4078 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4079 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4080 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4082 /* generate patcher stubs */
4084 emit_patcher_stubs(jd);
4089 * These are local overrides for various environment variables in Emacs.
4090 * Please do not remove this and leave it at the end of the file, where
4091 * Emacs will automagically detect them.
4092 * ---------------------------------------------------------------------
4095 * indent-tabs-mode: t
4099 * vim:noexpandtab:sw=4:ts=4: