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.h"
40 #include "native/localref.h"
41 #include "native/native.h"
43 #include "threads/lock-common.h"
45 #include "vm/jit/builtin.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.h"
54 #include "vm/jit/dseg.h"
55 #include "vm/jit/emit-common.hpp"
56 #include "vm/jit/jit.hpp"
57 #include "vm/jit/linenumbertable.h"
58 #include "vm/jit/patcher-common.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.hpp"
61 #include "vm/jit/trap.h"
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);
1408 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1409 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1410 M_CMPULT(s1, s2, REG_ITMP3);
1411 M_CMPULT(s2, s1, REG_ITMP1);
1412 M_ISUB(REG_ITMP1, REG_ITMP3, d);
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 disp = dseg_add_functionptr(cd, asm_handle_exception);
2260 M_ALD(REG_ITMP2, REG_PV, disp);
2261 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2263 M_NOP; /* nop ensures that XPC is less than the end */
2264 /* of basic block */
2268 case ICMD_GOTO: /* ... ==> ... */
2269 case ICMD_RET: /* ... ==> ... */
2271 emit_br(cd, iptr->dst.block);
2275 case ICMD_JSR: /* ... ==> ... */
2277 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2281 case ICMD_IFNULL: /* ..., value ==> ... */
2282 case ICMD_IFNONNULL:
2284 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2285 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2288 case ICMD_IFEQ: /* ..., value ==> ... */
2290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2291 if (iptr->sx.val.i == 0)
2292 emit_beqz(cd, iptr->dst.block, s1);
2294 ICONST(REG_ITMP2, iptr->sx.val.i);
2295 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2299 case ICMD_IFLT: /* ..., value ==> ... */
2301 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2302 if (iptr->sx.val.i == 0)
2303 emit_bltz(cd, iptr->dst.block, s1);
2305 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2306 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2308 ICONST(REG_ITMP2, iptr->sx.val.i);
2309 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2311 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2315 case ICMD_IFLE: /* ..., value ==> ... */
2317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318 if (iptr->sx.val.i == 0)
2319 emit_blez(cd, iptr->dst.block, s1);
2321 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2322 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2323 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2326 ICONST(REG_ITMP2, iptr->sx.val.i);
2327 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2328 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2333 case ICMD_IFNE: /* ..., value ==> ... */
2335 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2336 if (iptr->sx.val.i == 0)
2337 emit_bnez(cd, iptr->dst.block, s1);
2339 ICONST(REG_ITMP2, iptr->sx.val.i);
2340 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2344 case ICMD_IFGT: /* ..., value ==> ... */
2346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2347 if (iptr->sx.val.i == 0)
2348 emit_bgtz(cd, iptr->dst.block, s1);
2350 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2351 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2352 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2355 ICONST(REG_ITMP2, iptr->sx.val.i);
2356 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2357 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2362 case ICMD_IFGE: /* ..., value ==> ... */
2364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2365 if (iptr->sx.val.i == 0)
2366 emit_bgez(cd, iptr->dst.block, s1);
2368 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2369 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2371 ICONST(REG_ITMP2, iptr->sx.val.i);
2372 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2374 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2378 case ICMD_IF_LEQ: /* ..., value ==> ... */
2380 #if SIZEOF_VOID_P == 8
2381 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2382 if (iptr->sx.val.l == 0)
2383 emit_beqz(cd, iptr->dst.block, s1);
2385 LCONST(REG_ITMP2, iptr->sx.val.l);
2386 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2389 if (iptr->sx.val.l == 0) {
2390 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2391 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2392 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2395 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2396 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2397 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2398 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2399 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2400 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2401 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2402 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2407 case ICMD_IF_LLT: /* ..., value ==> ... */
2409 #if SIZEOF_VOID_P == 8
2410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2411 if (iptr->sx.val.l == 0)
2412 emit_bltz(cd, iptr->dst.block, s1);
2414 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2415 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2417 LCONST(REG_ITMP2, iptr->sx.val.l);
2418 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2420 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2423 if (iptr->sx.val.l == 0) {
2424 /* if high word is less than zero, the whole long is too */
2425 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2426 emit_bltz(cd, iptr->dst.block, s1);
2429 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2430 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2431 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2432 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2433 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2434 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2436 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2437 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2438 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2443 case ICMD_IF_LLE: /* ..., value ==> ... */
2445 #if SIZEOF_VOID_P == 8
2446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2447 if (iptr->sx.val.l == 0)
2448 emit_blez(cd, iptr->dst.block, s1);
2450 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2451 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2452 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2455 LCONST(REG_ITMP2, iptr->sx.val.l);
2456 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2457 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2461 if (iptr->sx.val.l == 0) {
2462 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2463 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2465 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2466 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2469 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2470 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2471 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2472 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2473 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2474 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2476 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2477 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2478 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2483 case ICMD_IF_LNE: /* ..., value ==> ... */
2485 #if SIZEOF_VOID_P == 8
2486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2487 if (iptr->sx.val.l == 0)
2488 emit_bnez(cd, iptr->dst.block, s1);
2490 LCONST(REG_ITMP2, iptr->sx.val.l);
2491 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2494 if (iptr->sx.val.l == 0) {
2495 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2496 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2497 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2500 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2501 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2502 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2503 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2504 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2505 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2506 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2507 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2512 case ICMD_IF_LGT: /* ..., value ==> ... */
2514 #if SIZEOF_VOID_P == 8
2515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2516 if (iptr->sx.val.l == 0)
2517 emit_bgtz(cd, iptr->dst.block, s1);
2519 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2520 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2521 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2524 LCONST(REG_ITMP2, iptr->sx.val.l);
2525 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2526 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2530 if (iptr->sx.val.l == 0) {
2531 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2532 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2533 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2535 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2538 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2539 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2540 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2541 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2542 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2543 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2545 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2546 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2547 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2552 case ICMD_IF_LGE: /* ..., value ==> ... */
2554 #if SIZEOF_VOID_P == 8
2555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2556 if (iptr->sx.val.l == 0)
2557 emit_bgez(cd, iptr->dst.block, s1);
2559 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2560 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2563 LCONST(REG_ITMP2, iptr->sx.val.l);
2564 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2566 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2569 if (iptr->sx.val.l == 0) {
2570 /* if high word is greater equal zero, the whole long is too */
2571 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2572 emit_bgez(cd, iptr->dst.block, s1);
2575 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2576 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2577 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2578 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2579 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2580 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2582 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2583 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2584 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2589 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2590 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2591 #if SIZEOF_VOID_P == 8
2592 case ICMD_IF_LCMPEQ:
2595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2596 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2597 emit_beq(cd, iptr->dst.block, s1, s2);
2600 #if SIZEOF_VOID_P == 4
2601 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2602 /* op1 = target JavaVM pc */
2604 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2605 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2606 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2608 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2609 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2610 emit_beq(cd, iptr->dst.block, s1, s2);
2614 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2615 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2616 #if SIZEOF_VOID_P == 8
2617 case ICMD_IF_LCMPNE:
2620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2622 emit_bne(cd, iptr->dst.block, s1, s2);
2625 #if SIZEOF_VOID_P == 4
2626 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2628 /* TODO: could be optimized (XOR or SUB) */
2629 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2630 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2631 emit_bne(cd, iptr->dst.block, s1, s2);
2632 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2633 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2634 emit_bne(cd, iptr->dst.block, s1, s2);
2638 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2639 #if SIZEOF_VOID_P == 8
2640 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2644 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2645 M_CMPLT(s1, s2, REG_ITMP3);
2646 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2649 #if SIZEOF_VOID_P == 4
2650 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2652 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2653 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2654 M_CMPLT(s1, s2, REG_ITMP3);
2655 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2656 M_CMPGT(s1, s2, REG_ITMP3);
2657 /* load low-bits before the branch, so we know the distance */
2658 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2659 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2660 M_BNEZ(REG_ITMP3, 4); /* XXX */
2662 M_CMPULT(s1, s2, REG_ITMP3);
2663 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2667 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2668 #if SIZEOF_VOID_P == 8
2669 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2674 M_CMPGT(s1, s2, REG_ITMP3);
2675 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2678 #if SIZEOF_VOID_P == 4
2679 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2681 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2682 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2683 M_CMPGT(s1, s2, REG_ITMP3);
2684 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2685 M_CMPLT(s1, s2, REG_ITMP3);
2686 /* load low-bits before the branch, so we know the distance */
2687 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2688 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2689 M_BNEZ(REG_ITMP3, 4); /* XXX */
2691 M_CMPUGT(s1, s2, REG_ITMP3);
2692 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
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 /* load low-bits before the branch, so we know the distance */
2716 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2717 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2718 M_BNEZ(REG_ITMP3, 4); /* XXX */
2720 M_CMPUGT(s1, s2, REG_ITMP3);
2721 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2725 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2726 #if SIZEOF_VOID_P == 8
2727 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2732 M_CMPLT(s1, s2, REG_ITMP3);
2733 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2736 #if SIZEOF_VOID_P == 4
2737 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2739 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2740 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2741 M_CMPGT(s1, s2, REG_ITMP3);
2742 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2743 M_CMPLT(s1, s2, REG_ITMP3);
2744 /* load low-bits before the branch, so we know the distance */
2745 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2746 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2747 M_BNEZ(REG_ITMP3, 4); /* XXX */
2749 M_CMPULT(s1, s2, REG_ITMP3);
2750 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2754 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2755 #if SIZEOF_VOID_P == 8
2759 REPLACEMENT_POINT_RETURN(cd, iptr);
2760 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2761 M_INTMOVE(s1, REG_RESULT);
2762 goto nowperformreturn;
2764 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2766 REPLACEMENT_POINT_RETURN(cd, iptr);
2767 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2768 M_INTMOVE(s1, REG_RESULT);
2770 #ifdef ENABLE_VERIFIER
2771 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2772 uc = iptr->sx.s23.s2.uc;
2774 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2776 #endif /* ENABLE_VERIFIER */
2777 goto nowperformreturn;
2779 #if SIZEOF_VOID_P == 4
2780 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2782 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2783 M_LNGMOVE(s1, REG_RESULT_PACKED);
2784 goto nowperformreturn;
2787 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2788 REPLACEMENT_POINT_RETURN(cd, iptr);
2789 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2790 M_FLTMOVE(s1, REG_FRESULT);
2791 goto nowperformreturn;
2793 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2795 REPLACEMENT_POINT_RETURN(cd, iptr);
2796 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2797 M_DBLMOVE(s1, REG_FRESULT);
2798 goto nowperformreturn;
2800 case ICMD_RETURN: /* ... ==> ... */
2802 REPLACEMENT_POINT_RETURN(cd, iptr);
2808 p = cd->stackframesize;
2810 #if !defined(NDEBUG)
2811 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2812 emit_verbosecall_exit(jd);
2815 #if defined(ENABLE_THREADS)
2816 if (checksync && code_is_synchronized(code)) {
2817 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2818 M_ALD(REG_ITMP3, REG_PV, disp);
2820 /* we need to save the proper return value */
2822 switch (iptr->opc) {
2825 #if SIZEOF_VOID_P == 8
2828 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2829 M_JSR(REG_RA, REG_ITMP3);
2830 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2832 #if SIZEOF_VOID_P == 4
2834 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2835 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2836 M_JSR(REG_RA, REG_ITMP3);
2842 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2843 M_JSR(REG_RA, REG_ITMP3);
2844 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2847 M_JSR(REG_RA, REG_ITMP3);
2848 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2852 /* and now restore the proper return value */
2854 switch (iptr->opc) {
2857 #if SIZEOF_VOID_P == 8
2860 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2862 #if SIZEOF_VOID_P == 4
2864 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2869 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2875 /* restore return address */
2877 if (!code_is_leafmethod(code)) {
2878 p--; M_ALD(REG_RA, REG_SP, p * 8);
2881 /* restore saved registers */
2883 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2884 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2886 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2887 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2890 /* deallocate stack and return */
2892 if (cd->stackframesize) {
2895 disp = cd->stackframesize * 8;
2896 lo = (short) (disp);
2897 hi = (short) (((disp) - lo) >> 16);
2901 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2903 M_LUI(REG_ITMP3,hi);
2904 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2906 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2919 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2922 branch_target_t *table;
2924 table = iptr->dst.table;
2926 l = iptr->sx.s23.s2.tablelow;
2927 i = iptr->sx.s23.s3.tablehigh;
2929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2931 {M_INTMOVE(s1, REG_ITMP1);}
2932 else if (l <= 32768) {
2933 M_IADD_IMM(s1, -l, REG_ITMP1);
2936 ICONST(REG_ITMP2, l);
2937 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2940 /* number of targets */
2945 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2946 emit_beqz(cd, table[0].block, REG_ITMP2);
2948 /* build jump table top down and use address of lowest entry */
2953 dseg_add_target(cd, table->block);
2958 /* length of dataseg after last dseg_add_target is used by load */
2960 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2961 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2962 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2969 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2972 lookup_target_t *lookup;
2974 lookup = iptr->dst.lookup;
2976 i = iptr->sx.s23.s2.lookupcount;
2978 MCODECHECK((i<<2)+8);
2979 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2982 ICONST(REG_ITMP2, lookup->value);
2983 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2987 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2993 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2995 bte = iptr->sx.s23.s3.bte;
2999 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3001 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3002 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3003 case ICMD_INVOKEINTERFACE:
3005 REPLACEMENT_POINT_INVOKE(cd, iptr);
3007 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3009 um = iptr->sx.s23.s3.um;
3010 md = um->methodref->parseddesc.md;
3013 lm = iptr->sx.s23.s3.fmiref->p.method;
3015 md = lm->parseddesc;
3019 s3 = md->paramcount;
3021 MCODECHECK((s3 << 1) + 64);
3023 /* copy arguments to registers or stack location */
3025 for (s3 = s3 - 1; s3 >= 0; s3--) {
3026 var = VAR(iptr->sx.s23.s2.args[s3]);
3027 d = md->params[s3].regoff;
3029 if (var->flags & PREALLOC)
3032 if (IS_INT_LNG_TYPE(var->type)) {
3033 #if SIZEOF_VOID_P == 8
3034 if (!md->params[s3].inmemory) {
3035 s1 = emit_load(jd, iptr, var, d);
3039 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3040 M_LST(s1, REG_SP, d);
3043 if (!md->params[s3].inmemory) {
3044 s1 = emit_load(jd, iptr, var, d);
3046 if (IS_2_WORD_TYPE(var->type))
3052 if (IS_2_WORD_TYPE(var->type)) {
3053 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3054 M_LST(s1, REG_SP, d);
3057 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3058 M_IST(s1, REG_SP, d);
3064 if (!md->params[s3].inmemory) {
3065 s1 = emit_load(jd, iptr, var, d);
3066 if (IS_2_WORD_TYPE(var->type))
3072 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3073 if (IS_2_WORD_TYPE(var->type))
3074 M_DST(s1, REG_SP, d);
3076 M_FST(s1, REG_SP, d);
3081 switch (iptr->opc) {
3083 if (bte->stub == NULL) {
3084 disp = dseg_add_functionptr(cd, bte->fp);
3085 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3087 /* generate the actual call */
3089 /* TWISTI: i actually don't know the reason for using
3090 REG_ITMP3 here instead of REG_PV. */
3092 M_JSR(REG_RA, REG_ITMP3);
3096 disp = dseg_add_functionptr(cd, bte->stub);
3097 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3099 /* generate the actual call */
3101 M_JSR(REG_RA, REG_PV);
3105 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3106 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3107 M_LDA(REG_PV, REG_RA, -disp);
3110 case ICMD_INVOKESPECIAL:
3111 emit_nullpointer_check(cd, iptr, REG_A0);
3114 case ICMD_INVOKESTATIC:
3116 disp = dseg_add_unique_address(cd, um);
3118 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3122 disp = dseg_add_address(cd, lm->stubroutine);
3124 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3126 /* generate the actual call */
3128 M_JSR(REG_RA, REG_PV);
3130 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3131 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3132 M_LDA(REG_PV, REG_RA, -disp);
3135 case ICMD_INVOKEVIRTUAL:
3136 emit_nullpointer_check(cd, iptr, REG_A0);
3139 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3144 s1 = OFFSET(vftbl_t, table[0]) +
3145 sizeof(methodptr) * lm->vftblindex;
3147 /* implicit null-pointer check */
3148 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3149 M_ALD(REG_PV, REG_METHODPTR, s1);
3151 /* generate the actual call */
3153 M_JSR(REG_RA, REG_PV);
3155 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3156 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3157 M_LDA(REG_PV, REG_RA, -disp);
3160 case ICMD_INVOKEINTERFACE:
3161 emit_nullpointer_check(cd, iptr, REG_A0);
3164 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3170 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3171 sizeof(methodptr*) * lm->clazz->index;
3173 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
3176 /* implicit null-pointer check */
3177 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3178 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3179 M_ALD(REG_PV, REG_METHODPTR, s2);
3181 /* generate the actual call */
3183 M_JSR(REG_RA, REG_PV);
3185 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3186 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3187 M_LDA(REG_PV, REG_RA, -disp);
3191 /* store return value */
3193 d = md->returntype.type;
3195 if (d != TYPE_VOID) {
3196 if (IS_INT_LNG_TYPE(d)) {
3197 #if SIZEOF_VOID_P == 8
3198 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3199 M_INTMOVE(REG_RESULT, s1);
3201 if (IS_2_WORD_TYPE(d)) {
3202 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3203 M_LNGMOVE(REG_RESULT_PACKED, s1);
3206 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3207 M_INTMOVE(REG_RESULT, s1);
3212 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3213 if (IS_2_WORD_TYPE(d))
3214 M_DMOV(REG_FRESULT, s1);
3216 M_FMOV(REG_FRESULT, s1);
3218 emit_store_dst(jd, iptr, s1);
3223 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3225 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3229 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3234 super = iptr->sx.s23.s3.c.cls;
3235 superindex = super->index;
3238 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3240 /* if class is not resolved, check which code to call */
3242 if (super == NULL) {
3243 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3245 cr = iptr->sx.s23.s3.c.ref;
3246 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3248 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3251 M_ILD(REG_ITMP2, REG_PV, disp);
3252 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3253 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3256 /* interface checkcast code */
3258 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3259 if (super == NULL) {
3260 cr = iptr->sx.s23.s3.c.ref;
3262 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3266 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3269 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3270 M_ILD(REG_ITMP3, REG_ITMP2,
3271 OFFSET(vftbl_t, interfacetablelength));
3272 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3273 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3275 M_ALD(REG_ITMP3, REG_ITMP2,
3276 OFFSET(vftbl_t, interfacetable[0]) -
3277 superindex * sizeof(methodptr*));
3278 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3281 emit_label_br(cd, BRANCH_LABEL_4);
3283 emit_label(cd, BRANCH_LABEL_3);
3286 /* class checkcast code */
3288 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3289 if (super == NULL) {
3290 emit_label(cd, BRANCH_LABEL_2);
3292 cr = iptr->sx.s23.s3.c.ref;
3293 disp = dseg_add_unique_address(cd, NULL);
3295 patcher_add_patch_ref(jd,
3296 PATCHER_resolve_classref_to_vftbl,
3300 disp = dseg_add_address(cd, super->vftbl);
3302 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3305 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3306 M_ALD(REG_ITMP3, REG_PV, disp);
3308 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3309 /* if (s1 != REG_ITMP1) { */
3310 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3311 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3312 /* #if defined(ENABLE_THREADS) */
3313 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3315 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3317 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3318 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3319 M_ALD(REG_ITMP3, REG_PV, disp);
3320 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3323 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3324 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3327 emit_label(cd, BRANCH_LABEL_5);
3330 if (super == NULL) {
3331 emit_label(cd, BRANCH_LABEL_1);
3332 emit_label(cd, BRANCH_LABEL_4);
3335 d = codegen_reg_of_dst(jd, iptr, s1);
3338 s1 = emit_load_s1(jd, iptr, REG_A0);
3339 M_INTMOVE(s1, REG_A0);
3341 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3342 cr = iptr->sx.s23.s3.c.ref;
3343 disp = dseg_add_unique_address(cd, NULL);
3345 patcher_add_patch_ref(jd,
3346 PATCHER_resolve_classref_to_classinfo,
3350 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3353 M_ALD(REG_A1, REG_PV, disp);
3354 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3355 M_ALD(REG_ITMP3, REG_PV, disp);
3356 M_JSR(REG_RA, REG_ITMP3);
3359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3360 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3362 d = codegen_reg_of_dst(jd, iptr, s1);
3366 emit_store_dst(jd, iptr, d);
3369 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3375 super = iptr->sx.s23.s3.c.cls;
3377 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3382 super = iptr->sx.s23.s3.c.cls;
3383 superindex = super->index;
3386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3390 M_MOV(s1, REG_ITMP1);
3396 /* if class is not resolved, check which code to call */
3398 if (super == NULL) {
3399 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3401 cr = iptr->sx.s23.s3.c.ref;
3402 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3404 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3407 M_ILD(REG_ITMP3, REG_PV, disp);
3408 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3409 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3412 /* interface instanceof code */
3414 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3415 if (super == NULL) {
3416 cr = iptr->sx.s23.s3.c.ref;
3418 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3422 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3425 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3426 M_ILD(REG_ITMP3, REG_ITMP1,
3427 OFFSET(vftbl_t, interfacetablelength));
3428 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3429 M_BLEZ(REG_ITMP3, 3);
3431 M_ALD(REG_ITMP1, REG_ITMP1,
3432 OFFSET(vftbl_t, interfacetable[0]) -
3433 superindex * sizeof(methodptr*));
3434 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3437 emit_label_br(cd, BRANCH_LABEL_4);
3439 emit_label(cd, BRANCH_LABEL_3);
3442 /* class instanceof code */
3444 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3445 if (super == NULL) {
3446 emit_label(cd, BRANCH_LABEL_2);
3448 cr = iptr->sx.s23.s3.c.ref;
3449 disp = dseg_add_unique_address(cd, NULL);
3451 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3455 disp = dseg_add_address(cd, super->vftbl);
3457 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3460 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3461 M_ALD(REG_ITMP2, REG_PV, disp);
3463 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3464 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3465 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3467 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3468 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3472 emit_label(cd, BRANCH_LABEL_5);
3475 if (super == NULL) {
3476 emit_label(cd, BRANCH_LABEL_1);
3477 emit_label(cd, BRANCH_LABEL_4);
3480 emit_store_dst(jd, iptr, d);
3484 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3486 /* check for negative sizes and copy sizes to stack if necessary */
3488 MCODECHECK((iptr->s1.argcount << 1) + 64);
3490 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3492 var = VAR(iptr->sx.s23.s2.args[s1]);
3494 /* copy SAVEDVAR sizes to stack */
3496 if (!(var->flags & PREALLOC)) {
3497 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3498 #if SIZEOF_VOID_P == 8
3499 M_LST(s2, REG_SP, s1 * 8);
3501 M_IST(s2, REG_SP, (s1 + 2) * 8);
3506 /* a0 = dimension count */
3508 ICONST(REG_A0, iptr->s1.argcount);
3510 /* is patcher function set? */
3512 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3513 cr = iptr->sx.s23.s3.c.ref;
3514 disp = dseg_add_unique_address(cd, NULL);
3516 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3520 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3523 /* a1 = arraydescriptor */
3525 M_ALD(REG_A1, REG_PV, disp);
3527 /* a2 = pointer to dimensions = stack pointer */
3529 #if SIZEOF_VOID_P == 8
3530 M_MOV(REG_SP, REG_A2);
3532 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3535 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3536 M_ALD(REG_ITMP3, REG_PV, disp);
3537 M_JSR(REG_RA, REG_ITMP3);
3540 /* check for exception before result assignment */
3542 emit_exception_check(cd, iptr);
3544 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3545 M_INTMOVE(REG_RESULT, d);
3546 emit_store_dst(jd, iptr, d);
3550 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3555 } /* for instruction */
3557 MCODECHECK(64); /* XXX require smaller number? */
3559 /* At the end of a basic block we may have to append some nops,
3560 because the patcher stub calling code might be longer than the
3561 actual instruction. So codepatching does not change the
3562 following block unintentionally. */
3564 if (cd->mcodeptr < cd->lastmcodeptr) {
3565 while (cd->mcodeptr < cd->lastmcodeptr)
3569 } /* if (bptr -> flags >= BBREACHED) */
3570 } /* for basic block */
3572 /* generate traps */
3574 emit_patcher_traps(jd);
3576 /* everything's ok */
3582 /* codegen_emit_stub_native ****************************************************
3584 Emits a stub routine which calls a native method.
3586 *******************************************************************************/
3588 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3599 /* get required compiler data */
3605 /* initialize variables */
3609 /* calculate stack frame size */
3611 cd->stackframesize =
3612 1 + /* return address */
3613 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3614 sizeof(localref_table) / SIZEOF_VOID_P +
3615 md->paramcount + /* for saving arguments over calls */
3616 #if SIZEOF_VOID_P == 4
3617 5 + /* additional save space (MIPS32) */
3619 1 + /* for saving return address */
3622 /* adjust stackframe size for 16-byte alignment */
3624 if (cd->stackframesize & 1)
3625 cd->stackframesize++;
3627 /* create method header */
3629 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3630 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3631 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3632 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3633 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3635 /* generate stub code */
3637 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3638 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3640 #if !defined(NDEBUG)
3641 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3642 emit_verbosecall_enter(jd);
3645 /* save integer and float argument registers */
3647 #if SIZEOF_VOID_P == 8
3648 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3649 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3650 s1 = md->params[i].regoff;
3651 M_AST(s1, REG_SP, j * 8);
3656 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3657 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3658 if (!md->params[i].inmemory) {
3659 s1 = md->params[i].regoff;
3661 if (IS_2_WORD_TYPE(md->params[i].type))
3662 M_LST(s1, REG_SP, j * 8);
3664 M_IST(s1, REG_SP, j * 8);
3672 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3673 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3674 s1 = md->params[i].regoff;
3676 if (IS_2_WORD_TYPE(md->params[i].type))
3677 M_DST(s1, REG_SP, j * 8);
3679 M_FST(s1, REG_SP, j * 8);
3685 /* prepare data structures for native function call */
3687 M_MOV(REG_SP, REG_A0);
3688 M_MOV(REG_PV, REG_A1);
3689 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3690 M_ALD(REG_ITMP3, REG_PV, disp);
3691 M_JSR(REG_RA, REG_ITMP3);
3692 M_NOP; /* XXX fill me! */
3694 /* remember class argument */
3696 if (m->flags & ACC_STATIC)
3697 M_MOV(REG_RESULT, REG_ITMP3);
3699 /* restore integer and float argument registers */
3701 #if SIZEOF_VOID_P == 8
3702 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3703 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3704 s1 = md->params[i].regoff;
3705 M_LLD(s1, REG_SP, j * 8);
3710 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3711 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3712 if (!md->params[i].inmemory) {
3713 s1 = md->params[i].regoff;
3715 if (IS_2_WORD_TYPE(md->params[i].type))
3716 M_LLD(s1, REG_SP, j * 8);
3718 M_ILD(s1, REG_SP, j * 8);
3726 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3727 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3728 s1 = md->params[i].regoff;
3730 if (IS_2_WORD_TYPE(md->params[i].type))
3731 M_DLD(s1, REG_SP, j * 8);
3733 M_FLD(s1, REG_SP, j * 8);
3739 /* copy or spill arguments to new locations */
3741 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3742 t = md->params[i].type;
3744 if (IS_INT_LNG_TYPE(t)) {
3745 if (!md->params[i].inmemory) {
3746 s1 = md->params[i].regoff;
3747 s2 = nmd->params[j].regoff;
3749 if (!nmd->params[j].inmemory) {
3750 #if SIZEOF_VOID_P == 8
3753 if (IS_2_WORD_TYPE(t))
3760 #if SIZEOF_VOID_P == 8
3761 M_LST(s1, REG_SP, s2);
3763 if (IS_2_WORD_TYPE(t))
3764 M_LST(s1, REG_SP, s2);
3766 M_IST(s1, REG_SP, s2);
3771 s1 = md->params[i].regoff + cd->stackframesize * 8;
3772 s2 = nmd->params[j].regoff;
3774 #if SIZEOF_VOID_P == 8
3775 M_LLD(REG_ITMP1, REG_SP, s1);
3776 M_LST(REG_ITMP1, REG_SP, s2);
3778 if (IS_2_WORD_TYPE(t)) {
3779 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3780 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3783 M_ILD(REG_ITMP1, REG_SP, s1);
3784 M_IST(REG_ITMP1, REG_SP, s2);
3790 if (!md->params[i].inmemory) {
3791 s1 = md->params[i].regoff;
3792 s2 = nmd->params[j].regoff;
3794 if (!nmd->params[j].inmemory) {
3795 #if SIZEOF_VOID_P == 8
3796 if (IS_2_WORD_TYPE(t))
3801 /* On MIPS32 float arguments for native functions
3802 can never be in float argument registers, since
3803 the first argument is _always_ an integer
3804 argument (JNIEnv) */
3806 if (IS_2_WORD_TYPE(t)) {
3807 /* double high/low order is endian
3808 independent: even numbered holds low
3809 32-bits, odd numbered high 32-bits */
3811 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3812 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3819 #if SIZEOF_VOID_P == 8
3820 if (IS_2_WORD_TYPE(t))
3821 M_DST(s1, REG_SP, s2);
3823 M_FST(s1, REG_SP, s2);
3825 /* s1 may have been originally in 2 int registers,
3826 but was moved out by the native function
3827 argument(s), just get low register */
3829 if (IS_2_WORD_TYPE(t))
3830 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3832 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3837 s1 = md->params[i].regoff + cd->stackframesize * 8;
3838 s2 = nmd->params[j].regoff;
3840 #if SIZEOF_VOID_P == 8
3841 if (IS_2_WORD_TYPE(t)) {
3842 M_DLD(REG_FTMP1, REG_SP, s1);
3843 M_DST(REG_FTMP1, REG_SP, s2);
3846 M_FLD(REG_FTMP1, REG_SP, s1);
3847 M_FST(REG_FTMP1, REG_SP, s2);
3850 if (IS_2_WORD_TYPE(t)) {
3851 M_DLD(REG_FTMP1, REG_SP, s1);
3852 M_DST(REG_FTMP1, REG_SP, s2);
3855 M_FLD(REG_FTMP1, REG_SP, s1);
3856 M_FST(REG_FTMP1, REG_SP, s2);
3863 /* Handle native Java methods. */
3865 if (m->flags & ACC_NATIVE) {
3866 /* put class into second argument register */
3868 if (m->flags & ACC_STATIC)
3869 M_MOV(REG_ITMP3, REG_A1);
3871 /* put env into first argument register */
3873 disp = dseg_add_address(cd, VM_get_jnienv());
3874 M_ALD(REG_A0, REG_PV, disp);
3877 /* Call the native function. */
3879 disp = dseg_add_functionptr(cd, f);
3880 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3881 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3882 M_NOP; /* delay slot */
3884 /* save return value */
3886 switch (md->returntype.type) {
3887 #if SIZEOF_VOID_P == 8
3891 M_LST(REG_RESULT, REG_SP, 0 * 8);
3895 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3900 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3903 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3907 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3914 #if !defined(NDEBUG)
3915 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3916 emit_verbosecall_exit(jd);
3919 /* remove native stackframe info */
3921 M_MOV(REG_SP, REG_A0);
3922 M_MOV(REG_PV, REG_A1);
3923 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3924 M_ALD(REG_ITMP3, REG_PV, disp);
3925 M_JSR(REG_RA, REG_ITMP3);
3926 M_NOP; /* XXX fill me! */
3927 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3929 /* restore return value */
3931 switch (md->returntype.type) {
3932 #if SIZEOF_VOID_P == 8
3936 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3940 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3945 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3948 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3952 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3959 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3961 /* check for exception */
3963 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3964 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3966 M_RET(REG_RA); /* return to caller */
3967 M_NOP; /* DELAY SLOT */
3969 /* handle exception */
3971 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3972 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3973 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3974 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3976 /* Generate patcher traps. */
3978 emit_patcher_traps(jd);
3983 * These are local overrides for various environment variables in Emacs.
3984 * Please do not remove this and leave it at the end of the file, where
3985 * Emacs will automagically detect them.
3986 * ---------------------------------------------------------------------
3989 * indent-tabs-mode: t
3993 * vim:noexpandtab:sw=4:ts=4: