1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "vm/jit/mips/arch.h"
36 #include "vm/jit/mips/codegen.h"
38 #include "mm/memory.hpp"
40 #include "native/localref.hpp"
41 #include "native/native.hpp"
43 #include "threads/lock.hpp"
45 #include "vm/jit/builtin.hpp"
46 #include "vm/class.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/options.h"
51 #include "vm/jit/abi.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.hpp"
54 #include "vm/jit/dseg.h"
55 #include "vm/jit/emit-common.hpp"
56 #include "vm/jit/jit.hpp"
57 #include "vm/jit/linenumbertable.hpp"
58 #include "vm/jit/patcher-common.hpp"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.hpp"
61 #include "vm/jit/trap.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);
1406 emit_label_bnez(cd, BRANCH_LABEL_1, d);
1407 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1408 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1409 M_CMPULT(s1, s2, REG_ITMP3);
1410 M_CMPULT(s2, s1, REG_ITMP1);
1411 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1412 emit_label(cd, BRANCH_LABEL_1);
1414 emit_store_dst(jd, iptr, d);
1418 /* floating operations ************************************************/
1420 case ICMD_FNEG: /* ..., value ==> ..., - value */
1422 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1423 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_DNEG: /* ..., value ==> ..., - value */
1430 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1433 emit_store_dst(jd, iptr, d);
1436 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1438 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1440 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1442 emit_store_dst(jd, iptr, d);
1445 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1447 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1448 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1449 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1451 emit_store_dst(jd, iptr, d);
1454 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1456 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1458 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1460 emit_store_dst(jd, iptr, d);
1463 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1465 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1467 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1469 emit_store_dst(jd, iptr, d);
1472 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1474 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1475 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1476 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1478 emit_store_dst(jd, iptr, d);
1481 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1483 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1485 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1487 emit_store_dst(jd, iptr, d);
1490 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1492 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1493 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1494 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1496 emit_store_dst(jd, iptr, d);
1499 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1501 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1502 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1503 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1505 emit_store_dst(jd, iptr, d);
1509 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1511 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1512 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1513 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1514 M_FDIV(s1,s2, REG_FTMP3);
1515 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1516 M_CVTLF(REG_FTMP3, REG_FTMP3);
1517 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1518 M_FSUB(s1, REG_FTMP3, d);
1519 emit_store_dst(jd, iptr, d);
1522 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1524 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1525 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1526 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1527 M_DDIV(s1,s2, REG_FTMP3);
1528 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1529 M_CVTLD(REG_FTMP3, REG_FTMP3);
1530 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1531 M_DSUB(s1, REG_FTMP3, d);
1532 emit_store_dst(jd, iptr, d);
1536 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1539 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1542 emit_store_dst(jd, iptr, d);
1545 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1548 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1551 emit_store_dst(jd, iptr, d);
1555 /* XXX these do not work correctly */
1557 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1559 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1561 M_TRUNCFI(s1, REG_FTMP1);
1562 M_MOVDI(REG_FTMP1, d);
1564 emit_store_dst(jd, iptr, d);
1567 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1569 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1571 M_TRUNCDI(s1, REG_FTMP1);
1572 M_MOVDI(REG_FTMP1, d);
1574 emit_store_dst(jd, iptr, d);
1577 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1579 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1581 M_TRUNCFL(s1, REG_FTMP1);
1582 M_MOVDL(REG_FTMP1, d);
1584 emit_store_dst(jd, iptr, d);
1587 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1589 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1591 M_TRUNCDL(s1, REG_FTMP1);
1592 M_MOVDL(REG_FTMP1, d);
1594 emit_store_dst(jd, iptr, d);
1598 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1600 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1601 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1603 emit_store_dst(jd, iptr, d);
1606 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1608 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1609 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1611 emit_store_dst(jd, iptr, d);
1614 #if SUPPORT_FLOAT_CMP
1615 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1617 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1618 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1622 M_AADD_IMM(REG_ZERO, 1, d);
1626 M_ASUB_IMM(REG_ZERO, 1, d);
1627 M_CMOVT(REG_ZERO, d);
1628 emit_store_dst(jd, iptr, d);
1631 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1633 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1634 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1638 M_ASUB_IMM(REG_ZERO, 1, d);
1642 M_AADD_IMM(REG_ZERO, 1, d);
1643 M_CMOVT(REG_ZERO, d);
1644 emit_store_dst(jd, iptr, d);
1648 #if SUPPORT_DOUBLE_CMP
1649 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1651 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1652 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1656 M_AADD_IMM(REG_ZERO, 1, d);
1660 M_ASUB_IMM(REG_ZERO, 1, d);
1661 M_CMOVT(REG_ZERO, d);
1662 emit_store_dst(jd, iptr, d);
1665 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1667 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1668 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1672 M_ASUB_IMM(REG_ZERO, 1, d);
1676 M_AADD_IMM(REG_ZERO, 1, d);
1677 M_CMOVT(REG_ZERO, d);
1678 emit_store_dst(jd, iptr, d);
1683 /* memory operations **************************************************/
1685 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1689 /* implicit null-pointer check */
1690 M_ILD(d, s1, OFFSET(java_array_t, size));
1691 emit_store_dst(jd, iptr, d);
1694 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1699 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1700 M_AADD(s2, s1, REG_ITMP3);
1701 /* implicit null-pointer check */
1702 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1703 emit_store_dst(jd, iptr, d);
1706 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1711 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1712 M_AADD(s2, s1, REG_ITMP3);
1713 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1714 /* implicit null-pointer check */
1715 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1716 emit_store_dst(jd, iptr, d);
1719 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1722 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1724 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1725 M_AADD(s2, s1, REG_ITMP3);
1726 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1727 /* implicit null-pointer check */
1728 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1729 emit_store_dst(jd, iptr, d);
1732 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1737 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1738 M_ASLL_IMM(s2, 2, REG_ITMP3);
1739 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1740 /* implicit null-pointer check */
1741 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1742 emit_store_dst(jd, iptr, d);
1745 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1748 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1749 #if SIZEOF_VOID_P == 8
1750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1754 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1755 M_ASLL_IMM(s2, 3, REG_ITMP3);
1756 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1757 /* implicit null-pointer check */
1758 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1759 emit_store_dst(jd, iptr, d);
1762 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1766 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1767 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1768 M_ASLL_IMM(s2, 2, REG_ITMP3);
1769 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1770 /* implicit null-pointer check */
1771 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1772 emit_store_dst(jd, iptr, d);
1775 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1779 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1780 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1781 M_ASLL_IMM(s2, 3, REG_ITMP3);
1782 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1783 /* implicit null-pointer check */
1784 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1785 emit_store_dst(jd, iptr, d);
1788 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1793 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1794 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1795 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1796 /* implicit null-pointer check */
1797 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1798 emit_store_dst(jd, iptr, d);
1802 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1806 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1807 M_AADD(s2, s1, REG_ITMP1);
1808 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1809 /* implicit null-pointer check */
1810 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1813 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1814 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1817 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1818 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1819 M_AADD(s2, s1, REG_ITMP1);
1820 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1821 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1822 /* implicit null-pointer check */
1823 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1826 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1829 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1830 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1831 M_ASLL_IMM(s2, 2, REG_ITMP2);
1832 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1833 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1834 /* implicit null-pointer check */
1835 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1838 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1842 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1843 M_ASLL_IMM(s2, 3, REG_ITMP2);
1844 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1845 #if SIZEOF_VOID_P == 8
1846 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1848 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1850 /* implicit null-pointer check */
1851 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1854 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1857 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1858 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1859 M_ASLL_IMM(s2, 2, REG_ITMP2);
1860 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1861 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1862 /* implicit null-pointer check */
1863 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1866 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1870 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1871 M_ASLL_IMM(s2, 3, REG_ITMP2);
1872 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1873 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1874 /* implicit null-pointer check */
1875 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1879 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1883 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1884 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1886 M_INTMOVE(s1, REG_A0);
1887 M_INTMOVE(s3, REG_A1);
1888 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1889 M_ALD(REG_ITMP3, REG_PV, disp);
1890 M_JSR(REG_RA, REG_ITMP3);
1892 emit_arraystore_check(cd, iptr);
1894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1896 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1897 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1898 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1899 /* implicit null-pointer check */
1900 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1904 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1907 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1908 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1909 M_AADD(s2, s1, REG_ITMP1);
1910 /* implicit null-pointer check */
1911 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1914 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1915 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1918 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1919 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1920 M_AADD(s2, s1, REG_ITMP1);
1921 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1922 /* implicit null-pointer check */
1923 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1926 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1929 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1930 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1931 M_ASLL_IMM(s2, 2, REG_ITMP2);
1932 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1933 /* implicit null-pointer check */
1934 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1937 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1940 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1941 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1942 M_ASLL_IMM(s2, 3, REG_ITMP2);
1943 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1944 /* implicit null-pointer check */
1945 #if SIZEOF_VOID_P == 8
1946 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1948 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1952 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1955 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1956 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1957 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1958 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1959 /* implicit null-pointer check */
1960 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1964 case ICMD_GETSTATIC: /* ... ==> ..., value */
1966 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1967 uf = iptr->sx.s23.s3.uf;
1968 fieldtype = uf->fieldref->parseddesc.fd->type;
1969 disp = dseg_add_unique_address(cd, uf);
1971 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1974 fi = iptr->sx.s23.s3.fmiref->p.field;
1975 fieldtype = fi->type;
1976 disp = dseg_add_address(cd, fi->value);
1978 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1979 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1983 M_ALD(REG_ITMP1, REG_PV, disp);
1985 switch (fieldtype) {
1987 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1988 M_ILD_INTERN(d, REG_ITMP1, 0);
1991 #if SIZEOF_VOID_P == 8
1992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1994 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1996 M_LLD_INTERN(d, REG_ITMP1, 0);
1999 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2000 M_ALD_INTERN(d, REG_ITMP1, 0);
2003 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2004 M_FLD_INTERN(d, REG_ITMP1, 0);
2007 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2008 M_DLD_INTERN(d, REG_ITMP1, 0);
2011 emit_store_dst(jd, iptr, d);
2014 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2017 uf = iptr->sx.s23.s3.uf;
2018 fieldtype = uf->fieldref->parseddesc.fd->type;
2019 disp = dseg_add_unique_address(cd, uf);
2021 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2024 fi = iptr->sx.s23.s3.fmiref->p.field;
2025 fieldtype = fi->type;
2026 disp = dseg_add_address(cd, fi->value);
2028 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2029 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2033 M_ALD(REG_ITMP1, REG_PV, disp);
2035 switch (fieldtype) {
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2038 M_IST_INTERN(s1, REG_ITMP1, 0);
2041 #if SIZEOF_VOID_P == 8
2042 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2044 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2046 M_LST_INTERN(s1, REG_ITMP1, 0);
2049 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2050 M_AST_INTERN(s1, REG_ITMP1, 0);
2053 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2054 M_FST_INTERN(s1, REG_ITMP1, 0);
2057 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2058 M_DST_INTERN(s1, REG_ITMP1, 0);
2063 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2066 uf = iptr->sx.s23.s3.uf;
2067 fieldtype = uf->fieldref->parseddesc.fd->type;
2068 disp = dseg_add_unique_address(cd, uf);
2070 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2073 fi = iptr->sx.s23.s3.fmiref->p.field;
2074 fieldtype = fi->type;
2075 disp = dseg_add_address(cd, fi->value);
2077 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2078 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2082 M_ALD(REG_ITMP1, REG_PV, disp);
2084 switch (fieldtype) {
2086 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2089 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2092 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2095 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2098 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2104 case ICMD_GETFIELD: /* ... ==> ..., value */
2106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2107 emit_nullpointer_check(cd, iptr, s1);
2109 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2110 uf = iptr->sx.s23.s3.uf;
2111 fieldtype = uf->fieldref->parseddesc.fd->type;
2114 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2117 fi = iptr->sx.s23.s3.fmiref->p.field;
2118 fieldtype = fi->type;
2122 switch (fieldtype) {
2124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2128 #if SIZEOF_VOID_P == 8
2129 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2133 M_LLD_GETFIELD(d, s1, disp);
2137 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2145 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2149 emit_store_dst(jd, iptr, d);
2152 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 emit_nullpointer_check(cd, iptr, s1);
2157 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2158 uf = iptr->sx.s23.s3.uf;
2159 fieldtype = uf->fieldref->parseddesc.fd->type;
2163 fi = iptr->sx.s23.s3.fmiref->p.field;
2164 fieldtype = fi->type;
2168 #if SIZEOF_VOID_P == 8
2169 if (IS_INT_LNG_TYPE(fieldtype))
2170 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2172 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2174 if (IS_INT_LNG_TYPE(fieldtype)) {
2175 if (IS_2_WORD_TYPE(fieldtype))
2176 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2178 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2181 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2184 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2185 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2187 switch (fieldtype) {
2189 M_IST(s2, s1, disp);
2192 M_LST(s2, s1, disp);
2195 M_AST(s2, s1, disp);
2198 M_FST(s2, s1, disp);
2201 M_DST(s2, s1, disp);
2206 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2208 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2209 emit_nullpointer_check(cd, iptr, s1);
2211 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2212 uf = iptr->sx.s23.s3.uf;
2213 fieldtype = uf->fieldref->parseddesc.fd->type;
2216 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2219 fi = iptr->sx.s23.s3.fmiref->p.field;
2220 fieldtype = fi->type;
2224 switch (fieldtype) {
2226 M_IST(REG_ZERO, s1, disp);
2229 M_LST(REG_ZERO, s1, disp);
2232 M_AST(REG_ZERO, s1, disp);
2235 M_FST(REG_ZERO, s1, disp);
2238 M_DST(REG_ZERO, s1, disp);
2244 /* branch operations **************************************************/
2246 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2249 M_INTMOVE(s1, REG_ITMP1_XPTR);
2251 #ifdef ENABLE_VERIFIER
2252 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2253 uc = iptr->sx.s23.s2.uc;
2255 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2257 #endif /* ENABLE_VERIFIER */
2259 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 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2434 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2435 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2436 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2437 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2438 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bgtz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2464 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2465 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2466 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2474 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2475 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2476 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2477 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2478 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bltz(cd, BRANCH_LABEL_1, GET_HIGH_REG(s1));
2534 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2535 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2543 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2544 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2545 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2546 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2547 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bne(cd, BRANCH_LABEL_1, s1, REG_ITMP2);
2580 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2581 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2582 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2583 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2584 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bne(cd, BRANCH_LABEL_1, s1, s2);
2607 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2608 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2609 emit_beq(cd, iptr->dst.block, s1, s2);
2610 emit_label(cd, BRANCH_LABEL_1);
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 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2658 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2659 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2660 M_CMPULT(s1, s2, REG_ITMP3);
2661 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2662 emit_label(cd, BRANCH_LABEL_1);
2666 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2667 #if SIZEOF_VOID_P == 8
2668 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2672 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2673 M_CMPGT(s1, s2, REG_ITMP3);
2674 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2677 #if SIZEOF_VOID_P == 4
2678 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2680 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2681 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2682 M_CMPGT(s1, s2, REG_ITMP3);
2683 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2684 M_CMPLT(s1, s2, REG_ITMP3);
2685 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2686 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2687 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2688 M_CMPUGT(s1, s2, REG_ITMP3);
2689 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2690 emit_label(cd, BRANCH_LABEL_1);
2694 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2695 #if SIZEOF_VOID_P == 8
2696 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2701 M_CMPGT(s1, s2, REG_ITMP3);
2702 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2705 #if SIZEOF_VOID_P == 4
2706 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2708 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2709 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2710 M_CMPLT(s1, s2, REG_ITMP3);
2711 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2712 M_CMPGT(s1, s2, REG_ITMP3);
2713 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2714 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2715 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2716 M_CMPUGT(s1, s2, REG_ITMP3);
2717 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2718 emit_label(cd, BRANCH_LABEL_1);
2722 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2723 #if SIZEOF_VOID_P == 8
2724 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2729 M_CMPLT(s1, s2, REG_ITMP3);
2730 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2733 #if SIZEOF_VOID_P == 4
2734 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2736 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2737 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2738 M_CMPGT(s1, s2, REG_ITMP3);
2739 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2740 M_CMPLT(s1, s2, REG_ITMP3);
2741 emit_label_bnez(cd, BRANCH_LABEL_1, REG_ITMP3);
2742 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2743 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2744 M_CMPULT(s1, s2, REG_ITMP3);
2745 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2746 emit_label(cd, BRANCH_LABEL_1);
2750 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2751 #if SIZEOF_VOID_P == 8
2755 REPLACEMENT_POINT_RETURN(cd, iptr);
2756 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2757 M_INTMOVE(s1, REG_RESULT);
2758 goto nowperformreturn;
2760 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2762 REPLACEMENT_POINT_RETURN(cd, iptr);
2763 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2764 M_INTMOVE(s1, REG_RESULT);
2766 #ifdef ENABLE_VERIFIER
2767 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2768 uc = iptr->sx.s23.s2.uc;
2770 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2772 #endif /* ENABLE_VERIFIER */
2773 goto nowperformreturn;
2775 #if SIZEOF_VOID_P == 4
2776 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2778 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2779 M_LNGMOVE(s1, REG_RESULT_PACKED);
2780 goto nowperformreturn;
2783 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2784 REPLACEMENT_POINT_RETURN(cd, iptr);
2785 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2786 M_FLTMOVE(s1, REG_FRESULT);
2787 goto nowperformreturn;
2789 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2791 REPLACEMENT_POINT_RETURN(cd, iptr);
2792 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2793 M_DBLMOVE(s1, REG_FRESULT);
2794 goto nowperformreturn;
2796 case ICMD_RETURN: /* ... ==> ... */
2798 REPLACEMENT_POINT_RETURN(cd, iptr);
2804 p = cd->stackframesize;
2806 #if !defined(NDEBUG)
2807 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2808 emit_verbosecall_exit(jd);
2811 #if defined(ENABLE_THREADS)
2812 if (checksync && code_is_synchronized(code)) {
2813 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2814 M_ALD(REG_ITMP3, REG_PV, disp);
2816 /* we need to save the proper return value */
2818 switch (iptr->opc) {
2821 #if SIZEOF_VOID_P == 8
2824 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2825 M_JSR(REG_RA, REG_ITMP3);
2826 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2828 #if SIZEOF_VOID_P == 4
2830 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2831 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2832 M_JSR(REG_RA, REG_ITMP3);
2838 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2839 M_JSR(REG_RA, REG_ITMP3);
2840 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2843 M_JSR(REG_RA, REG_ITMP3);
2844 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2848 /* and now restore the proper return value */
2850 switch (iptr->opc) {
2853 #if SIZEOF_VOID_P == 8
2856 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2858 #if SIZEOF_VOID_P == 4
2860 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2865 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2871 /* restore return address */
2873 if (!code_is_leafmethod(code)) {
2874 p--; M_ALD(REG_RA, REG_SP, p * 8);
2877 /* restore saved registers */
2879 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2880 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2882 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2883 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2886 /* deallocate stack and return */
2888 if (cd->stackframesize) {
2891 disp = cd->stackframesize * 8;
2892 lo = (short) (disp);
2893 hi = (short) (((disp) - lo) >> 16);
2897 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2899 M_LUI(REG_ITMP3,hi);
2900 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2902 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2915 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2918 branch_target_t *table;
2920 table = iptr->dst.table;
2922 l = iptr->sx.s23.s2.tablelow;
2923 i = iptr->sx.s23.s3.tablehigh;
2925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2927 {M_INTMOVE(s1, REG_ITMP1);}
2928 else if (l <= 32768) {
2929 M_IADD_IMM(s1, -l, REG_ITMP1);
2932 ICONST(REG_ITMP2, l);
2933 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2936 /* number of targets */
2941 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2942 emit_beqz(cd, table[0].block, REG_ITMP2);
2944 /* build jump table top down and use address of lowest entry */
2949 dseg_add_target(cd, table->block);
2954 /* length of dataseg after last dseg_add_target is used by load */
2956 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2957 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2958 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2965 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2968 lookup_target_t *lookup;
2970 lookup = iptr->dst.lookup;
2972 i = iptr->sx.s23.s2.lookupcount;
2974 MCODECHECK((i<<2)+8);
2975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2978 ICONST(REG_ITMP2, lookup->value);
2979 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2983 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2989 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2991 bte = iptr->sx.s23.s3.bte;
2995 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2997 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2998 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2999 case ICMD_INVOKEINTERFACE:
3001 REPLACEMENT_POINT_INVOKE(cd, iptr);
3003 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3005 um = iptr->sx.s23.s3.um;
3006 md = um->methodref->parseddesc.md;
3009 lm = iptr->sx.s23.s3.fmiref->p.method;
3011 md = lm->parseddesc;
3015 s3 = md->paramcount;
3017 MCODECHECK((s3 << 1) + 64);
3019 /* copy arguments to registers or stack location */
3021 for (s3 = s3 - 1; s3 >= 0; s3--) {
3022 var = VAR(iptr->sx.s23.s2.args[s3]);
3023 d = md->params[s3].regoff;
3025 if (var->flags & PREALLOC)
3028 if (IS_INT_LNG_TYPE(var->type)) {
3029 #if SIZEOF_VOID_P == 8
3030 if (!md->params[s3].inmemory) {
3031 s1 = emit_load(jd, iptr, var, d);
3035 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3036 M_LST(s1, REG_SP, d);
3039 if (!md->params[s3].inmemory) {
3040 s1 = emit_load(jd, iptr, var, d);
3042 if (IS_2_WORD_TYPE(var->type))
3048 if (IS_2_WORD_TYPE(var->type)) {
3049 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3050 M_LST(s1, REG_SP, d);
3053 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3054 M_IST(s1, REG_SP, d);
3060 if (!md->params[s3].inmemory) {
3061 s1 = emit_load(jd, iptr, var, d);
3062 if (IS_2_WORD_TYPE(var->type))
3068 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3069 if (IS_2_WORD_TYPE(var->type))
3070 M_DST(s1, REG_SP, d);
3072 M_FST(s1, REG_SP, d);
3077 switch (iptr->opc) {
3079 if (bte->stub == NULL) {
3080 disp = dseg_add_functionptr(cd, bte->fp);
3081 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3083 /* generate the actual call */
3085 /* TWISTI: i actually don't know the reason for using
3086 REG_ITMP3 here instead of REG_PV. */
3088 M_JSR(REG_RA, REG_ITMP3);
3092 disp = dseg_add_functionptr(cd, bte->stub);
3093 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3095 /* generate the actual call */
3097 M_JSR(REG_RA, REG_PV);
3101 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3102 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3103 M_LDA(REG_PV, REG_RA, -disp);
3106 case ICMD_INVOKESPECIAL:
3107 emit_nullpointer_check(cd, iptr, REG_A0);
3110 case ICMD_INVOKESTATIC:
3112 disp = dseg_add_unique_address(cd, um);
3114 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3118 disp = dseg_add_address(cd, lm->stubroutine);
3120 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3122 /* generate the actual call */
3124 M_JSR(REG_RA, REG_PV);
3126 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3127 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3128 M_LDA(REG_PV, REG_RA, -disp);
3131 case ICMD_INVOKEVIRTUAL:
3132 emit_nullpointer_check(cd, iptr, REG_A0);
3135 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3140 s1 = OFFSET(vftbl_t, table[0]) +
3141 sizeof(methodptr) * lm->vftblindex;
3143 /* implicit null-pointer check */
3144 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3145 M_ALD(REG_PV, REG_METHODPTR, s1);
3147 /* generate the actual call */
3149 M_JSR(REG_RA, REG_PV);
3151 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3152 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3153 M_LDA(REG_PV, REG_RA, -disp);
3156 case ICMD_INVOKEINTERFACE:
3157 emit_nullpointer_check(cd, iptr, REG_A0);
3160 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3166 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3167 sizeof(methodptr*) * lm->clazz->index;
3169 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
3172 /* implicit null-pointer check */
3173 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3174 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3175 M_ALD(REG_PV, REG_METHODPTR, s2);
3177 /* generate the actual call */
3179 M_JSR(REG_RA, REG_PV);
3181 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3182 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3183 M_LDA(REG_PV, REG_RA, -disp);
3187 /* store return value */
3189 d = md->returntype.type;
3191 if (d != TYPE_VOID) {
3192 if (IS_INT_LNG_TYPE(d)) {
3193 #if SIZEOF_VOID_P == 8
3194 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3195 M_INTMOVE(REG_RESULT, s1);
3197 if (IS_2_WORD_TYPE(d)) {
3198 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3199 M_LNGMOVE(REG_RESULT_PACKED, s1);
3202 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3203 M_INTMOVE(REG_RESULT, s1);
3208 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3209 if (IS_2_WORD_TYPE(d))
3210 M_DMOV(REG_FRESULT, s1);
3212 M_FMOV(REG_FRESULT, s1);
3214 emit_store_dst(jd, iptr, s1);
3219 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3221 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3225 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3230 super = iptr->sx.s23.s3.c.cls;
3231 superindex = super->index;
3234 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3236 /* if class is not resolved, check which code to call */
3238 if (super == NULL) {
3239 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3241 cr = iptr->sx.s23.s3.c.ref;
3242 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3244 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3247 M_ILD(REG_ITMP2, REG_PV, disp);
3248 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3249 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3252 /* interface checkcast code */
3254 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3255 if (super == NULL) {
3256 cr = iptr->sx.s23.s3.c.ref;
3258 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3262 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3265 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3266 M_ILD(REG_ITMP3, REG_ITMP2,
3267 OFFSET(vftbl_t, interfacetablelength));
3268 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3269 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3271 M_ALD(REG_ITMP3, REG_ITMP2,
3272 OFFSET(vftbl_t, interfacetable[0]) -
3273 superindex * sizeof(methodptr*));
3274 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3277 emit_label_br(cd, BRANCH_LABEL_4);
3279 emit_label(cd, BRANCH_LABEL_3);
3282 /* class checkcast code */
3284 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3285 if (super == NULL) {
3286 emit_label(cd, BRANCH_LABEL_2);
3288 cr = iptr->sx.s23.s3.c.ref;
3289 disp = dseg_add_unique_address(cd, NULL);
3291 patcher_add_patch_ref(jd,
3292 PATCHER_resolve_classref_to_vftbl,
3296 disp = dseg_add_address(cd, super->vftbl);
3298 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3301 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3302 M_ALD(REG_ITMP3, REG_PV, disp);
3304 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3305 /* if (s1 != REG_ITMP1) { */
3306 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3307 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3308 /* #if defined(ENABLE_THREADS) */
3309 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3311 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3313 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3314 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3315 M_ALD(REG_ITMP3, REG_PV, disp);
3316 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3319 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3320 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3323 emit_label(cd, BRANCH_LABEL_5);
3326 if (super == NULL) {
3327 emit_label(cd, BRANCH_LABEL_1);
3328 emit_label(cd, BRANCH_LABEL_4);
3331 d = codegen_reg_of_dst(jd, iptr, s1);
3334 s1 = emit_load_s1(jd, iptr, REG_A0);
3335 M_INTMOVE(s1, REG_A0);
3337 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3338 cr = iptr->sx.s23.s3.c.ref;
3339 disp = dseg_add_unique_address(cd, NULL);
3341 patcher_add_patch_ref(jd,
3342 PATCHER_resolve_classref_to_classinfo,
3346 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3349 M_ALD(REG_A1, REG_PV, disp);
3350 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3351 M_ALD(REG_ITMP3, REG_PV, disp);
3352 M_JSR(REG_RA, REG_ITMP3);
3355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3356 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3358 d = codegen_reg_of_dst(jd, iptr, s1);
3362 emit_store_dst(jd, iptr, d);
3365 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3371 super = iptr->sx.s23.s3.c.cls;
3373 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3378 super = iptr->sx.s23.s3.c.cls;
3379 superindex = super->index;
3382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3383 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3386 M_MOV(s1, REG_ITMP1);
3392 /* if class is not resolved, check which code to call */
3394 if (super == NULL) {
3395 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3397 cr = iptr->sx.s23.s3.c.ref;
3398 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3400 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3403 M_ILD(REG_ITMP3, REG_PV, disp);
3404 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3405 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3408 /* interface instanceof code */
3410 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3411 if (super == NULL) {
3412 cr = iptr->sx.s23.s3.c.ref;
3414 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3418 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3421 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3422 M_ILD(REG_ITMP3, REG_ITMP1,
3423 OFFSET(vftbl_t, interfacetablelength));
3424 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3425 M_BLEZ(REG_ITMP3, 3);
3427 M_ALD(REG_ITMP1, REG_ITMP1,
3428 OFFSET(vftbl_t, interfacetable[0]) -
3429 superindex * sizeof(methodptr*));
3430 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3433 emit_label_br(cd, BRANCH_LABEL_4);
3435 emit_label(cd, BRANCH_LABEL_3);
3438 /* class instanceof code */
3440 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3441 if (super == NULL) {
3442 emit_label(cd, BRANCH_LABEL_2);
3444 cr = iptr->sx.s23.s3.c.ref;
3445 disp = dseg_add_unique_address(cd, NULL);
3447 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3451 disp = dseg_add_address(cd, super->vftbl);
3453 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3456 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3457 M_ALD(REG_ITMP2, REG_PV, disp);
3459 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3460 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3461 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3463 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3464 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3468 emit_label(cd, BRANCH_LABEL_5);
3471 if (super == NULL) {
3472 emit_label(cd, BRANCH_LABEL_1);
3473 emit_label(cd, BRANCH_LABEL_4);
3476 emit_store_dst(jd, iptr, d);
3480 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3482 /* check for negative sizes and copy sizes to stack if necessary */
3484 MCODECHECK((iptr->s1.argcount << 1) + 64);
3486 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3488 var = VAR(iptr->sx.s23.s2.args[s1]);
3490 /* copy SAVEDVAR sizes to stack */
3492 if (!(var->flags & PREALLOC)) {
3493 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3494 #if SIZEOF_VOID_P == 8
3495 M_LST(s2, REG_SP, s1 * 8);
3497 M_IST(s2, REG_SP, (s1 + 2) * 8);
3502 /* a0 = dimension count */
3504 ICONST(REG_A0, iptr->s1.argcount);
3506 /* is patcher function set? */
3508 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3509 cr = iptr->sx.s23.s3.c.ref;
3510 disp = dseg_add_unique_address(cd, NULL);
3512 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3516 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3519 /* a1 = arraydescriptor */
3521 M_ALD(REG_A1, REG_PV, disp);
3523 /* a2 = pointer to dimensions = stack pointer */
3525 #if SIZEOF_VOID_P == 8
3526 M_MOV(REG_SP, REG_A2);
3528 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3531 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3532 M_ALD(REG_ITMP3, REG_PV, disp);
3533 M_JSR(REG_RA, REG_ITMP3);
3536 /* check for exception before result assignment */
3538 emit_exception_check(cd, iptr);
3540 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3541 M_INTMOVE(REG_RESULT, d);
3542 emit_store_dst(jd, iptr, d);
3546 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3551 } /* for instruction */
3553 MCODECHECK(64); /* XXX require smaller number? */
3555 /* At the end of a basic block we may have to append some nops,
3556 because the patcher stub calling code might be longer than the
3557 actual instruction. So codepatching does not change the
3558 following block unintentionally. */
3560 if (cd->mcodeptr < cd->lastmcodeptr) {
3561 while (cd->mcodeptr < cd->lastmcodeptr)
3565 } /* if (bptr -> flags >= BBREACHED) */
3566 } /* for basic block */
3568 /* generate traps */
3570 emit_patcher_traps(jd);
3572 /* everything's ok */
3578 /* codegen_emit_stub_native ****************************************************
3580 Emits a stub routine which calls a native method.
3582 *******************************************************************************/
3584 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3595 /* get required compiler data */
3601 /* initialize variables */
3605 /* calculate stack frame size */
3607 cd->stackframesize =
3608 1 + /* return address */
3609 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3610 sizeof(localref_table) / SIZEOF_VOID_P +
3611 md->paramcount + /* for saving arguments over calls */
3612 #if SIZEOF_VOID_P == 4
3613 5 + /* additional save space (MIPS32) */
3615 1 + /* for saving return address */
3618 /* adjust stackframe size for 16-byte alignment */
3620 if (cd->stackframesize & 1)
3621 cd->stackframesize++;
3623 /* create method header */
3625 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3626 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3627 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3628 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3629 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3631 /* generate stub code */
3633 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3634 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3636 #if !defined(NDEBUG)
3637 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3638 emit_verbosecall_enter(jd);
3641 /* save integer and float argument registers */
3643 #if SIZEOF_VOID_P == 8
3644 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3645 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3646 s1 = md->params[i].regoff;
3647 M_AST(s1, REG_SP, j * 8);
3652 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3653 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3654 if (!md->params[i].inmemory) {
3655 s1 = md->params[i].regoff;
3657 if (IS_2_WORD_TYPE(md->params[i].type))
3658 M_LST(s1, REG_SP, j * 8);
3660 M_IST(s1, REG_SP, j * 8);
3668 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3669 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3670 s1 = md->params[i].regoff;
3672 if (IS_2_WORD_TYPE(md->params[i].type))
3673 M_DST(s1, REG_SP, j * 8);
3675 M_FST(s1, REG_SP, j * 8);
3681 /* prepare data structures for native function call */
3683 M_MOV(REG_SP, REG_A0);
3684 M_MOV(REG_PV, REG_A1);
3685 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3686 M_ALD(REG_ITMP3, REG_PV, disp);
3687 M_JSR(REG_RA, REG_ITMP3);
3688 M_NOP; /* XXX fill me! */
3690 /* remember class argument */
3692 if (m->flags & ACC_STATIC)
3693 M_MOV(REG_RESULT, REG_ITMP3);
3695 /* restore integer and float argument registers */
3697 #if SIZEOF_VOID_P == 8
3698 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3699 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3700 s1 = md->params[i].regoff;
3701 M_LLD(s1, REG_SP, j * 8);
3706 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3707 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3708 if (!md->params[i].inmemory) {
3709 s1 = md->params[i].regoff;
3711 if (IS_2_WORD_TYPE(md->params[i].type))
3712 M_LLD(s1, REG_SP, j * 8);
3714 M_ILD(s1, REG_SP, j * 8);
3722 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3723 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3724 s1 = md->params[i].regoff;
3726 if (IS_2_WORD_TYPE(md->params[i].type))
3727 M_DLD(s1, REG_SP, j * 8);
3729 M_FLD(s1, REG_SP, j * 8);
3735 /* copy or spill arguments to new locations */
3737 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3738 t = md->params[i].type;
3740 if (IS_INT_LNG_TYPE(t)) {
3741 if (!md->params[i].inmemory) {
3742 s1 = md->params[i].regoff;
3743 s2 = nmd->params[j].regoff;
3745 if (!nmd->params[j].inmemory) {
3746 #if SIZEOF_VOID_P == 8
3749 if (IS_2_WORD_TYPE(t))
3756 #if SIZEOF_VOID_P == 8
3757 M_LST(s1, REG_SP, s2);
3759 if (IS_2_WORD_TYPE(t))
3760 M_LST(s1, REG_SP, s2);
3762 M_IST(s1, REG_SP, s2);
3767 s1 = md->params[i].regoff + cd->stackframesize * 8;
3768 s2 = nmd->params[j].regoff;
3770 #if SIZEOF_VOID_P == 8
3771 M_LLD(REG_ITMP1, REG_SP, s1);
3772 M_LST(REG_ITMP1, REG_SP, s2);
3774 if (IS_2_WORD_TYPE(t)) {
3775 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3776 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3779 M_ILD(REG_ITMP1, REG_SP, s1);
3780 M_IST(REG_ITMP1, REG_SP, s2);
3786 if (!md->params[i].inmemory) {
3787 s1 = md->params[i].regoff;
3788 s2 = nmd->params[j].regoff;
3790 if (!nmd->params[j].inmemory) {
3791 #if SIZEOF_VOID_P == 8
3792 if (IS_2_WORD_TYPE(t))
3797 /* On MIPS32 float arguments for native functions
3798 can never be in float argument registers, since
3799 the first argument is _always_ an integer
3800 argument (JNIEnv) */
3802 if (IS_2_WORD_TYPE(t)) {
3803 /* double high/low order is endian
3804 independent: even numbered holds low
3805 32-bits, odd numbered high 32-bits */
3807 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3808 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3815 #if SIZEOF_VOID_P == 8
3816 if (IS_2_WORD_TYPE(t))
3817 M_DST(s1, REG_SP, s2);
3819 M_FST(s1, REG_SP, s2);
3821 /* s1 may have been originally in 2 int registers,
3822 but was moved out by the native function
3823 argument(s), just get low register */
3825 if (IS_2_WORD_TYPE(t))
3826 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3828 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3833 s1 = md->params[i].regoff + cd->stackframesize * 8;
3834 s2 = nmd->params[j].regoff;
3836 #if SIZEOF_VOID_P == 8
3837 if (IS_2_WORD_TYPE(t)) {
3838 M_DLD(REG_FTMP1, REG_SP, s1);
3839 M_DST(REG_FTMP1, REG_SP, s2);
3842 M_FLD(REG_FTMP1, REG_SP, s1);
3843 M_FST(REG_FTMP1, REG_SP, s2);
3846 if (IS_2_WORD_TYPE(t)) {
3847 M_DLD(REG_FTMP1, REG_SP, s1);
3848 M_DST(REG_FTMP1, REG_SP, s2);
3851 M_FLD(REG_FTMP1, REG_SP, s1);
3852 M_FST(REG_FTMP1, REG_SP, s2);
3859 /* Handle native Java methods. */
3861 if (m->flags & ACC_NATIVE) {
3862 /* put class into second argument register */
3864 if (m->flags & ACC_STATIC)
3865 M_MOV(REG_ITMP3, REG_A1);
3867 /* put env into first argument register */
3869 disp = dseg_add_address(cd, VM_get_jnienv());
3870 M_ALD(REG_A0, REG_PV, disp);
3873 /* Call the native function. */
3875 disp = dseg_add_functionptr(cd, f);
3876 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3877 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3878 M_NOP; /* delay slot */
3880 /* save return value */
3882 switch (md->returntype.type) {
3883 #if SIZEOF_VOID_P == 8
3887 M_LST(REG_RESULT, REG_SP, 0 * 8);
3891 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3896 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3899 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3903 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3910 #if !defined(NDEBUG)
3911 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3912 emit_verbosecall_exit(jd);
3915 /* remove native stackframe info */
3917 M_MOV(REG_SP, REG_A0);
3918 M_MOV(REG_PV, REG_A1);
3919 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3920 M_ALD(REG_ITMP3, REG_PV, disp);
3921 M_JSR(REG_RA, REG_ITMP3);
3922 M_NOP; /* XXX fill me! */
3923 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3925 /* restore return value */
3927 switch (md->returntype.type) {
3928 #if SIZEOF_VOID_P == 8
3932 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3936 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3941 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3944 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3948 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3955 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3957 /* check for exception */
3959 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3960 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3962 M_RET(REG_RA); /* return to caller */
3963 M_NOP; /* DELAY SLOT */
3965 /* handle exception */
3967 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3968 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3969 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3970 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3972 /* Generate patcher traps. */
3974 emit_patcher_traps(jd);
3979 * These are local overrides for various environment variables in Emacs.
3980 * Please do not remove this and leave it at the end of the file, where
3981 * Emacs will automagically detect them.
3982 * ---------------------------------------------------------------------
3985 * indent-tabs-mode: t
3989 * vim:noexpandtab:sw=4:ts=4: