1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "vm/jit/mips/arch.h"
36 #include "vm/jit/mips/codegen.h"
38 #include "mm/memory.hpp"
40 #include "native/localref.hpp"
41 #include "native/native.hpp"
43 #include "threads/lock.hpp"
45 #include "vm/jit/builtin.hpp"
46 #include "vm/class.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/options.h"
51 #include "vm/jit/abi.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.hpp"
54 #include "vm/jit/dseg.h"
55 #include "vm/jit/emit-common.hpp"
56 #include "vm/jit/jit.hpp"
57 #include "vm/jit/linenumbertable.hpp"
58 #include "vm/jit/patcher-common.hpp"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.hpp"
61 #include "vm/jit/trap.hpp"
63 #if defined(ENABLE_LSRA)
64 # include "vm/jit/allocator/lsra.h"
68 /* codegen_emit ****************************************************************
70 Generates machine code.
72 *******************************************************************************/
74 bool codegen_emit(jitdata *jd)
80 s4 len, s1, s2, s3, d, disp;
85 constant_classref *cr;
87 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
88 unresolved_method *um;
89 builtintable_entry *bte;
96 /* get required compiler data */
103 /* prevent compiler warnings */
118 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
120 /* space to save used callee saved registers */
122 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
123 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
125 cd->stackframesize = rd->memuse + savedregs_num;
127 #if defined(ENABLE_THREADS)
128 /* space to save argument of monitor_enter */
130 if (checksync && code_is_synchronized(code)) {
131 # if SIZEOF_VOID_P == 8
132 cd->stackframesize++;
135 cd->stackframesize += 2;
140 /* keep stack 16-byte aligned */
142 if (cd->stackframesize & 1)
143 cd->stackframesize++;
145 /* create method header */
147 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
148 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
150 code->synchronizedoffset = rd->memuse * 8;
152 /* REMOVEME: We still need it for exception handling in assembler. */
154 if (code_is_leafmethod(code))
155 (void) dseg_add_unique_s4(cd, 1);
157 (void) dseg_add_unique_s4(cd, 0);
159 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
160 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
162 /* create stack frame (if necessary) */
164 if (cd->stackframesize)
165 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
167 /* save return address and used callee saved registers */
169 p = cd->stackframesize;
170 if (!code_is_leafmethod(code)) {
171 p--; M_AST(REG_RA, REG_SP, p * 8);
173 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
174 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
176 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
177 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
180 /* take arguments out of register or stack frame */
184 for (p = 0, l = 0; p < md->paramcount; p++) {
185 t = md->paramtypes[p].type;
187 varindex = jd->local_map[l * 5 + t];
190 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
193 if (varindex == UNUSED)
197 s1 = md->params[p].regoff;
199 if (IS_INT_LNG_TYPE(t)) { /* integer args */
200 if (!md->params[p].inmemory) { /* register arguments */
201 #if SIZEOF_VOID_P == 8
202 if (!(var->flags & INMEMORY))
203 M_INTMOVE(s1, var->vv.regoff);
205 M_LST(s1, REG_SP, var->vv.regoff);
207 if (!(var->flags & INMEMORY)) {
208 if (IS_2_WORD_TYPE(t))
209 M_LNGMOVE(s1, var->vv.regoff);
211 M_INTMOVE(s1, var->vv.regoff);
214 if (IS_2_WORD_TYPE(t))
215 M_LST(s1, REG_SP, var->vv.regoff);
217 M_IST(s1, REG_SP, var->vv.regoff);
221 else { /* stack arguments */
222 if (!(var->flags & INMEMORY)) {
223 #if SIZEOF_VOID_P == 8
224 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
226 if (IS_2_WORD_TYPE(t))
227 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
229 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
233 var->vv.regoff = cd->stackframesize * 8 + s1;
236 else { /* floating args */
237 if (!md->params[p].inmemory) {
238 if (!(var->flags & INMEMORY)) {
239 if (IS_2_WORD_TYPE(t))
240 M_DBLMOVE(s1, var->vv.regoff);
242 M_FLTMOVE(s1, var->vv.regoff);
245 if (IS_2_WORD_TYPE(t))
246 M_DST(s1, REG_SP, var->vv.regoff);
248 M_FST(s1, REG_SP, var->vv.regoff);
252 if (!(var->flags & INMEMORY)) {
253 if (IS_2_WORD_TYPE(t))
254 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
256 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
259 var->vv.regoff = cd->stackframesize * 8 + s1;
264 /* call monitorenter function */
266 #if defined(ENABLE_THREADS)
267 if (checksync && code_is_synchronized(code)) {
268 /* stack offset for monitor argument */
272 # if !defined(NDEBUG)
273 if (opt_verbosecall) {
274 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
276 for (p = 0; p < INT_ARG_CNT; p++)
277 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
279 for (p = 0; p < FLT_ARG_CNT; p++)
280 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
282 s1 += INT_ARG_CNT + FLT_ARG_CNT;
286 /* get correct lock object */
288 if (m->flags & ACC_STATIC) {
289 disp = dseg_add_address(cd, &m->clazz->object.header);
290 M_ALD(REG_A0, REG_PV, disp);
291 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
292 M_ALD(REG_ITMP3, REG_PV, disp);
295 /* emit_nullpointer_check(cd, iptr, REG_A0); */
297 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
298 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
299 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
302 M_JSR(REG_RA, REG_ITMP3);
303 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
305 # if !defined(NDEBUG)
306 if (opt_verbosecall) {
307 for (p = 0; p < INT_ARG_CNT; p++)
308 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
310 for (p = 0; p < FLT_ARG_CNT; p++)
311 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
314 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
322 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
323 emit_verbosecall_enter(jd);
326 /* end of header generation */
328 /* create replacement points */
330 REPLACEMENT_POINTS_INIT(cd, jd);
332 /* walk through all basic blocks */
334 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
336 /* handle replacement points */
338 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
340 /* store relative start of block */
342 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
344 if (bptr->flags >= BBREACHED) {
345 /* branch resolving */
347 codegen_resolve_branchrefs(cd, bptr);
349 /* copy interface registers to their destination */
353 #if defined(ENABLE_LSRA)
357 src = bptr->invars[len];
358 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
359 /* d = reg_of_var(m, src, REG_ITMP1); */
360 if (!(src->flags & INMEMORY))
364 M_INTMOVE(REG_ITMP1, d);
365 emit_store(jd, NULL, src, d);
372 var = VAR(bptr->invars[len]);
373 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
374 d = codegen_reg_of_var(0, var, REG_ITMP1);
375 M_INTMOVE(REG_ITMP1, d);
376 emit_store(jd, NULL, var, d);
379 assert((var->flags & INOUT));
382 #if defined(ENABLE_LSRA)
385 /* walk through all instructions */
388 /* currentline = 0; */
390 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
391 if (iptr->line != currentline) {
392 linenumbertable_list_entry_add(cd, iptr->line);
393 currentline = iptr->line;
396 MCODECHECK(64); /* an instruction usually needs < 64 words */
400 case ICMD_NOP: /* ... ==> ... */
401 case ICMD_POP: /* ..., value ==> ... */
402 case ICMD_POP2: /* ..., value, value ==> ... */
405 case ICMD_INLINE_START:
407 REPLACEMENT_POINT_INLINE_START(cd, iptr);
410 case ICMD_INLINE_BODY:
412 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
413 linenumbertable_list_entry_add_inline_start(cd, iptr);
414 linenumbertable_list_entry_add(cd, iptr->line);
417 case ICMD_INLINE_END:
419 linenumbertable_list_entry_add_inline_end(cd, iptr);
420 linenumbertable_list_entry_add(cd, iptr->line);
423 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
425 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
426 emit_nullpointer_check(cd, iptr, s1);
429 /* constant operations ************************************************/
431 case ICMD_ICONST: /* ... ==> ..., constant */
433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
434 ICONST(d, iptr->sx.val.i);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_LCONST: /* ... ==> ..., constant */
440 #if SIZEOF_VOID_P == 8
441 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
443 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
445 LCONST(d, iptr->sx.val.l);
446 emit_store_dst(jd, iptr, d);
449 case ICMD_FCONST: /* ... ==> ..., constant */
451 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
452 disp = dseg_add_float(cd, iptr->sx.val.f);
453 M_FLD(d, REG_PV, disp);
454 emit_store_dst(jd, iptr, d);
457 case ICMD_DCONST: /* ... ==> ..., constant */
459 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
460 disp = dseg_add_double(cd, iptr->sx.val.d);
461 M_DLD(d, REG_PV, disp);
462 emit_store_dst(jd, iptr, d);
465 case ICMD_ACONST: /* ... ==> ..., constant */
467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
469 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
470 cr = iptr->sx.val.c.ref;
471 disp = dseg_add_unique_address(cd, cr);
473 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
476 M_ALD(d, REG_PV, disp);
479 if (iptr->sx.val.anyptr == NULL)
480 M_INTMOVE(REG_ZERO, d);
482 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
483 M_ALD(d, REG_PV, disp);
486 emit_store_dst(jd, iptr, d);
490 /* load/store/copy/move operations ************************************/
492 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
497 case ICMD_ISTORE: /* ..., value ==> ... */
508 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
513 /* integer operations *************************************************/
515 case ICMD_INEG: /* ..., value ==> ..., - value */
517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
519 M_ISUB(REG_ZERO, s1, d);
520 emit_store_dst(jd, iptr, d);
523 case ICMD_LNEG: /* ..., value ==> ..., - value */
525 #if SIZEOF_VOID_P == 8
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528 M_LSUB(REG_ZERO, s1, d);
530 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
532 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
533 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
534 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
535 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
537 emit_store_dst(jd, iptr, d);
540 case ICMD_I2L: /* ..., value ==> ..., value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 #if SIZEOF_VOID_P == 8
544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
548 M_INTMOVE(s1, GET_LOW_REG(d));
549 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
551 emit_store_dst(jd, iptr, d);
554 case ICMD_L2I: /* ..., value ==> ..., value */
556 #if SIZEOF_VOID_P == 8
557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 M_ISLL_IMM(s1, 0, d);
561 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
563 M_INTMOVE(GET_LOW_REG(s1), d);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
572 #if SIZEOF_VOID_P == 8
573 M_LSLL_IMM(s1, 56, d);
574 M_LSRA_IMM( d, 56, d);
576 M_ISLL_IMM(s1, 24, d);
577 M_ISRA_IMM( d, 24, d);
579 emit_store_dst(jd, iptr, d);
582 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586 M_AND_IMM(s1, 0xffff, d);
587 emit_store_dst(jd, iptr, d);
590 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
594 #if SIZEOF_VOID_P == 8
595 M_LSLL_IMM(s1, 48, d);
596 M_LSRA_IMM( d, 48, d);
598 M_ISLL_IMM(s1, 16, d);
599 M_ISRA_IMM( d, 16, d);
601 emit_store_dst(jd, iptr, d);
605 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 emit_store_dst(jd, iptr, d);
615 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
616 /* sx.val.i = constant */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
621 M_IADD_IMM(s1, iptr->sx.val.i, d);
623 ICONST(REG_ITMP2, iptr->sx.val.i);
624 M_IADD(s1, REG_ITMP2, d);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
631 #if SIZEOF_VOID_P == 8
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
637 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
638 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
640 M_IADD(s1, s2, GET_HIGH_REG(d));
641 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
642 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
643 if (s1 == GET_LOW_REG(d)) {
644 M_MOV(s1, REG_ITMP3);
647 M_IADD(s1, s2, GET_LOW_REG(d));
648 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
649 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
651 emit_store_dst(jd, iptr, d);
654 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
655 /* sx.val.l = constant */
657 #if SIZEOF_VOID_P == 8
658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
660 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
661 M_LADD_IMM(s1, iptr->sx.val.l, d);
663 LCONST(REG_ITMP2, iptr->sx.val.l);
664 M_LADD(s1, REG_ITMP2, d);
667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
668 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
669 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
670 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
671 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
672 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
674 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
675 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
676 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
677 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
678 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
679 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
680 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
683 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
684 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
685 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
686 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
687 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
688 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
689 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
690 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
693 emit_store_dst(jd, iptr, d);
696 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
706 /* sx.val.i = constant */
708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
711 M_IADD_IMM(s1, -iptr->sx.val.i, d);
713 ICONST(REG_ITMP2, iptr->sx.val.i);
714 M_ISUB(s1, REG_ITMP2, d);
716 emit_store_dst(jd, iptr, d);
719 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
721 #if SIZEOF_VOID_P == 8
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
727 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
728 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
729 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
730 M_ISUB(s1, s2, GET_HIGH_REG(d));
731 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
732 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
733 M_CMPULT(s1, s2, REG_ITMP3);
734 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
735 /* if s1 is equal to REG_ITMP3 we have to reload it, since
736 the CMPULT instruction destroyed it */
738 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
739 M_ISUB(s1, s2, GET_LOW_REG(d));
742 emit_store_dst(jd, iptr, d);
745 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
746 /* sx.val.l = constant */
748 #if SIZEOF_VOID_P == 8
749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
751 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
752 M_LADD_IMM(s1, -iptr->sx.val.l, d);
754 LCONST(REG_ITMP2, iptr->sx.val.l);
755 M_LSUB(s1, REG_ITMP2, d);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
759 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
760 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
761 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
762 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
763 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
764 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
765 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
767 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
768 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
769 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
770 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
771 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
774 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
775 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
776 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
777 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
778 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
779 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
780 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
781 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
784 emit_store_dst(jd, iptr, d);
787 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
791 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
800 /* sx.val.i = constant */
802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
804 ICONST(REG_ITMP2, iptr->sx.val.i);
805 M_IMUL(s1, REG_ITMP2);
809 emit_store_dst(jd, iptr, d);
812 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
814 #if SIZEOF_VOID_P == 8
815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
816 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
824 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
830 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
832 M_MFHI(GET_HIGH_REG(d));
833 M_MFLO(GET_LOW_REG(d));
836 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
838 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
839 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
842 /* XXX do we need nops here? */
844 emit_store_dst(jd, iptr, d);
847 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
848 /* sx.val.l = constant */
850 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 LCONST(REG_ITMP2, iptr->sx.val.l);
853 M_LMUL(s1, REG_ITMP2);
857 emit_store_dst(jd, iptr, d);
860 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
863 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
864 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
865 emit_arithmetic_check(cd, iptr, s2);
870 emit_store_dst(jd, iptr, d);
873 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
877 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878 emit_arithmetic_check(cd, iptr, s2);
883 emit_store_dst(jd, iptr, d);
886 #if SIZEOF_VOID_P == 8
888 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
891 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
893 emit_arithmetic_check(cd, iptr, s2);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
906 emit_arithmetic_check(cd, iptr, s2);
911 emit_store_dst(jd, iptr, d);
914 #else /* SIZEOF_VOID_P == 8 */
916 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
917 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
919 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
920 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
922 /* XXX TODO: only do this if arithmetic check is really done! */
923 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
924 emit_arithmetic_check(cd, iptr, REG_ITMP3);
926 M_LNGMOVE(s1, REG_A0_A1_PACKED);
927 M_LNGMOVE(s2, REG_A2_A3_PACKED);
929 bte = iptr->sx.s23.s3.bte;
930 disp = dseg_add_functionptr(cd, bte->fp);
931 M_ALD(REG_ITMP3, REG_PV, disp);
932 M_JSR(REG_RA, REG_ITMP3);
935 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
936 M_LNGMOVE(REG_RESULT_PACKED, d);
937 emit_store_dst(jd, iptr, d);
940 #endif /* SIZEOF_VOID_P == 8 */
942 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
943 /* val.i = constant */
945 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
947 #if SIZEOF_VOID_P == 8
948 M_LSRA_IMM(s1, 63, REG_ITMP2);
949 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
950 M_LADD(s1, REG_ITMP2, REG_ITMP2);
951 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
953 M_ISRA_IMM(s1, 31, REG_ITMP2);
954 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
955 M_IADD(s1, REG_ITMP2, REG_ITMP2);
956 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
962 /* val.i = constant */
964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
965 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
967 M_MOV(s1, REG_ITMP1);
970 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
971 M_AND_IMM(s1, iptr->sx.val.i, d);
974 M_ISUB(REG_ZERO, s1, d);
975 M_AND_IMM(d, iptr->sx.val.i, d);
978 ICONST(REG_ITMP2, iptr->sx.val.i);
979 M_AND(s1, REG_ITMP2, d);
982 M_ISUB(REG_ZERO, s1, d);
983 M_AND(d, REG_ITMP2, d);
985 M_ISUB(REG_ZERO, d, d);
986 emit_store_dst(jd, iptr, d);
989 #if SIZEOF_VOID_P == 8
991 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
992 /* val.i = constant */
994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
996 M_LSRA_IMM(s1, 63, REG_ITMP2);
997 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
998 M_LADD(s1, REG_ITMP2, REG_ITMP2);
999 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1000 emit_store_dst(jd, iptr, d);
1003 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1004 /* val.l = constant */
1006 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1007 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1009 M_MOV(s1, REG_ITMP1);
1012 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1013 M_AND_IMM(s1, iptr->sx.val.l, d);
1016 M_LSUB(REG_ZERO, s1, d);
1017 M_AND_IMM(d, iptr->sx.val.l, d);
1020 LCONST(REG_ITMP2, iptr->sx.val.l);
1021 M_AND(s1, REG_ITMP2, d);
1024 M_LSUB(REG_ZERO, s1, d);
1025 M_AND(d, REG_ITMP2, d);
1027 M_LSUB(REG_ZERO, d, d);
1028 emit_store_dst(jd, iptr, d);
1031 #endif /* SIZEOF_VOID_P == 8 */
1033 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1039 emit_store_dst(jd, iptr, d);
1042 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1043 /* sx.val.i = constant */
1045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1046 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1047 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1061 /* sx.val.i = constant */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1072 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1073 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1075 emit_store_dst(jd, iptr, d);
1078 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1079 /* sx.val.i = constant */
1081 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1083 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1089 #if SIZEOF_VOID_P == 8
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1096 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1097 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1099 M_ISLL(s2, 26, REG_ITMP1);
1100 M_BGEZ(REG_ITMP1, 3);
1103 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1105 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1108 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1110 M_BEQZ(REG_ITMP1, 4);
1111 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1113 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1114 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1115 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1118 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1121 emit_store_dst(jd, iptr, d);
1124 #if SIZEOF_VOID_P == 8
1126 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1127 /* sx.val.i = constant */
1129 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1131 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1132 emit_store_dst(jd, iptr, d);
1135 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1138 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1139 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1141 emit_store_dst(jd, iptr, d);
1144 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1145 /* sx.val.i = constant */
1147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1148 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1149 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1150 emit_store_dst(jd, iptr, d);
1153 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1156 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1157 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1159 emit_store_dst(jd, iptr, d);
1162 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1163 /* sx.val.i = constant */
1165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1166 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1167 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1168 emit_store_dst(jd, iptr, d);
1171 #endif /* SIZEOF_VOID_P == 8 */
1173 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1179 emit_store_dst(jd, iptr, d);
1182 case ICMD_IANDCONST: /* ..., 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 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1188 M_AND_IMM(s1, iptr->sx.val.i, d);
1190 ICONST(REG_ITMP2, iptr->sx.val.i);
1191 M_AND(s1, REG_ITMP2, d);
1193 emit_store_dst(jd, iptr, d);
1196 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1198 #if SIZEOF_VOID_P == 8
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1201 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1204 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1205 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1206 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1207 M_AND(s1, s2, GET_LOW_REG(d));
1208 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1209 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1210 M_AND(s1, s2, GET_HIGH_REG(d));
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1216 /* sx.val.l = constant */
1218 #if SIZEOF_VOID_P == 8
1219 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1221 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1222 M_AND_IMM(s1, iptr->sx.val.l, d);
1224 LCONST(REG_ITMP2, iptr->sx.val.l);
1225 M_AND(s1, REG_ITMP2, d);
1228 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1229 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1230 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1231 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1232 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1235 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1236 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1237 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1238 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1239 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1251 emit_store_dst(jd, iptr, d);
1254 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1255 /* sx.val.i = constant */
1257 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1258 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1259 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1260 M_OR_IMM(s1, iptr->sx.val.i, d);
1262 ICONST(REG_ITMP2, iptr->sx.val.i);
1263 M_OR(s1, REG_ITMP2, d);
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1270 #if SIZEOF_VOID_P == 8
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1273 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1276 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1277 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1279 M_OR(s1, s2, GET_LOW_REG(d));
1280 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1281 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1282 M_OR(s1, s2, GET_HIGH_REG(d));
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1288 /* sx.val.l = constant */
1290 #if SIZEOF_VOID_P == 8
1291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1293 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1294 M_OR_IMM(s1, iptr->sx.val.l, d);
1296 LCONST(REG_ITMP2, iptr->sx.val.l);
1297 M_OR(s1, REG_ITMP2, d);
1300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1301 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1302 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1303 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1304 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1307 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1308 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1309 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1310 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1311 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1321 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1327 /* sx.val.i = constant */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1331 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1332 M_XOR_IMM(s1, iptr->sx.val.i, d);
1334 ICONST(REG_ITMP2, iptr->sx.val.i);
1335 M_XOR(s1, REG_ITMP2, d);
1337 emit_store_dst(jd, iptr, d);
1340 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1342 #if SIZEOF_VOID_P == 8
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1345 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1348 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1349 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1351 M_XOR(s1, s2, GET_LOW_REG(d));
1352 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1353 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1354 M_XOR(s1, s2, GET_HIGH_REG(d));
1356 emit_store_dst(jd, iptr, d);
1359 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1360 /* sx.val.l = constant */
1362 #if SIZEOF_VOID_P == 8
1363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1365 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1366 M_XOR_IMM(s1, iptr->sx.val.l, d);
1368 LCONST(REG_ITMP2, iptr->sx.val.l);
1369 M_XOR(s1, REG_ITMP2, d);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1373 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1374 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1375 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1376 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1379 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1380 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1381 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1382 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1383 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1386 emit_store_dst(jd, iptr, d);
1390 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1392 #if SIZEOF_VOID_P == 8
1393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1394 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1396 M_CMPLT(s1, s2, REG_ITMP3);
1397 M_CMPLT(s2, s1, REG_ITMP1);
1398 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1400 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1401 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1403 M_CMPLT(s1, s2, REG_ITMP3);
1404 M_CMPLT(s2, s1, REG_ITMP1);
1405 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1406 emit_label_bnez(cd, BRANCH_LABEL_1, d);
1407 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1408 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1409 M_CMPULT(s1, s2, REG_ITMP3);
1410 M_CMPULT(s2, s1, REG_ITMP1);
1411 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1412 emit_label(cd, BRANCH_LABEL_1);
1414 emit_store_dst(jd, iptr, d);
1418 /* floating operations ************************************************/
1420 case ICMD_FNEG: /* ..., value ==> ..., - value */
1422 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1423 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_DNEG: /* ..., value ==> ..., - value */
1430 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1433 emit_store_dst(jd, iptr, d);
1436 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1438 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1440 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1442 emit_store_dst(jd, iptr, d);
1445 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1447 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1448 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1449 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1451 emit_store_dst(jd, iptr, d);
1454 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1456 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1458 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1460 emit_store_dst(jd, iptr, d);
1463 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1465 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1467 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1469 emit_store_dst(jd, iptr, d);
1472 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1474 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1475 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1476 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1478 emit_store_dst(jd, iptr, d);
1481 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1483 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1485 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1487 emit_store_dst(jd, iptr, d);
1490 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1492 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1493 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1494 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1496 emit_store_dst(jd, iptr, d);
1499 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1501 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1502 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1503 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1505 emit_store_dst(jd, iptr, d);
1509 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1511 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1512 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1513 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1514 M_FDIV(s1,s2, REG_FTMP3);
1515 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1516 M_CVTLF(REG_FTMP3, REG_FTMP3);
1517 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1518 M_FSUB(s1, REG_FTMP3, d);
1519 emit_store_dst(jd, iptr, d);
1522 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1524 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1525 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1526 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1527 M_DDIV(s1,s2, REG_FTMP3);
1528 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1529 M_CVTLD(REG_FTMP3, REG_FTMP3);
1530 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1531 M_DSUB(s1, REG_FTMP3, d);
1532 emit_store_dst(jd, iptr, d);
1536 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1539 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1542 emit_store_dst(jd, iptr, d);
1545 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1548 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1551 emit_store_dst(jd, iptr, d);
1555 /* XXX these do not work correctly */
1557 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1559 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1561 M_TRUNCFI(s1, REG_FTMP1);
1562 M_MOVDI(REG_FTMP1, d);
1564 emit_store_dst(jd, iptr, d);
1567 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1569 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1571 M_TRUNCDI(s1, REG_FTMP1);
1572 M_MOVDI(REG_FTMP1, d);
1574 emit_store_dst(jd, iptr, d);
1577 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1579 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1581 M_TRUNCFL(s1, REG_FTMP1);
1582 M_MOVDL(REG_FTMP1, d);
1584 emit_store_dst(jd, iptr, d);
1587 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1589 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1591 M_TRUNCDL(s1, REG_FTMP1);
1592 M_MOVDL(REG_FTMP1, d);
1594 emit_store_dst(jd, iptr, d);
1598 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1600 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1601 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1603 emit_store_dst(jd, iptr, d);
1606 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1608 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1609 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1611 emit_store_dst(jd, iptr, d);
1614 #if SUPPORT_FLOAT_CMP
1615 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1617 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1618 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1622 M_AADD_IMM(REG_ZERO, 1, d);
1626 M_ASUB_IMM(REG_ZERO, 1, d);
1627 M_CMOVT(REG_ZERO, d);
1628 emit_store_dst(jd, iptr, d);
1631 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1633 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1634 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1638 M_ASUB_IMM(REG_ZERO, 1, d);
1642 M_AADD_IMM(REG_ZERO, 1, d);
1643 M_CMOVT(REG_ZERO, d);
1644 emit_store_dst(jd, iptr, d);
1648 #if SUPPORT_DOUBLE_CMP
1649 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1651 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1652 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1656 M_AADD_IMM(REG_ZERO, 1, d);
1660 M_ASUB_IMM(REG_ZERO, 1, d);
1661 M_CMOVT(REG_ZERO, d);
1662 emit_store_dst(jd, iptr, d);
1665 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1667 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1668 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1672 M_ASUB_IMM(REG_ZERO, 1, d);
1676 M_AADD_IMM(REG_ZERO, 1, d);
1677 M_CMOVT(REG_ZERO, d);
1678 emit_store_dst(jd, iptr, d);
1683 /* memory operations **************************************************/
1685 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1689 /* implicit null-pointer check */
1690 M_ILD(d, s1, OFFSET(java_array_t, size));
1691 emit_store_dst(jd, iptr, d);
1694 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1699 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1700 M_AADD(s2, s1, REG_ITMP3);
1701 /* implicit null-pointer check */
1702 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1703 emit_store_dst(jd, iptr, d);
1706 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1711 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1712 M_AADD(s2, s1, REG_ITMP3);
1713 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1714 /* implicit null-pointer check */
1715 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1716 emit_store_dst(jd, iptr, d);
1719 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1722 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1724 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1725 M_AADD(s2, s1, REG_ITMP3);
1726 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1727 /* implicit null-pointer check */
1728 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1729 emit_store_dst(jd, iptr, d);
1732 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1737 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1738 M_ASLL_IMM(s2, 2, REG_ITMP3);
1739 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1740 /* implicit null-pointer check */
1741 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1742 emit_store_dst(jd, iptr, d);
1745 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1748 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1749 #if SIZEOF_VOID_P == 8
1750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1754 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1755 M_ASLL_IMM(s2, 3, REG_ITMP3);
1756 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1757 /* implicit null-pointer check */
1758 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1759 emit_store_dst(jd, iptr, d);
1762 case ICMD_FALOAD: /* ..., 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_FTMP1);
1767 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1768 M_ASLL_IMM(s2, 2, REG_ITMP3);
1769 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1770 /* implicit null-pointer check */
1771 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1772 emit_store_dst(jd, iptr, d);
1775 case ICMD_DALOAD: /* ..., 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_FTMP1);
1780 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1781 M_ASLL_IMM(s2, 3, REG_ITMP3);
1782 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1783 /* implicit null-pointer check */
1784 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1785 emit_store_dst(jd, iptr, d);
1788 case ICMD_AALOAD: /* ..., 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, POINTERSHIFT, REG_ITMP3);
1795 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1796 /* implicit null-pointer check */
1797 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1798 emit_store_dst(jd, iptr, d);
1802 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1806 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1807 M_AADD(s2, s1, REG_ITMP1);
1808 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1809 /* implicit null-pointer check */
1810 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1813 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1814 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1817 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1818 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1819 M_AADD(s2, s1, REG_ITMP1);
1820 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1821 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1822 /* implicit null-pointer check */
1823 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1826 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1829 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1830 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1831 M_ASLL_IMM(s2, 2, REG_ITMP2);
1832 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1833 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1834 /* implicit null-pointer check */
1835 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1838 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1842 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1843 M_ASLL_IMM(s2, 3, REG_ITMP2);
1844 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1845 #if SIZEOF_VOID_P == 8
1846 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1848 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1850 /* implicit null-pointer check */
1851 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1854 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1857 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1858 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1859 M_ASLL_IMM(s2, 2, REG_ITMP2);
1860 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1861 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1862 /* implicit null-pointer check */
1863 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1866 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1870 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1871 M_ASLL_IMM(s2, 3, REG_ITMP2);
1872 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1873 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1874 /* implicit null-pointer check */
1875 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1879 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1883 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1884 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1886 M_INTMOVE(s1, REG_A0);
1887 M_INTMOVE(s3, REG_A1);
1888 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1889 M_ALD(REG_ITMP3, REG_PV, disp);
1890 M_JSR(REG_RA, REG_ITMP3);
1892 emit_arraystore_check(cd, iptr);
1894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1896 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1897 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1898 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1899 /* implicit null-pointer check */
1900 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1904 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1907 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1908 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1909 M_AADD(s2, s1, REG_ITMP1);
1910 /* implicit null-pointer check */
1911 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1914 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1915 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1918 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1919 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1920 M_AADD(s2, s1, REG_ITMP1);
1921 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1922 /* implicit null-pointer check */
1923 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1926 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1929 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1930 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1931 M_ASLL_IMM(s2, 2, REG_ITMP2);
1932 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1933 /* implicit null-pointer check */
1934 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1937 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1940 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1941 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1942 M_ASLL_IMM(s2, 3, REG_ITMP2);
1943 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1944 /* implicit null-pointer check */
1945 #if SIZEOF_VOID_P == 8
1946 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1948 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1952 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1955 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1956 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1957 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1958 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1959 /* implicit null-pointer check */
1960 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1964 case ICMD_GETSTATIC: /* ... ==> ..., value */
1966 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1967 uf = iptr->sx.s23.s3.uf;
1968 fieldtype = uf->fieldref->parseddesc.fd->type;
1969 disp = dseg_add_unique_address(cd, uf);
1971 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1974 fi = iptr->sx.s23.s3.fmiref->p.field;
1975 fieldtype = fi->type;
1976 disp = dseg_add_address(cd, fi->value);
1978 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1979 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1983 M_ALD(REG_ITMP1, REG_PV, disp);
1985 switch (fieldtype) {
1987 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1988 M_ILD_INTERN(d, REG_ITMP1, 0);
1991 #if SIZEOF_VOID_P == 8
1992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1994 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1996 M_LLD_INTERN(d, REG_ITMP1, 0);
1999 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2000 M_ALD_INTERN(d, REG_ITMP1, 0);
2003 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2004 M_FLD_INTERN(d, REG_ITMP1, 0);
2007 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2008 M_DLD_INTERN(d, REG_ITMP1, 0);
2011 emit_store_dst(jd, iptr, d);
2014 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2017 uf = iptr->sx.s23.s3.uf;
2018 fieldtype = uf->fieldref->parseddesc.fd->type;
2019 disp = dseg_add_unique_address(cd, uf);
2021 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2024 fi = iptr->sx.s23.s3.fmiref->p.field;
2025 fieldtype = fi->type;
2026 disp = dseg_add_address(cd, fi->value);
2028 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2029 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2033 M_ALD(REG_ITMP1, REG_PV, disp);
2035 switch (fieldtype) {
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2038 M_IST_INTERN(s1, REG_ITMP1, 0);
2041 #if SIZEOF_VOID_P == 8
2042 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2044 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2046 M_LST_INTERN(s1, REG_ITMP1, 0);
2049 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2050 M_AST_INTERN(s1, REG_ITMP1, 0);
2053 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2054 M_FST_INTERN(s1, REG_ITMP1, 0);
2057 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2058 M_DST_INTERN(s1, REG_ITMP1, 0);
2063 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2066 uf = iptr->sx.s23.s3.uf;
2067 fieldtype = uf->fieldref->parseddesc.fd->type;
2068 disp = dseg_add_unique_address(cd, uf);
2070 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2073 fi = iptr->sx.s23.s3.fmiref->p.field;
2074 fieldtype = fi->type;
2075 disp = dseg_add_address(cd, fi->value);
2077 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2078 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2082 M_ALD(REG_ITMP1, REG_PV, disp);
2084 switch (fieldtype) {
2086 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2089 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2092 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2095 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2098 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2104 case ICMD_GETFIELD: /* ... ==> ..., value */
2106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2107 emit_nullpointer_check(cd, iptr, s1);
2109 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2110 uf = iptr->sx.s23.s3.uf;
2111 fieldtype = uf->fieldref->parseddesc.fd->type;
2114 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2117 fi = iptr->sx.s23.s3.fmiref->p.field;
2118 fieldtype = fi->type;
2122 switch (fieldtype) {
2124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2128 #if SIZEOF_VOID_P == 8
2129 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2133 M_LLD_GETFIELD(d, s1, disp);
2137 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2145 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2149 emit_store_dst(jd, iptr, d);
2152 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 emit_nullpointer_check(cd, iptr, s1);
2157 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2158 uf = iptr->sx.s23.s3.uf;
2159 fieldtype = uf->fieldref->parseddesc.fd->type;
2163 fi = iptr->sx.s23.s3.fmiref->p.field;
2164 fieldtype = fi->type;
2168 #if SIZEOF_VOID_P == 8
2169 if (IS_INT_LNG_TYPE(fieldtype))
2170 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2172 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2174 if (IS_INT_LNG_TYPE(fieldtype)) {
2175 if (IS_2_WORD_TYPE(fieldtype))
2176 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2178 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2181 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2184 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2185 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2187 switch (fieldtype) {
2189 M_IST(s2, s1, disp);
2192 M_LST(s2, s1, disp);
2195 M_AST(s2, s1, disp);
2198 M_FST(s2, s1, disp);
2201 M_DST(s2, s1, disp);
2206 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2208 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2209 emit_nullpointer_check(cd, iptr, s1);
2211 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2212 uf = iptr->sx.s23.s3.uf;
2213 fieldtype = uf->fieldref->parseddesc.fd->type;
2216 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2219 fi = iptr->sx.s23.s3.fmiref->p.field;
2220 fieldtype = fi->type;
2224 switch (fieldtype) {
2226 M_IST(REG_ZERO, s1, disp);
2229 M_LST(REG_ZERO, s1, disp);
2232 M_AST(REG_ZERO, s1, disp);
2235 M_FST(REG_ZERO, s1, disp);
2238 M_DST(REG_ZERO, s1, disp);
2244 /* branch operations **************************************************/
2246 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2249 M_INTMOVE(s1, REG_ITMP1_XPTR);
2251 #ifdef ENABLE_VERIFIER
2252 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2253 uc = iptr->sx.s23.s2.uc;
2255 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2257 #endif /* ENABLE_VERIFIER */
2259 // Some processor implementations seem to have a problem when using
2260 // the JALR instruction with (reg_dest == reg_src), so avoid that.
2261 disp = dseg_add_functionptr(cd, asm_handle_exception);
2262 M_ALD(REG_ITMP3, REG_PV, disp);
2263 M_JSR(REG_ITMP2_XPC, REG_ITMP3);
2265 M_NOP; /* nop ensures that XPC is less than the end */
2266 /* of basic block */
2270 case ICMD_GOTO: /* ... ==> ... */
2271 case ICMD_RET: /* ... ==> ... */
2273 emit_br(cd, iptr->dst.block);
2277 case ICMD_JSR: /* ... ==> ... */
2279 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2283 case ICMD_IFNULL: /* ..., value ==> ... */
2284 case ICMD_IFNONNULL:
2286 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2287 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2290 case ICMD_IFEQ: /* ..., value ==> ... */
2292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2293 if (iptr->sx.val.i == 0)
2294 emit_beqz(cd, iptr->dst.block, s1);
2296 ICONST(REG_ITMP2, iptr->sx.val.i);
2297 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2301 case ICMD_IFLT: /* ..., value ==> ... */
2303 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2304 if (iptr->sx.val.i == 0)
2305 emit_bltz(cd, iptr->dst.block, s1);
2307 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2308 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2310 ICONST(REG_ITMP2, iptr->sx.val.i);
2311 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2313 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2317 case ICMD_IFLE: /* ..., value ==> ... */
2319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2320 if (iptr->sx.val.i == 0)
2321 emit_blez(cd, iptr->dst.block, s1);
2323 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2324 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2325 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2328 ICONST(REG_ITMP2, iptr->sx.val.i);
2329 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2330 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2335 case ICMD_IFNE: /* ..., value ==> ... */
2337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2338 if (iptr->sx.val.i == 0)
2339 emit_bnez(cd, iptr->dst.block, s1);
2341 ICONST(REG_ITMP2, iptr->sx.val.i);
2342 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2346 case ICMD_IFGT: /* ..., value ==> ... */
2348 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2349 if (iptr->sx.val.i == 0)
2350 emit_bgtz(cd, iptr->dst.block, s1);
2352 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2353 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2354 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2357 ICONST(REG_ITMP2, iptr->sx.val.i);
2358 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2359 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2364 case ICMD_IFGE: /* ..., value ==> ... */
2366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2367 if (iptr->sx.val.i == 0)
2368 emit_bgez(cd, iptr->dst.block, s1);
2370 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2371 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2373 ICONST(REG_ITMP2, iptr->sx.val.i);
2374 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2376 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2380 case ICMD_IF_LEQ: /* ..., value ==> ... */
2382 #if SIZEOF_VOID_P == 8
2383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2384 if (iptr->sx.val.l == 0)
2385 emit_beqz(cd, iptr->dst.block, s1);
2387 LCONST(REG_ITMP2, iptr->sx.val.l);
2388 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2391 if (iptr->sx.val.l == 0) {
2392 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2393 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2394 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2397 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2398 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2399 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2400 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2401 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2402 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2403 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2404 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2409 case ICMD_IF_LLT: /* ..., value ==> ... */
2411 #if SIZEOF_VOID_P == 8
2412 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2413 if (iptr->sx.val.l == 0)
2414 emit_bltz(cd, iptr->dst.block, s1);
2416 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2417 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2419 LCONST(REG_ITMP2, iptr->sx.val.l);
2420 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2422 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2425 if (iptr->sx.val.l == 0) {
2426 /* if high word is less than zero, the whole long is too */
2427 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2428 emit_bltz(cd, iptr->dst.block, s1);
2431 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2432 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2433 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2434 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2435 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2436 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2437 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2438 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2439 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2440 emit_label(cd, BRANCH_LABEL_1);
2445 case ICMD_IF_LLE: /* ..., value ==> ... */
2447 #if SIZEOF_VOID_P == 8
2448 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2449 if (iptr->sx.val.l == 0)
2450 emit_blez(cd, iptr->dst.block, s1);
2452 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2453 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2454 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2457 LCONST(REG_ITMP2, iptr->sx.val.l);
2458 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2459 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2463 if (iptr->sx.val.l == 0) {
2464 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2465 emit_label_bgtz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2466 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2467 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2468 emit_label(cd, BRANCH_LABEL_1);
2471 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2472 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2473 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2474 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2475 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2476 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2477 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2478 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2479 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2480 emit_label(cd, BRANCH_LABEL_1);
2485 case ICMD_IF_LNE: /* ..., value ==> ... */
2487 #if SIZEOF_VOID_P == 8
2488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2489 if (iptr->sx.val.l == 0)
2490 emit_bnez(cd, iptr->dst.block, s1);
2492 LCONST(REG_ITMP2, iptr->sx.val.l);
2493 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2496 if (iptr->sx.val.l == 0) {
2497 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2498 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2499 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2502 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2503 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2504 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2505 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2506 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2507 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2508 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2509 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2514 case ICMD_IF_LGT: /* ..., value ==> ... */
2516 #if SIZEOF_VOID_P == 8
2517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2518 if (iptr->sx.val.l == 0)
2519 emit_bgtz(cd, iptr->dst.block, s1);
2521 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2522 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2523 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2526 LCONST(REG_ITMP2, iptr->sx.val.l);
2527 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2528 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2532 if (iptr->sx.val.l == 0) {
2533 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2534 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2535 emit_label_bltz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2536 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2537 emit_label(cd, BRANCH_LABEL_1);
2540 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2541 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2542 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2543 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2544 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2545 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2546 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2547 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2548 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2549 emit_label(cd, BRANCH_LABEL_1);
2554 case ICMD_IF_LGE: /* ..., value ==> ... */
2556 #if SIZEOF_VOID_P == 8
2557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2558 if (iptr->sx.val.l == 0)
2559 emit_bgez(cd, iptr->dst.block, s1);
2561 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2562 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2565 LCONST(REG_ITMP2, iptr->sx.val.l);
2566 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2568 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2571 if (iptr->sx.val.l == 0) {
2572 /* if high word is greater equal zero, the whole long is too */
2573 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2574 emit_bgez(cd, iptr->dst.block, s1);
2577 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2578 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2579 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2580 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2581 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2582 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2583 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2584 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2585 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2586 emit_label(cd, BRANCH_LABEL_1);
2591 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2592 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2593 #if SIZEOF_VOID_P == 8
2594 case ICMD_IF_LCMPEQ:
2597 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2598 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2599 emit_beq(cd, iptr->dst.block, s1, s2);
2602 #if SIZEOF_VOID_P == 4
2603 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2604 /* op1 = target JavaVM pc */
2606 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2607 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2608 emit_label_bne(cd, BRANCH_LABEL_1, s1, s2);
2609 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2610 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2611 emit_beq(cd, iptr->dst.block, s1, s2);
2612 emit_label(cd, BRANCH_LABEL_1);
2616 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2617 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2618 #if SIZEOF_VOID_P == 8
2619 case ICMD_IF_LCMPNE:
2622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2624 emit_bne(cd, iptr->dst.block, s1, s2);
2627 #if SIZEOF_VOID_P == 4
2628 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2630 /* TODO: could be optimized (XOR or SUB) */
2631 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2632 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2633 emit_bne(cd, iptr->dst.block, s1, s2);
2634 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2635 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2636 emit_bne(cd, iptr->dst.block, s1, s2);
2640 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2641 #if SIZEOF_VOID_P == 8
2642 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2647 M_CMPLT(s1, s2, REG_ITMP3);
2648 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2651 #if SIZEOF_VOID_P == 4
2652 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2654 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2655 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2656 M_CMPLT(s1, s2, REG_ITMP3);
2657 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2658 M_CMPGT(s1, s2, REG_ITMP3);
2659 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2660 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2661 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2662 M_CMPULT(s1, s2, REG_ITMP3);
2663 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2664 emit_label(cd, BRANCH_LABEL_1);
2668 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2669 #if SIZEOF_VOID_P == 8
2670 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2675 M_CMPGT(s1, s2, REG_ITMP3);
2676 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2679 #if SIZEOF_VOID_P == 4
2680 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2682 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2683 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2684 M_CMPGT(s1, s2, REG_ITMP3);
2685 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2686 M_CMPLT(s1, s2, REG_ITMP3);
2687 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2688 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2689 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2690 M_CMPUGT(s1, s2, REG_ITMP3);
2691 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2692 emit_label(cd, BRANCH_LABEL_1);
2696 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2697 #if SIZEOF_VOID_P == 8
2698 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2703 M_CMPGT(s1, s2, REG_ITMP3);
2704 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2707 #if SIZEOF_VOID_P == 4
2708 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2710 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2711 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2712 M_CMPLT(s1, s2, REG_ITMP3);
2713 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2714 M_CMPGT(s1, s2, REG_ITMP3);
2715 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2716 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2717 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2718 M_CMPUGT(s1, s2, REG_ITMP3);
2719 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2720 emit_label(cd, BRANCH_LABEL_1);
2724 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2725 #if SIZEOF_VOID_P == 8
2726 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2731 M_CMPLT(s1, s2, REG_ITMP3);
2732 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2735 #if SIZEOF_VOID_P == 4
2736 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2738 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2739 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2740 M_CMPGT(s1, s2, REG_ITMP3);
2741 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2742 M_CMPLT(s1, s2, REG_ITMP3);
2743 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2744 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2745 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2746 M_CMPULT(s1, s2, REG_ITMP3);
2747 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2748 emit_label(cd, BRANCH_LABEL_1);
2752 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2753 #if SIZEOF_VOID_P == 8
2757 REPLACEMENT_POINT_RETURN(cd, iptr);
2758 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2759 M_INTMOVE(s1, REG_RESULT);
2760 goto nowperformreturn;
2762 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2764 REPLACEMENT_POINT_RETURN(cd, iptr);
2765 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2766 M_INTMOVE(s1, REG_RESULT);
2768 #ifdef ENABLE_VERIFIER
2769 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2770 uc = iptr->sx.s23.s2.uc;
2772 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2774 #endif /* ENABLE_VERIFIER */
2775 goto nowperformreturn;
2777 #if SIZEOF_VOID_P == 4
2778 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2780 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2781 M_LNGMOVE(s1, REG_RESULT_PACKED);
2782 goto nowperformreturn;
2785 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2786 REPLACEMENT_POINT_RETURN(cd, iptr);
2787 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2788 M_FLTMOVE(s1, REG_FRESULT);
2789 goto nowperformreturn;
2791 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2793 REPLACEMENT_POINT_RETURN(cd, iptr);
2794 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2795 M_DBLMOVE(s1, REG_FRESULT);
2796 goto nowperformreturn;
2798 case ICMD_RETURN: /* ... ==> ... */
2800 REPLACEMENT_POINT_RETURN(cd, iptr);
2806 p = cd->stackframesize;
2808 #if !defined(NDEBUG)
2809 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2810 emit_verbosecall_exit(jd);
2813 #if defined(ENABLE_THREADS)
2814 if (checksync && code_is_synchronized(code)) {
2815 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2816 M_ALD(REG_ITMP3, REG_PV, disp);
2818 /* we need to save the proper return value */
2820 switch (iptr->opc) {
2823 #if SIZEOF_VOID_P == 8
2826 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2827 M_JSR(REG_RA, REG_ITMP3);
2828 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2830 #if SIZEOF_VOID_P == 4
2832 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2833 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2834 M_JSR(REG_RA, REG_ITMP3);
2840 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2841 M_JSR(REG_RA, REG_ITMP3);
2842 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2845 M_JSR(REG_RA, REG_ITMP3);
2846 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2850 /* and now restore the proper return value */
2852 switch (iptr->opc) {
2855 #if SIZEOF_VOID_P == 8
2858 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2860 #if SIZEOF_VOID_P == 4
2862 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2867 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2873 /* restore return address */
2875 if (!code_is_leafmethod(code)) {
2876 p--; M_ALD(REG_RA, REG_SP, p * 8);
2879 /* restore saved registers */
2881 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2882 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2884 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2885 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2888 /* deallocate stack and return */
2890 if (cd->stackframesize) {
2893 disp = cd->stackframesize * 8;
2894 lo = (short) (disp);
2895 hi = (short) (((disp) - lo) >> 16);
2899 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2901 M_LUI(REG_ITMP3,hi);
2902 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2904 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2917 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2920 branch_target_t *table;
2922 table = iptr->dst.table;
2924 l = iptr->sx.s23.s2.tablelow;
2925 i = iptr->sx.s23.s3.tablehigh;
2927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2929 {M_INTMOVE(s1, REG_ITMP1);}
2930 else if (l <= 32768) {
2931 M_IADD_IMM(s1, -l, REG_ITMP1);
2934 ICONST(REG_ITMP2, l);
2935 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2938 /* number of targets */
2943 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2944 emit_beqz(cd, table[0].block, REG_ITMP2);
2946 /* build jump table top down and use address of lowest entry */
2951 dseg_add_target(cd, table->block);
2956 /* length of dataseg after last dseg_add_target is used by load */
2958 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2959 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2960 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2967 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2970 lookup_target_t *lookup;
2972 lookup = iptr->dst.lookup;
2974 i = iptr->sx.s23.s2.lookupcount;
2976 MCODECHECK((i<<2)+8);
2977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2980 ICONST(REG_ITMP2, lookup->value);
2981 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2985 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2991 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2993 bte = iptr->sx.s23.s3.bte;
2997 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2999 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3000 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3001 case ICMD_INVOKEINTERFACE:
3003 REPLACEMENT_POINT_INVOKE(cd, iptr);
3005 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3007 um = iptr->sx.s23.s3.um;
3008 md = um->methodref->parseddesc.md;
3011 lm = iptr->sx.s23.s3.fmiref->p.method;
3013 md = lm->parseddesc;
3017 s3 = md->paramcount;
3019 MCODECHECK((s3 << 1) + 64);
3021 /* copy arguments to registers or stack location */
3023 for (s3 = s3 - 1; s3 >= 0; s3--) {
3024 var = VAR(iptr->sx.s23.s2.args[s3]);
3025 d = md->params[s3].regoff;
3027 if (var->flags & PREALLOC)
3030 if (IS_INT_LNG_TYPE(var->type)) {
3031 #if SIZEOF_VOID_P == 8
3032 if (!md->params[s3].inmemory) {
3033 s1 = emit_load(jd, iptr, var, d);
3037 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3038 M_LST(s1, REG_SP, d);
3041 if (!md->params[s3].inmemory) {
3042 s1 = emit_load(jd, iptr, var, d);
3044 if (IS_2_WORD_TYPE(var->type))
3050 if (IS_2_WORD_TYPE(var->type)) {
3051 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3052 M_LST(s1, REG_SP, d);
3055 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3056 M_IST(s1, REG_SP, d);
3062 if (!md->params[s3].inmemory) {
3063 s1 = emit_load(jd, iptr, var, d);
3064 if (IS_2_WORD_TYPE(var->type))
3070 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3071 if (IS_2_WORD_TYPE(var->type))
3072 M_DST(s1, REG_SP, d);
3074 M_FST(s1, REG_SP, d);
3079 switch (iptr->opc) {
3081 if (bte->stub == NULL) {
3082 disp = dseg_add_functionptr(cd, bte->fp);
3083 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3085 /* generate the actual call */
3087 /* TWISTI: i actually don't know the reason for using
3088 REG_ITMP3 here instead of REG_PV. */
3090 M_JSR(REG_RA, REG_ITMP3);
3094 disp = dseg_add_functionptr(cd, bte->stub);
3095 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3097 /* generate the actual call */
3099 M_JSR(REG_RA, REG_PV);
3103 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3104 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3105 M_LDA(REG_PV, REG_RA, -disp);
3108 case ICMD_INVOKESPECIAL:
3109 emit_nullpointer_check(cd, iptr, REG_A0);
3112 case ICMD_INVOKESTATIC:
3114 disp = dseg_add_unique_address(cd, um);
3116 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3120 disp = dseg_add_address(cd, lm->stubroutine);
3122 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3124 /* generate the actual call */
3126 M_JSR(REG_RA, REG_PV);
3128 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3129 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3130 M_LDA(REG_PV, REG_RA, -disp);
3133 case ICMD_INVOKEVIRTUAL:
3134 emit_nullpointer_check(cd, iptr, REG_A0);
3137 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3142 s1 = OFFSET(vftbl_t, table[0]) +
3143 sizeof(methodptr) * lm->vftblindex;
3145 /* implicit null-pointer check */
3146 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3147 M_ALD(REG_PV, REG_METHODPTR, s1);
3149 /* generate the actual call */
3151 M_JSR(REG_RA, REG_PV);
3153 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3154 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3155 M_LDA(REG_PV, REG_RA, -disp);
3158 case ICMD_INVOKEINTERFACE:
3159 emit_nullpointer_check(cd, iptr, REG_A0);
3162 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3168 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3169 sizeof(methodptr*) * lm->clazz->index;
3171 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
3174 /* implicit null-pointer check */
3175 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3176 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3177 M_ALD(REG_PV, REG_METHODPTR, s2);
3179 /* generate the actual call */
3181 M_JSR(REG_RA, REG_PV);
3183 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3184 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3185 M_LDA(REG_PV, REG_RA, -disp);
3189 /* store return value */
3191 d = md->returntype.type;
3193 if (d != TYPE_VOID) {
3194 if (IS_INT_LNG_TYPE(d)) {
3195 #if SIZEOF_VOID_P == 8
3196 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3197 M_INTMOVE(REG_RESULT, s1);
3199 if (IS_2_WORD_TYPE(d)) {
3200 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3201 M_LNGMOVE(REG_RESULT_PACKED, s1);
3204 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3205 M_INTMOVE(REG_RESULT, s1);
3210 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3211 if (IS_2_WORD_TYPE(d))
3212 M_DMOV(REG_FRESULT, s1);
3214 M_FMOV(REG_FRESULT, s1);
3216 emit_store_dst(jd, iptr, s1);
3221 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3223 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3227 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3232 super = iptr->sx.s23.s3.c.cls;
3233 superindex = super->index;
3236 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3238 /* if class is not resolved, check which code to call */
3240 if (super == NULL) {
3241 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3243 cr = iptr->sx.s23.s3.c.ref;
3244 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3246 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3249 M_ILD(REG_ITMP2, REG_PV, disp);
3250 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3251 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3254 /* interface checkcast code */
3256 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3257 if (super == NULL) {
3258 cr = iptr->sx.s23.s3.c.ref;
3260 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3264 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3267 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3268 M_ILD(REG_ITMP3, REG_ITMP2,
3269 OFFSET(vftbl_t, interfacetablelength));
3270 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3271 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3273 M_ALD(REG_ITMP3, REG_ITMP2,
3274 OFFSET(vftbl_t, interfacetable[0]) -
3275 superindex * sizeof(methodptr*));
3276 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3279 emit_label_br(cd, BRANCH_LABEL_4);
3281 emit_label(cd, BRANCH_LABEL_3);
3284 /* class checkcast code */
3286 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3287 if (super == NULL) {
3288 emit_label(cd, BRANCH_LABEL_2);
3290 cr = iptr->sx.s23.s3.c.ref;
3291 disp = dseg_add_unique_address(cd, NULL);
3293 patcher_add_patch_ref(jd,
3294 PATCHER_resolve_classref_to_vftbl,
3298 disp = dseg_add_address(cd, super->vftbl);
3300 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3303 // The following code checks whether object s is a subtype of class t.
3304 // Represents the following semantic:
3305 // if (!fast_subtype_check(s->vftbl, t->vftbl)) throw;
3307 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3308 M_ALD(REG_ITMP3, REG_PV, disp);
3310 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
3311 // Represents the following semantic:
3312 // if (*(s->vftbl + t->vftbl->subtype_offset) == t->vftbl) good;
3314 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
3315 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
3316 M_AADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
3317 M_ALD(REG_ITMP1, REG_ITMP1, 0);
3318 emit_label_beq(cd, BRANCH_LABEL_6, REG_ITMP1, REG_ITMP3); /* good */
3320 // Represents the following semantic:
3321 // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) throw;
3323 // REG_ITMP3==t->vftbl;
3324 if (super == NULL) {
3325 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
3326 M_ISUB_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
3327 emit_label_bnez(cd, BRANCH_LABEL_9, REG_ITMP1); /* throw */
3330 // Represents the following semantic:
3331 // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) throw;
3333 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
3334 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
3335 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
3336 M_CMPULT(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3337 emit_label_bnez(cd, BRANCH_LABEL_8, REG_ITMP1); /* throw */
3339 // Represents the following semantic:
3340 // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) throw;
3342 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl->subtype_depth;
3343 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
3344 M_ASLL_IMM(REG_ITMP3, POINTERSHIFT, REG_ITMP3);
3345 M_AADD(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3346 M_ALD(REG_ITMP2, REG_ITMP2, -DISPLAY_SIZE * SIZEOF_VOID_P);
3347 M_ALD(REG_ITMP3, REG_PV, disp); /* reload REG_ITMP3, was destroyed */
3348 emit_label_beq(cd, BRANCH_LABEL_7, REG_ITMP2, REG_ITMP3); /* good */
3351 emit_label(cd, BRANCH_LABEL_8);
3353 emit_label(cd, BRANCH_LABEL_9);
3354 emit_load_s1(jd, iptr, REG_ITMP1); /* reload s1, might have been destroyed */
3355 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
3358 emit_label(cd, BRANCH_LABEL_7);
3359 emit_label(cd, BRANCH_LABEL_6);
3360 emit_load_s1(jd, iptr, REG_ITMP1); /* reload s1, might have been destroyed */
3363 // Represents the following semantic:
3364 // if (*(s->vftbl + t->vftbl->subtype_offset) != t->vftbl) throw;
3366 // REG_ITMP2==s->vftbl; REG_ITMP3==t->vftbl;
3367 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
3368 M_BEQ(REG_ITMP2, REG_ITMP3, 2);
3369 M_NOP; /* delay slot */
3370 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
3374 emit_label(cd, BRANCH_LABEL_5);
3377 if (super == NULL) {
3378 emit_label(cd, BRANCH_LABEL_1);
3379 emit_label(cd, BRANCH_LABEL_4);
3382 d = codegen_reg_of_dst(jd, iptr, s1);
3385 s1 = emit_load_s1(jd, iptr, REG_A0);
3386 M_INTMOVE(s1, REG_A0);
3388 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3389 cr = iptr->sx.s23.s3.c.ref;
3390 disp = dseg_add_unique_address(cd, NULL);
3392 patcher_add_patch_ref(jd,
3393 PATCHER_resolve_classref_to_classinfo,
3397 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3400 M_ALD(REG_A1, REG_PV, disp);
3401 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3402 M_ALD(REG_ITMP3, REG_PV, disp);
3403 M_JSR(REG_RA, REG_ITMP3);
3406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3407 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3409 d = codegen_reg_of_dst(jd, iptr, s1);
3413 emit_store_dst(jd, iptr, d);
3416 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3422 super = iptr->sx.s23.s3.c.cls;
3424 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3429 super = iptr->sx.s23.s3.c.cls;
3430 superindex = super->index;
3433 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3437 M_MOV(s1, REG_ITMP1);
3443 /* if class is not resolved, check which code to call */
3445 if (super == NULL) {
3446 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3448 cr = iptr->sx.s23.s3.c.ref;
3449 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3451 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3454 M_ILD(REG_ITMP3, REG_PV, disp);
3455 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3456 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3459 /* interface instanceof code */
3461 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3462 if (super == NULL) {
3463 cr = iptr->sx.s23.s3.c.ref;
3465 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3469 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3472 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3473 M_ILD(REG_ITMP3, REG_ITMP1,
3474 OFFSET(vftbl_t, interfacetablelength));
3475 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3476 M_BLEZ(REG_ITMP3, 3);
3478 M_ALD(REG_ITMP1, REG_ITMP1,
3479 OFFSET(vftbl_t, interfacetable[0]) -
3480 superindex * sizeof(methodptr*));
3481 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3484 emit_label_br(cd, BRANCH_LABEL_4);
3486 emit_label(cd, BRANCH_LABEL_3);
3489 /* class instanceof code */
3491 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3492 if (super == NULL) {
3493 emit_label(cd, BRANCH_LABEL_2);
3495 cr = iptr->sx.s23.s3.c.ref;
3496 disp = dseg_add_unique_address(cd, NULL);
3498 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3502 disp = dseg_add_address(cd, super->vftbl);
3504 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3507 // The following code checks whether object s is a subtype of class t.
3508 // Represents the following semantic:
3509 // fast_subtype_check(s->vftbl, t->vftbl));
3511 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3512 M_ALD(REG_ITMP3, REG_PV, disp);
3514 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
3515 // Represents the following semantic:
3516 // if (*(s->vftbl + t->vftbl->subtype_offset) == t->vftbl) true;
3518 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3519 M_ILD(REG_ITMP2, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
3520 M_AADD(REG_ITMP2, REG_ITMP1, REG_ITMP2);
3521 M_ALD(REG_ITMP2, REG_ITMP2, 0);
3522 emit_label_beq(cd, BRANCH_LABEL_6, REG_ITMP2, REG_ITMP3); /* true */
3524 // Represents the following semantic:
3525 // if (t->vftbl->subtype_offset != OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE])) false;
3527 // REG_ITMP3==t->vftbl;
3528 if (super == NULL) {
3529 M_ILD(REG_ITMP2, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
3530 M_ISUB_IMM(REG_ITMP2, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP2);
3531 emit_label_bnez(cd, BRANCH_LABEL_9, REG_ITMP2); /* false */
3534 // Represents the following semantic:
3535 // if (s->vftbl->subtype_depth < t->vftbl->subtype_depth) false;
3537 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3538 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(vftbl_t, subtype_depth));
3539 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
3540 M_CMPULT(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3541 emit_label_bnez(cd, BRANCH_LABEL_8, REG_ITMP2); /* false */
3543 // Represents the following semantic:
3544 // if (s->vftbl->subtype_overflow[t->vftbl->subtype_depth - DISPLAY_SIZE] != t->vftbl) false;
3546 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl->subtype_depth;
3547 M_ALD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, subtype_overflow));
3548 M_ASLL_IMM(REG_ITMP3, POINTERSHIFT, REG_ITMP3);
3549 M_AADD(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3550 M_ALD(REG_ITMP1, REG_ITMP1, -DISPLAY_SIZE * SIZEOF_VOID_P);
3551 M_ALD(REG_ITMP3, REG_PV, disp); /* reload REG_ITMP3, was destroyed */
3552 emit_label_bne(cd, BRANCH_LABEL_7, REG_ITMP1, REG_ITMP3); /* false */
3555 emit_label(cd, BRANCH_LABEL_6);
3557 if (d == REG_ITMP2) {
3558 M_BR(2); /* branch over M_CLR */
3559 M_NOP; /* delay slot */
3562 // False (fall-through) case
3563 emit_label(cd, BRANCH_LABEL_7);
3564 emit_label(cd, BRANCH_LABEL_8);
3566 emit_label(cd, BRANCH_LABEL_9);
3568 M_CLR(d); /* if d == REG_ITMP2, it was destroyed */
3571 // Represents the following semantic:
3572 // *(s->vftbl + t->vftbl->subtype_offset) == t->vftbl;
3574 // REG_ITMP1==s->vftbl; REG_ITMP3==t->vftbl;
3575 M_ALD(REG_ITMP1, REG_ITMP1, super->vftbl->subtype_offset);
3576 M_XOR(REG_ITMP1, REG_ITMP3, d);
3577 M_CMPULT_IMM(d, 1, d);
3581 emit_label(cd, BRANCH_LABEL_5);
3584 if (super == NULL) {
3585 emit_label(cd, BRANCH_LABEL_1);
3586 emit_label(cd, BRANCH_LABEL_4);
3589 emit_store_dst(jd, iptr, d);
3593 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3595 /* check for negative sizes and copy sizes to stack if necessary */
3597 MCODECHECK((iptr->s1.argcount << 1) + 64);
3599 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3601 var = VAR(iptr->sx.s23.s2.args[s1]);
3603 /* copy SAVEDVAR sizes to stack */
3605 if (!(var->flags & PREALLOC)) {
3606 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3607 #if SIZEOF_VOID_P == 8
3608 M_LST(s2, REG_SP, s1 * 8);
3610 M_IST(s2, REG_SP, (s1 + 2) * 8);
3615 /* a0 = dimension count */
3617 ICONST(REG_A0, iptr->s1.argcount);
3619 /* is patcher function set? */
3621 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3622 cr = iptr->sx.s23.s3.c.ref;
3623 disp = dseg_add_unique_address(cd, NULL);
3625 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3629 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3632 /* a1 = arraydescriptor */
3634 M_ALD(REG_A1, REG_PV, disp);
3636 /* a2 = pointer to dimensions = stack pointer */
3638 #if SIZEOF_VOID_P == 8
3639 M_MOV(REG_SP, REG_A2);
3641 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3644 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3645 M_ALD(REG_ITMP3, REG_PV, disp);
3646 M_JSR(REG_RA, REG_ITMP3);
3649 /* check for exception before result assignment */
3651 emit_exception_check(cd, iptr);
3653 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3654 M_INTMOVE(REG_RESULT, d);
3655 emit_store_dst(jd, iptr, d);
3659 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3664 } /* for instruction */
3666 MCODECHECK(64); /* XXX require smaller number? */
3668 /* At the end of a basic block we may have to append some nops,
3669 because the patcher stub calling code might be longer than the
3670 actual instruction. So codepatching does not change the
3671 following block unintentionally. */
3673 if (cd->mcodeptr < cd->lastmcodeptr) {
3674 while (cd->mcodeptr < cd->lastmcodeptr)
3678 } /* if (bptr -> flags >= BBREACHED) */
3679 } /* for basic block */
3681 /* generate traps */
3683 emit_patcher_traps(jd);
3685 /* everything's ok */
3691 /* codegen_emit_stub_native ****************************************************
3693 Emits a stub routine which calls a native method.
3695 *******************************************************************************/
3697 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3708 /* get required compiler data */
3714 /* initialize variables */
3718 /* calculate stack frame size */
3720 cd->stackframesize =
3721 1 + /* return address */
3722 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3723 sizeof(localref_table) / SIZEOF_VOID_P +
3724 md->paramcount + /* for saving arguments over calls */
3725 #if SIZEOF_VOID_P == 4
3726 5 + /* additional save space (MIPS32) */
3728 1 + /* for saving return address */
3731 /* adjust stackframe size for 16-byte alignment */
3733 if (cd->stackframesize & 1)
3734 cd->stackframesize++;
3736 /* create method header */
3738 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3739 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3740 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3741 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3742 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3744 /* generate stub code */
3746 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3747 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3749 /* save integer and float argument registers */
3751 #if SIZEOF_VOID_P == 8
3752 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3753 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3754 s1 = md->params[i].regoff;
3755 M_AST(s1, REG_SP, j * 8);
3760 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3761 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3762 if (!md->params[i].inmemory) {
3763 s1 = md->params[i].regoff;
3765 if (IS_2_WORD_TYPE(md->params[i].type))
3766 M_LST(s1, REG_SP, j * 8);
3768 M_IST(s1, REG_SP, j * 8);
3776 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3777 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3778 s1 = md->params[i].regoff;
3780 if (IS_2_WORD_TYPE(md->params[i].type))
3781 M_DST(s1, REG_SP, j * 8);
3783 M_FST(s1, REG_SP, j * 8);
3789 /* prepare data structures for native function call */
3791 M_MOV(REG_SP, REG_A0);
3792 M_MOV(REG_PV, REG_A1);
3793 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3794 M_ALD(REG_ITMP3, REG_PV, disp);
3795 M_JSR(REG_RA, REG_ITMP3);
3796 M_NOP; /* XXX fill me! */
3798 /* remember class argument */
3800 if (m->flags & ACC_STATIC)
3801 M_MOV(REG_RESULT, REG_ITMP3);
3803 /* restore integer and float argument registers */
3805 #if SIZEOF_VOID_P == 8
3806 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3807 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3808 s1 = md->params[i].regoff;
3809 M_LLD(s1, REG_SP, j * 8);
3814 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3815 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3816 if (!md->params[i].inmemory) {
3817 s1 = md->params[i].regoff;
3819 if (IS_2_WORD_TYPE(md->params[i].type))
3820 M_LLD(s1, REG_SP, j * 8);
3822 M_ILD(s1, REG_SP, j * 8);
3830 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3831 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3832 s1 = md->params[i].regoff;
3834 if (IS_2_WORD_TYPE(md->params[i].type))
3835 M_DLD(s1, REG_SP, j * 8);
3837 M_FLD(s1, REG_SP, j * 8);
3843 /* copy or spill arguments to new locations */
3845 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3846 t = md->params[i].type;
3848 if (IS_INT_LNG_TYPE(t)) {
3849 if (!md->params[i].inmemory) {
3850 s1 = md->params[i].regoff;
3851 s2 = nmd->params[j].regoff;
3853 if (!nmd->params[j].inmemory) {
3854 #if SIZEOF_VOID_P == 8
3857 if (IS_2_WORD_TYPE(t))
3864 #if SIZEOF_VOID_P == 8
3865 M_LST(s1, REG_SP, s2);
3867 if (IS_2_WORD_TYPE(t))
3868 M_LST(s1, REG_SP, s2);
3870 M_IST(s1, REG_SP, s2);
3875 s1 = md->params[i].regoff + cd->stackframesize * 8;
3876 s2 = nmd->params[j].regoff;
3878 #if SIZEOF_VOID_P == 8
3879 M_LLD(REG_ITMP1, REG_SP, s1);
3880 M_LST(REG_ITMP1, REG_SP, s2);
3882 if (IS_2_WORD_TYPE(t)) {
3883 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3884 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3887 M_ILD(REG_ITMP1, REG_SP, s1);
3888 M_IST(REG_ITMP1, REG_SP, s2);
3894 if (!md->params[i].inmemory) {
3895 s1 = md->params[i].regoff;
3896 s2 = nmd->params[j].regoff;
3898 if (!nmd->params[j].inmemory) {
3899 #if SIZEOF_VOID_P == 8
3900 if (IS_2_WORD_TYPE(t))
3905 /* On MIPS32 float arguments for native functions
3906 can never be in float argument registers, since
3907 the first argument is _always_ an integer
3908 argument (JNIEnv) */
3910 if (IS_2_WORD_TYPE(t)) {
3911 /* double high/low order is endian
3912 independent: even numbered holds low
3913 32-bits, odd numbered high 32-bits */
3915 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3916 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3923 #if SIZEOF_VOID_P == 8
3924 if (IS_2_WORD_TYPE(t))
3925 M_DST(s1, REG_SP, s2);
3927 M_FST(s1, REG_SP, s2);
3929 /* s1 may have been originally in 2 int registers,
3930 but was moved out by the native function
3931 argument(s), just get low register */
3933 if (IS_2_WORD_TYPE(t))
3934 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3936 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3941 s1 = md->params[i].regoff + cd->stackframesize * 8;
3942 s2 = nmd->params[j].regoff;
3944 #if SIZEOF_VOID_P == 8
3945 if (IS_2_WORD_TYPE(t)) {
3946 M_DLD(REG_FTMP1, REG_SP, s1);
3947 M_DST(REG_FTMP1, REG_SP, s2);
3950 M_FLD(REG_FTMP1, REG_SP, s1);
3951 M_FST(REG_FTMP1, REG_SP, s2);
3954 if (IS_2_WORD_TYPE(t)) {
3955 M_DLD(REG_FTMP1, REG_SP, s1);
3956 M_DST(REG_FTMP1, REG_SP, s2);
3959 M_FLD(REG_FTMP1, REG_SP, s1);
3960 M_FST(REG_FTMP1, REG_SP, s2);
3967 /* Handle native Java methods. */
3969 if (m->flags & ACC_NATIVE) {
3970 /* put class into second argument register */
3972 if (m->flags & ACC_STATIC)
3973 M_MOV(REG_ITMP3, REG_A1);
3975 /* put env into first argument register */
3977 disp = dseg_add_address(cd, VM_get_jnienv());
3978 M_ALD(REG_A0, REG_PV, disp);
3981 /* Call the native function. */
3983 disp = dseg_add_functionptr(cd, f);
3984 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3985 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3986 M_NOP; /* delay slot */
3988 /* save return value */
3990 switch (md->returntype.type) {
3991 #if SIZEOF_VOID_P == 8
3995 M_LST(REG_RESULT, REG_SP, 0 * 8);
3999 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4004 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
4007 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
4011 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4018 /* remove native stackframe info */
4020 M_MOV(REG_SP, REG_A0);
4021 M_MOV(REG_PV, REG_A1);
4022 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4023 M_ALD(REG_ITMP3, REG_PV, disp);
4024 M_JSR(REG_RA, REG_ITMP3);
4025 M_NOP; /* XXX fill me! */
4026 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4028 /* restore return value */
4030 switch (md->returntype.type) {
4031 #if SIZEOF_VOID_P == 8
4035 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4039 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4044 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
4047 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
4051 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4058 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4060 /* check for exception */
4062 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4063 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4065 M_RET(REG_RA); /* return to caller */
4066 M_NOP; /* DELAY SLOT */
4068 /* handle exception */
4070 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4071 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4072 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4073 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4075 /* Generate patcher traps. */
4077 emit_patcher_traps(jd);
4082 * These are local overrides for various environment variables in Emacs.
4083 * Please do not remove this and leave it at the end of the file, where
4084 * Emacs will automagically detect them.
4085 * ---------------------------------------------------------------------
4088 * indent-tabs-mode: t
4092 * vim:noexpandtab:sw=4:ts=4: