1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "vm/jit/mips/arch.h"
38 #include "vm/jit/mips/codegen.h"
40 #include "mm/memory.h"
42 #include "native/localref.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
51 #include "vm/jit/abi.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.h"
54 #include "vm/jit/dseg.h"
55 #include "vm/jit/emit-common.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/md.h"
58 #include "vm/jit/patcher-common.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
62 #if defined(ENABLE_LSRA)
63 # include "vm/jit/allocator/lsra.h"
66 #include "vmcore/class.h"
67 #include "vmcore/options.h"
70 /* codegen_emit ****************************************************************
72 Generates machine code.
74 *******************************************************************************/
76 bool codegen_emit(jitdata *jd)
82 s4 len, s1, s2, s3, d, disp;
88 constant_classref *cr;
90 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
91 unresolved_method *um;
92 builtintable_entry *bte;
99 /* get required compiler data */
106 /* prevent compiler warnings */
121 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
123 /* space to save used callee saved registers */
125 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128 cd->stackframesize = rd->memuse + savedregs_num;
130 #if defined(ENABLE_THREADS)
131 /* space to save argument of monitor_enter */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
134 # if SIZEOF_VOID_P == 8
135 cd->stackframesize++;
138 cd->stackframesize += 2;
143 /* keep stack 16-byte aligned */
145 if (cd->stackframesize & 1)
146 cd->stackframesize++;
148 /* create method header */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
166 /* REMOVEME: We still need it for exception handling in assembler. */
168 if (code_is_leafmethod(code))
169 (void) dseg_add_unique_s4(cd, 1);
171 (void) dseg_add_unique_s4(cd, 0);
173 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
174 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
175 dseg_addlinenumbertablesize(cd);
176 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
178 /* create exception table */
180 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
181 dseg_add_target(cd, ex->start);
182 dseg_add_target(cd, ex->end);
183 dseg_add_target(cd, ex->handler);
184 (void) dseg_add_unique_address(cd, ex->catchtype.any);
187 /* create stack frame (if necessary) */
189 if (cd->stackframesize)
190 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
192 /* save return address and used callee saved registers */
194 p = cd->stackframesize;
195 if (!code_is_leafmethod(code)) {
196 p--; M_AST(REG_RA, REG_SP, p * 8);
198 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
199 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
201 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
202 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
205 /* take arguments out of register or stack frame */
209 for (p = 0, l = 0; p < md->paramcount; p++) {
210 t = md->paramtypes[p].type;
212 varindex = jd->local_map[l * 5 + t];
215 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
218 if (varindex == UNUSED)
222 s1 = md->params[p].regoff;
224 if (IS_INT_LNG_TYPE(t)) { /* integer args */
225 if (!md->params[p].inmemory) { /* register arguments */
226 #if SIZEOF_VOID_P == 8
227 if (!(var->flags & INMEMORY))
228 M_INTMOVE(s1, var->vv.regoff);
230 M_LST(s1, REG_SP, var->vv.regoff);
232 if (!(var->flags & INMEMORY)) {
233 if (IS_2_WORD_TYPE(t))
234 M_LNGMOVE(s1, var->vv.regoff);
236 M_INTMOVE(s1, var->vv.regoff);
239 if (IS_2_WORD_TYPE(t))
240 M_LST(s1, REG_SP, var->vv.regoff);
242 M_IST(s1, REG_SP, var->vv.regoff);
246 else { /* stack arguments */
247 if (!(var->flags & INMEMORY)) {
248 #if SIZEOF_VOID_P == 8
249 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
251 if (IS_2_WORD_TYPE(t))
252 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
254 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
258 var->vv.regoff = cd->stackframesize * 8 + s1;
261 else { /* floating args */
262 if (!md->params[p].inmemory) {
263 if (!(var->flags & INMEMORY)) {
264 if (IS_2_WORD_TYPE(t))
265 M_DBLMOVE(s1, var->vv.regoff);
267 M_FLTMOVE(s1, var->vv.regoff);
270 if (IS_2_WORD_TYPE(t))
271 M_DST(s1, REG_SP, var->vv.regoff);
273 M_FST(s1, REG_SP, var->vv.regoff);
277 if (!(var->flags & INMEMORY)) {
278 if (IS_2_WORD_TYPE(t))
279 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
281 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
284 var->vv.regoff = cd->stackframesize * 8 + s1;
289 /* call monitorenter function */
291 #if defined(ENABLE_THREADS)
292 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
293 /* stack offset for monitor argument */
297 # if !defined(NDEBUG)
298 if (opt_verbosecall) {
299 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
301 for (p = 0; p < INT_ARG_CNT; p++)
302 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
304 for (p = 0; p < FLT_ARG_CNT; p++)
305 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
307 s1 += INT_ARG_CNT + FLT_ARG_CNT;
311 /* get correct lock object */
313 if (m->flags & ACC_STATIC) {
314 disp = dseg_add_address(cd, &m->class->object.header);
315 M_ALD(REG_A0, REG_PV, disp);
316 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
317 M_ALD(REG_ITMP3, REG_PV, disp);
320 /* emit_nullpointer_check(cd, iptr, REG_A0); */
322 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
323 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
324 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
327 M_JSR(REG_RA, REG_ITMP3);
328 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
330 # if !defined(NDEBUG)
331 if (opt_verbosecall) {
332 for (p = 0; p < INT_ARG_CNT; p++)
333 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
335 for (p = 0; p < FLT_ARG_CNT; p++)
336 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
339 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
347 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
348 emit_verbosecall_enter(jd);
351 /* end of header generation */
353 /* create replacement points */
355 REPLACEMENT_POINTS_INIT(cd, jd);
357 /* walk through all basic blocks */
359 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
361 /* handle replacement points */
363 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
365 /* store relative start of block */
367 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
369 if (bptr->flags >= BBREACHED) {
370 /* branch resolving */
372 codegen_resolve_branchrefs(cd, bptr);
374 /* copy interface registers to their destination */
378 #if defined(ENABLE_LSRA)
382 src = bptr->invars[len];
383 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
384 /* d = reg_of_var(m, src, REG_ITMP1); */
385 if (!(src->flags & INMEMORY))
389 M_INTMOVE(REG_ITMP1, d);
390 emit_store(jd, NULL, src, d);
397 var = VAR(bptr->invars[len]);
398 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
399 d = codegen_reg_of_var(0, var, REG_ITMP1);
400 M_INTMOVE(REG_ITMP1, d);
401 emit_store(jd, NULL, var, d);
404 assert((var->flags & INOUT));
407 #if defined(ENABLE_LSRA)
410 /* walk through all instructions */
413 /* currentline = 0; */
415 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
416 if (iptr->line != currentline) {
417 dseg_addlinenumber(cd, iptr->line);
418 currentline = iptr->line;
421 MCODECHECK(64); /* an instruction usually needs < 64 words */
425 case ICMD_NOP: /* ... ==> ... */
426 case ICMD_POP: /* ..., value ==> ... */
427 case ICMD_POP2: /* ..., value, value ==> ... */
430 case ICMD_INLINE_START:
432 REPLACEMENT_POINT_INLINE_START(cd, iptr);
435 case ICMD_INLINE_BODY:
437 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
438 dseg_addlinenumber_inline_start(cd, iptr);
439 dseg_addlinenumber(cd, iptr->line);
442 case ICMD_INLINE_END:
444 dseg_addlinenumber_inline_end(cd, iptr);
445 dseg_addlinenumber(cd, iptr->line);
448 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
451 emit_nullpointer_check(cd, iptr, s1);
454 /* constant operations ************************************************/
456 case ICMD_ICONST: /* ... ==> ..., constant */
458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
459 ICONST(d, iptr->sx.val.i);
460 emit_store_dst(jd, iptr, d);
463 case ICMD_LCONST: /* ... ==> ..., constant */
465 #if SIZEOF_VOID_P == 8
466 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
470 LCONST(d, iptr->sx.val.l);
471 emit_store_dst(jd, iptr, d);
474 case ICMD_FCONST: /* ... ==> ..., constant */
476 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
477 disp = dseg_add_float(cd, iptr->sx.val.f);
478 M_FLD(d, REG_PV, disp);
479 emit_store_dst(jd, iptr, d);
482 case ICMD_DCONST: /* ... ==> ..., constant */
484 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
485 disp = dseg_add_double(cd, iptr->sx.val.d);
486 M_DLD(d, REG_PV, disp);
487 emit_store_dst(jd, iptr, d);
490 case ICMD_ACONST: /* ... ==> ..., constant */
492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
494 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
495 cr = iptr->sx.val.c.ref;
496 disp = dseg_add_unique_address(cd, cr);
498 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
501 M_ALD(d, REG_PV, disp);
504 if (iptr->sx.val.anyptr == NULL)
505 M_INTMOVE(REG_ZERO, d);
507 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
508 M_ALD(d, REG_PV, disp);
511 emit_store_dst(jd, iptr, d);
515 /* load/store/copy/move operations ************************************/
517 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
522 case ICMD_ISTORE: /* ..., value ==> ... */
533 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
538 /* integer operations *************************************************/
540 case ICMD_INEG: /* ..., value ==> ..., - value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
544 M_ISUB(REG_ZERO, s1, d);
545 emit_store_dst(jd, iptr, d);
548 case ICMD_LNEG: /* ..., value ==> ..., - value */
550 #if SIZEOF_VOID_P == 8
551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
553 M_LSUB(REG_ZERO, s1, d);
555 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
557 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
558 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
559 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
560 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
562 emit_store_dst(jd, iptr, d);
565 case ICMD_I2L: /* ..., value ==> ..., value */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 #if SIZEOF_VOID_P == 8
569 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
573 M_INTMOVE(s1, GET_LOW_REG(d));
574 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
576 emit_store_dst(jd, iptr, d);
579 case ICMD_L2I: /* ..., value ==> ..., value */
581 #if SIZEOF_VOID_P == 8
582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
584 M_ISLL_IMM(s1, 0, d);
586 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
588 M_INTMOVE(GET_LOW_REG(s1), d);
590 emit_store_dst(jd, iptr, d);
593 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
597 #if SIZEOF_VOID_P == 8
598 M_LSLL_IMM(s1, 56, d);
599 M_LSRA_IMM( d, 56, d);
601 M_ISLL_IMM(s1, 24, d);
602 M_ISRA_IMM( d, 24, d);
604 emit_store_dst(jd, iptr, d);
607 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 M_AND_IMM(s1, 0xffff, d);
612 emit_store_dst(jd, iptr, d);
615 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
619 #if SIZEOF_VOID_P == 8
620 M_LSLL_IMM(s1, 48, d);
621 M_LSRA_IMM( d, 48, d);
623 M_ISLL_IMM(s1, 16, d);
624 M_ISRA_IMM( d, 16, d);
626 emit_store_dst(jd, iptr, d);
630 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
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);
636 emit_store_dst(jd, iptr, d);
640 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
641 /* sx.val.i = constant */
643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
645 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
646 M_IADD_IMM(s1, iptr->sx.val.i, d);
648 ICONST(REG_ITMP2, iptr->sx.val.i);
649 M_IADD(s1, REG_ITMP2, d);
651 emit_store_dst(jd, iptr, d);
654 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
656 #if SIZEOF_VOID_P == 8
657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
662 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
663 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
665 M_IADD(s1, s2, GET_HIGH_REG(d));
666 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
667 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
668 if (s1 == GET_LOW_REG(d)) {
669 M_MOV(s1, REG_ITMP3);
672 M_IADD(s1, s2, GET_LOW_REG(d));
673 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
674 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
676 emit_store_dst(jd, iptr, d);
679 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
680 /* sx.val.l = constant */
682 #if SIZEOF_VOID_P == 8
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
686 M_LADD_IMM(s1, iptr->sx.val.l, d);
688 LCONST(REG_ITMP2, iptr->sx.val.l);
689 M_LADD(s1, REG_ITMP2, d);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
693 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
694 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
695 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
696 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
697 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
699 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
700 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
701 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
702 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
703 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
704 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
705 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
708 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
709 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
710 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
711 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
712 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
713 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
714 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
715 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
718 emit_store_dst(jd, iptr, d);
721 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
727 emit_store_dst(jd, iptr, d);
730 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
731 /* sx.val.i = constant */
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
735 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
736 M_IADD_IMM(s1, -iptr->sx.val.i, d);
738 ICONST(REG_ITMP2, iptr->sx.val.i);
739 M_ISUB(s1, REG_ITMP2, d);
741 emit_store_dst(jd, iptr, d);
744 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
746 #if SIZEOF_VOID_P == 8
747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
748 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
749 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
753 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
755 M_ISUB(s1, s2, GET_HIGH_REG(d));
756 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
757 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
758 M_CMPULT(s1, s2, REG_ITMP3);
759 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
760 /* if s1 is equal to REG_ITMP3 we have to reload it, since
761 the CMPULT instruction destroyed it */
763 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
764 M_ISUB(s1, s2, GET_LOW_REG(d));
767 emit_store_dst(jd, iptr, d);
770 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
771 /* sx.val.l = constant */
773 #if SIZEOF_VOID_P == 8
774 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
776 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
777 M_LADD_IMM(s1, -iptr->sx.val.l, d);
779 LCONST(REG_ITMP2, iptr->sx.val.l);
780 M_LSUB(s1, REG_ITMP2, d);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
784 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
785 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
786 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
787 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
788 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
789 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
790 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
792 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
793 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
794 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
795 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
796 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
799 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
800 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
801 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
802 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
803 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
804 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
805 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
806 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
809 emit_store_dst(jd, iptr, d);
812 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
815 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
825 /* sx.val.i = constant */
827 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829 ICONST(REG_ITMP2, iptr->sx.val.i);
830 M_IMUL(s1, REG_ITMP2);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
839 #if SIZEOF_VOID_P == 8
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
848 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
849 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
855 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
857 M_MFHI(GET_HIGH_REG(d));
858 M_MFLO(GET_LOW_REG(d));
861 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
863 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
864 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
867 /* XXX do we need nops here? */
869 emit_store_dst(jd, iptr, d);
872 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
873 /* sx.val.l = constant */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
877 LCONST(REG_ITMP2, iptr->sx.val.l);
878 M_LMUL(s1, REG_ITMP2);
882 emit_store_dst(jd, iptr, d);
885 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
888 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
889 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
890 emit_arithmetic_check(cd, iptr, s2);
895 emit_store_dst(jd, iptr, d);
898 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
901 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
902 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
903 emit_arithmetic_check(cd, iptr, s2);
908 emit_store_dst(jd, iptr, d);
911 #if SIZEOF_VOID_P == 8
913 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
915 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
916 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
917 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
918 emit_arithmetic_check(cd, iptr, s2);
923 emit_store_dst(jd, iptr, d);
926 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
929 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
930 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
931 emit_arithmetic_check(cd, iptr, s2);
936 emit_store_dst(jd, iptr, d);
939 #else /* SIZEOF_VOID_P == 8 */
941 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
942 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
944 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
945 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
947 /* XXX TODO: only do this if arithmetic check is really done! */
948 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
949 emit_arithmetic_check(cd, iptr, REG_ITMP3);
951 M_LNGMOVE(s1, REG_A0_A1_PACKED);
952 M_LNGMOVE(s2, REG_A2_A3_PACKED);
954 bte = iptr->sx.s23.s3.bte;
955 disp = dseg_add_functionptr(cd, bte->fp);
956 M_ALD(REG_ITMP3, REG_PV, disp);
957 M_JSR(REG_RA, REG_ITMP3);
960 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
961 M_LNGMOVE(REG_RESULT_PACKED, d);
962 emit_store_dst(jd, iptr, d);
965 #endif /* SIZEOF_VOID_P == 8 */
967 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
968 /* val.i = constant */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
972 #if SIZEOF_VOID_P == 8
973 M_LSRA_IMM(s1, 63, REG_ITMP2);
974 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
975 M_LADD(s1, REG_ITMP2, REG_ITMP2);
976 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
978 M_ISRA_IMM(s1, 31, REG_ITMP2);
979 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
980 M_IADD(s1, REG_ITMP2, REG_ITMP2);
981 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
983 emit_store_dst(jd, iptr, d);
986 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
987 /* val.i = constant */
989 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
990 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
992 M_MOV(s1, REG_ITMP1);
995 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
996 M_AND_IMM(s1, iptr->sx.val.i, d);
999 M_ISUB(REG_ZERO, s1, d);
1000 M_AND_IMM(d, iptr->sx.val.i, d);
1003 ICONST(REG_ITMP2, iptr->sx.val.i);
1004 M_AND(s1, REG_ITMP2, d);
1007 M_ISUB(REG_ZERO, s1, d);
1008 M_AND(d, REG_ITMP2, d);
1010 M_ISUB(REG_ZERO, d, d);
1011 emit_store_dst(jd, iptr, d);
1014 #if SIZEOF_VOID_P == 8
1016 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1017 /* val.i = constant */
1019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021 M_LSRA_IMM(s1, 63, REG_ITMP2);
1022 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1023 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1024 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1025 emit_store_dst(jd, iptr, d);
1028 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1029 /* val.l = constant */
1031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1032 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1034 M_MOV(s1, REG_ITMP1);
1037 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1038 M_AND_IMM(s1, iptr->sx.val.l, d);
1041 M_LSUB(REG_ZERO, s1, d);
1042 M_AND_IMM(d, iptr->sx.val.l, d);
1045 LCONST(REG_ITMP2, iptr->sx.val.l);
1046 M_AND(s1, REG_ITMP2, d);
1049 M_LSUB(REG_ZERO, s1, d);
1050 M_AND(d, REG_ITMP2, d);
1052 M_LSUB(REG_ZERO, d, d);
1053 emit_store_dst(jd, iptr, d);
1056 #endif /* SIZEOF_VOID_P == 8 */
1058 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1064 emit_store_dst(jd, iptr, d);
1067 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1068 /* sx.val.i = constant */
1070 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1071 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1073 emit_store_dst(jd, iptr, d);
1076 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1080 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1082 emit_store_dst(jd, iptr, d);
1085 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1086 /* sx.val.i = constant */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1090 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1091 emit_store_dst(jd, iptr, d);
1094 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1096 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1097 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1098 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1100 emit_store_dst(jd, iptr, d);
1103 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1104 /* sx.val.i = constant */
1106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1107 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1108 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1109 emit_store_dst(jd, iptr, d);
1112 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1114 #if SIZEOF_VOID_P == 8
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1120 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1121 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1122 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1124 M_ISLL(s2, 26, REG_ITMP1);
1125 M_BGEZ(REG_ITMP1, 3);
1128 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1130 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1133 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1135 M_BEQZ(REG_ITMP1, 4);
1136 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1138 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1139 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1140 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1143 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1146 emit_store_dst(jd, iptr, d);
1149 #if SIZEOF_VOID_P == 8
1151 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1152 /* sx.val.i = constant */
1154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1156 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1157 emit_store_dst(jd, iptr, d);
1160 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1164 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1166 emit_store_dst(jd, iptr, d);
1169 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1170 /* sx.val.i = constant */
1172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1173 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1174 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1175 emit_store_dst(jd, iptr, d);
1178 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1181 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1182 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1184 emit_store_dst(jd, iptr, d);
1187 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1188 /* sx.val.i = constant */
1190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1191 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1192 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1193 emit_store_dst(jd, iptr, d);
1196 #endif /* SIZEOF_VOID_P == 8 */
1198 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1202 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1204 emit_store_dst(jd, iptr, d);
1207 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1208 /* sx.val.i = constant */
1210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1211 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1212 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1213 M_AND_IMM(s1, iptr->sx.val.i, d);
1215 ICONST(REG_ITMP2, iptr->sx.val.i);
1216 M_AND(s1, REG_ITMP2, d);
1218 emit_store_dst(jd, iptr, d);
1221 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1223 #if SIZEOF_VOID_P == 8
1224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1225 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1229 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1230 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1231 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1232 M_AND(s1, s2, GET_LOW_REG(d));
1233 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1234 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1235 M_AND(s1, s2, GET_HIGH_REG(d));
1237 emit_store_dst(jd, iptr, d);
1240 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1241 /* sx.val.l = constant */
1243 #if SIZEOF_VOID_P == 8
1244 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1246 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1247 M_AND_IMM(s1, iptr->sx.val.l, d);
1249 LCONST(REG_ITMP2, iptr->sx.val.l);
1250 M_AND(s1, REG_ITMP2, d);
1253 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1254 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1255 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1256 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1257 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1260 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1261 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1262 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1263 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1264 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1267 emit_store_dst(jd, iptr, d);
1270 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1272 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1273 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1274 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1276 emit_store_dst(jd, iptr, d);
1279 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1280 /* sx.val.i = constant */
1282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1283 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1284 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1285 M_OR_IMM(s1, iptr->sx.val.i, d);
1287 ICONST(REG_ITMP2, iptr->sx.val.i);
1288 M_OR(s1, REG_ITMP2, d);
1290 emit_store_dst(jd, iptr, d);
1293 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1295 #if SIZEOF_VOID_P == 8
1296 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1297 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1298 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1301 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1302 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1304 M_OR(s1, s2, GET_LOW_REG(d));
1305 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1306 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1307 M_OR(s1, s2, GET_HIGH_REG(d));
1309 emit_store_dst(jd, iptr, d);
1312 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1313 /* sx.val.l = constant */
1315 #if SIZEOF_VOID_P == 8
1316 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1317 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1318 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1319 M_OR_IMM(s1, iptr->sx.val.l, d);
1321 LCONST(REG_ITMP2, iptr->sx.val.l);
1322 M_OR(s1, REG_ITMP2, d);
1325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1326 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1327 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1328 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1329 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1332 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1333 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1334 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1335 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1336 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1352 /* sx.val.i = constant */
1354 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1356 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1357 M_XOR_IMM(s1, iptr->sx.val.i, d);
1359 ICONST(REG_ITMP2, iptr->sx.val.i);
1360 M_XOR(s1, REG_ITMP2, d);
1362 emit_store_dst(jd, iptr, d);
1365 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1367 #if SIZEOF_VOID_P == 8
1368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1369 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1373 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1374 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1376 M_XOR(s1, s2, GET_LOW_REG(d));
1377 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1378 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1379 M_XOR(s1, s2, GET_HIGH_REG(d));
1381 emit_store_dst(jd, iptr, d);
1384 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1385 /* sx.val.l = constant */
1387 #if SIZEOF_VOID_P == 8
1388 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1390 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1391 M_XOR_IMM(s1, iptr->sx.val.l, d);
1393 LCONST(REG_ITMP2, iptr->sx.val.l);
1394 M_XOR(s1, REG_ITMP2, d);
1397 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1398 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1399 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1400 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1401 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1404 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1405 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1406 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1407 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1408 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1411 emit_store_dst(jd, iptr, d);
1415 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1417 #if SIZEOF_VOID_P == 8
1418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1419 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1421 M_CMPLT(s1, s2, REG_ITMP3);
1422 M_CMPLT(s2, s1, REG_ITMP1);
1423 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1425 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1426 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1427 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1428 M_CMPLT(s1, s2, REG_ITMP3);
1429 M_CMPLT(s2, s1, REG_ITMP1);
1430 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1433 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1434 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1435 M_CMPULT(s1, s2, REG_ITMP3);
1436 M_CMPULT(s2, s1, REG_ITMP1);
1437 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1439 emit_store_dst(jd, iptr, d);
1443 /* floating operations ************************************************/
1445 case ICMD_FNEG: /* ..., value ==> ..., - value */
1447 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1448 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1450 emit_store_dst(jd, iptr, d);
1453 case ICMD_DNEG: /* ..., value ==> ..., - value */
1455 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1456 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1458 emit_store_dst(jd, iptr, d);
1461 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1463 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1464 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1465 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1467 emit_store_dst(jd, iptr, d);
1470 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1472 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1473 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1474 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1476 emit_store_dst(jd, iptr, d);
1479 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1481 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1482 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1483 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1485 emit_store_dst(jd, iptr, d);
1488 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1490 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1491 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1492 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1494 emit_store_dst(jd, iptr, d);
1497 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1499 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1500 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1501 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1503 emit_store_dst(jd, iptr, d);
1506 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1508 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1509 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1510 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1512 emit_store_dst(jd, iptr, d);
1515 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1517 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1519 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1521 emit_store_dst(jd, iptr, d);
1524 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1526 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1527 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1528 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1530 emit_store_dst(jd, iptr, d);
1534 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1536 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1537 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1538 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1539 M_FDIV(s1,s2, REG_FTMP3);
1540 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1541 M_CVTLF(REG_FTMP3, REG_FTMP3);
1542 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1543 M_FSUB(s1, REG_FTMP3, d);
1544 emit_store_dst(jd, iptr, d);
1547 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1549 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1550 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1551 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1552 M_DDIV(s1,s2, REG_FTMP3);
1553 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1554 M_CVTLD(REG_FTMP3, REG_FTMP3);
1555 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1556 M_DSUB(s1, REG_FTMP3, d);
1557 emit_store_dst(jd, iptr, d);
1561 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1573 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1576 emit_store_dst(jd, iptr, d);
1580 /* XXX these do not work correctly */
1582 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1584 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1586 M_TRUNCFI(s1, REG_FTMP1);
1587 M_MOVDI(REG_FTMP1, d);
1589 emit_store_dst(jd, iptr, d);
1592 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1594 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1596 M_TRUNCDI(s1, REG_FTMP1);
1597 M_MOVDI(REG_FTMP1, d);
1599 emit_store_dst(jd, iptr, d);
1602 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1604 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1606 M_TRUNCFL(s1, REG_FTMP1);
1607 M_MOVDL(REG_FTMP1, d);
1609 emit_store_dst(jd, iptr, d);
1612 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1614 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1616 M_TRUNCDL(s1, REG_FTMP1);
1617 M_MOVDL(REG_FTMP1, d);
1619 emit_store_dst(jd, iptr, d);
1623 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1625 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1626 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1628 emit_store_dst(jd, iptr, d);
1631 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1633 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1634 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1636 emit_store_dst(jd, iptr, d);
1639 #if SUPPORT_FLOAT_CMP
1640 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1642 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1643 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1647 M_AADD_IMM(REG_ZERO, 1, d);
1651 M_ASUB_IMM(REG_ZERO, 1, d);
1652 M_CMOVT(REG_ZERO, d);
1653 emit_store_dst(jd, iptr, d);
1656 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1658 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1659 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1663 M_ASUB_IMM(REG_ZERO, 1, d);
1667 M_AADD_IMM(REG_ZERO, 1, d);
1668 M_CMOVT(REG_ZERO, d);
1669 emit_store_dst(jd, iptr, d);
1673 #if SUPPORT_DOUBLE_CMP
1674 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1676 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1677 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1681 M_AADD_IMM(REG_ZERO, 1, d);
1685 M_ASUB_IMM(REG_ZERO, 1, d);
1686 M_CMOVT(REG_ZERO, d);
1687 emit_store_dst(jd, iptr, d);
1690 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1692 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1693 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1694 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1697 M_ASUB_IMM(REG_ZERO, 1, d);
1701 M_AADD_IMM(REG_ZERO, 1, d);
1702 M_CMOVT(REG_ZERO, d);
1703 emit_store_dst(jd, iptr, d);
1708 /* memory operations **************************************************/
1710 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1714 /* implicit null-pointer check */
1715 M_ILD(d, s1, OFFSET(java_array_t, size));
1716 emit_store_dst(jd, iptr, d);
1719 case ICMD_BALOAD: /* ..., 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 /* implicit null-pointer check */
1727 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1728 emit_store_dst(jd, iptr, d);
1731 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1736 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1737 M_AADD(s2, s1, REG_ITMP3);
1738 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1739 /* implicit null-pointer check */
1740 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1741 emit_store_dst(jd, iptr, d);
1744 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1747 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1748 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1749 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1750 M_AADD(s2, s1, REG_ITMP3);
1751 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1752 /* implicit null-pointer check */
1753 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1754 emit_store_dst(jd, iptr, d);
1757 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1760 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1761 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1762 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1763 M_ASLL_IMM(s2, 2, REG_ITMP3);
1764 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1765 /* implicit null-pointer check */
1766 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1767 emit_store_dst(jd, iptr, d);
1770 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1774 #if SIZEOF_VOID_P == 8
1775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1777 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1779 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1780 M_ASLL_IMM(s2, 3, REG_ITMP3);
1781 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1782 /* implicit null-pointer check */
1783 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1784 emit_store_dst(jd, iptr, d);
1787 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1791 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1792 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1793 M_ASLL_IMM(s2, 2, REG_ITMP3);
1794 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1795 /* implicit null-pointer check */
1796 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1797 emit_store_dst(jd, iptr, d);
1800 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1803 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1804 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1805 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1806 M_ASLL_IMM(s2, 3, REG_ITMP3);
1807 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1808 /* implicit null-pointer check */
1809 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1810 emit_store_dst(jd, iptr, d);
1813 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1816 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1818 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1819 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1820 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1821 /* implicit null-pointer check */
1822 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1823 emit_store_dst(jd, iptr, d);
1827 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1830 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1831 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1832 M_AADD(s2, s1, REG_ITMP1);
1833 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1834 /* implicit null-pointer check */
1835 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1838 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1839 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1843 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1844 M_AADD(s2, s1, REG_ITMP1);
1845 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1846 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1847 /* implicit null-pointer check */
1848 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1851 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1854 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1855 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1856 M_ASLL_IMM(s2, 2, REG_ITMP2);
1857 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1858 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1859 /* implicit null-pointer check */
1860 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1863 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1867 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1868 M_ASLL_IMM(s2, 3, REG_ITMP2);
1869 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1870 #if SIZEOF_VOID_P == 8
1871 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1873 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1875 /* implicit null-pointer check */
1876 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1879 case ICMD_FASTORE: /* ..., 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 M_ASLL_IMM(s2, 2, REG_ITMP2);
1885 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1886 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1887 /* implicit null-pointer check */
1888 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1891 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1894 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1895 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1896 M_ASLL_IMM(s2, 3, REG_ITMP2);
1897 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1898 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1899 /* implicit null-pointer check */
1900 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1904 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
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 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1911 M_INTMOVE(s1, REG_A0);
1912 M_INTMOVE(s3, REG_A1);
1913 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1914 M_ALD(REG_ITMP3, REG_PV, disp);
1915 M_JSR(REG_RA, REG_ITMP3);
1917 emit_arraystore_check(cd, iptr);
1919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1920 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1921 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1922 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1923 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1924 /* implicit null-pointer check */
1925 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1929 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1933 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1934 M_AADD(s2, s1, REG_ITMP1);
1935 /* implicit null-pointer check */
1936 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1939 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1940 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1942 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1943 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1944 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1945 M_AADD(s2, s1, REG_ITMP1);
1946 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1947 /* implicit null-pointer check */
1948 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1951 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1954 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1955 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1956 M_ASLL_IMM(s2, 2, REG_ITMP2);
1957 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1958 /* implicit null-pointer check */
1959 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1962 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1965 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1966 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1967 M_ASLL_IMM(s2, 3, REG_ITMP2);
1968 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1969 /* implicit null-pointer check */
1970 #if SIZEOF_VOID_P == 8
1971 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1973 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1977 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1979 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1980 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1981 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1982 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1983 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1984 /* implicit null-pointer check */
1985 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1989 case ICMD_GETSTATIC: /* ... ==> ..., value */
1991 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1992 uf = iptr->sx.s23.s3.uf;
1993 fieldtype = uf->fieldref->parseddesc.fd->type;
1994 disp = dseg_add_unique_address(cd, uf);
1996 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1999 fi = iptr->sx.s23.s3.fmiref->p.field;
2000 fieldtype = fi->type;
2001 disp = dseg_add_address(cd, fi->value);
2003 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2004 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2008 M_ALD(REG_ITMP1, REG_PV, disp);
2010 switch (fieldtype) {
2012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2013 M_ILD_INTERN(d, REG_ITMP1, 0);
2016 #if SIZEOF_VOID_P == 8
2017 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2019 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2021 M_LLD_INTERN(d, REG_ITMP1, 0);
2024 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2025 M_ALD_INTERN(d, REG_ITMP1, 0);
2028 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2029 M_FLD_INTERN(d, REG_ITMP1, 0);
2032 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2033 M_DLD_INTERN(d, REG_ITMP1, 0);
2036 emit_store_dst(jd, iptr, d);
2039 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2041 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2042 uf = iptr->sx.s23.s3.uf;
2043 fieldtype = uf->fieldref->parseddesc.fd->type;
2044 disp = dseg_add_unique_address(cd, uf);
2046 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2049 fi = iptr->sx.s23.s3.fmiref->p.field;
2050 fieldtype = fi->type;
2051 disp = dseg_add_address(cd, fi->value);
2053 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2054 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2058 M_ALD(REG_ITMP1, REG_PV, disp);
2060 switch (fieldtype) {
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2063 M_IST_INTERN(s1, REG_ITMP1, 0);
2066 #if SIZEOF_VOID_P == 8
2067 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2069 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2071 M_LST_INTERN(s1, REG_ITMP1, 0);
2074 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2075 M_AST_INTERN(s1, REG_ITMP1, 0);
2078 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2079 M_FST_INTERN(s1, REG_ITMP1, 0);
2082 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2083 M_DST_INTERN(s1, REG_ITMP1, 0);
2088 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2090 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2091 uf = iptr->sx.s23.s3.uf;
2092 fieldtype = uf->fieldref->parseddesc.fd->type;
2093 disp = dseg_add_unique_address(cd, uf);
2095 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2098 fi = iptr->sx.s23.s3.fmiref->p.field;
2099 fieldtype = fi->type;
2100 disp = dseg_add_address(cd, fi->value);
2102 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2103 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2107 M_ALD(REG_ITMP1, REG_PV, disp);
2109 switch (fieldtype) {
2111 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2114 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2117 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2120 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2123 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2129 case ICMD_GETFIELD: /* ... ==> ..., value */
2131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132 emit_nullpointer_check(cd, iptr, s1);
2134 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2135 uf = iptr->sx.s23.s3.uf;
2136 fieldtype = uf->fieldref->parseddesc.fd->type;
2139 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2142 fi = iptr->sx.s23.s3.fmiref->p.field;
2143 fieldtype = fi->type;
2147 switch (fieldtype) {
2149 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2153 #if SIZEOF_VOID_P == 8
2154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2157 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2158 M_LLD_GETFIELD(d, s1, disp);
2162 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2166 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2170 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2174 emit_store_dst(jd, iptr, d);
2177 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2180 emit_nullpointer_check(cd, iptr, s1);
2182 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2183 uf = iptr->sx.s23.s3.uf;
2184 fieldtype = uf->fieldref->parseddesc.fd->type;
2188 fi = iptr->sx.s23.s3.fmiref->p.field;
2189 fieldtype = fi->type;
2193 #if SIZEOF_VOID_P == 8
2194 if (IS_INT_LNG_TYPE(fieldtype))
2195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2197 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2199 if (IS_INT_LNG_TYPE(fieldtype)) {
2200 if (IS_2_WORD_TYPE(fieldtype))
2201 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2203 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2206 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2209 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2210 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2212 switch (fieldtype) {
2214 M_IST(s2, s1, disp);
2217 M_LST(s2, s1, disp);
2220 M_AST(s2, s1, disp);
2223 M_FST(s2, s1, disp);
2226 M_DST(s2, s1, disp);
2231 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2234 emit_nullpointer_check(cd, iptr, s1);
2236 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2237 uf = iptr->sx.s23.s3.uf;
2238 fieldtype = uf->fieldref->parseddesc.fd->type;
2241 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2244 fi = iptr->sx.s23.s3.fmiref->p.field;
2245 fieldtype = fi->type;
2249 switch (fieldtype) {
2251 M_IST(REG_ZERO, s1, disp);
2254 M_LST(REG_ZERO, s1, disp);
2257 M_AST(REG_ZERO, s1, disp);
2260 M_FST(REG_ZERO, s1, disp);
2263 M_DST(REG_ZERO, s1, disp);
2269 /* branch operations **************************************************/
2271 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2273 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2274 M_INTMOVE(s1, REG_ITMP1_XPTR);
2276 #ifdef ENABLE_VERIFIER
2277 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2278 uc = iptr->sx.s23.s2.uc;
2280 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2282 #endif /* ENABLE_VERIFIER */
2284 disp = dseg_add_functionptr(cd, asm_handle_exception);
2285 M_ALD(REG_ITMP2, REG_PV, disp);
2286 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2288 M_NOP; /* nop ensures that XPC is less than the end */
2289 /* of basic block */
2293 case ICMD_GOTO: /* ... ==> ... */
2294 case ICMD_RET: /* ... ==> ... */
2296 emit_br(cd, iptr->dst.block);
2300 case ICMD_JSR: /* ... ==> ... */
2302 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2306 case ICMD_IFNULL: /* ..., value ==> ... */
2307 case ICMD_IFNONNULL:
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2313 case ICMD_IFEQ: /* ..., value ==> ... */
2315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2316 if (iptr->sx.val.i == 0)
2317 emit_beqz(cd, iptr->dst.block, s1);
2319 ICONST(REG_ITMP2, iptr->sx.val.i);
2320 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2324 case ICMD_IFLT: /* ..., value ==> ... */
2326 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2327 if (iptr->sx.val.i == 0)
2328 emit_bltz(cd, iptr->dst.block, s1);
2330 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2331 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2333 ICONST(REG_ITMP2, iptr->sx.val.i);
2334 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2336 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2340 case ICMD_IFLE: /* ..., value ==> ... */
2342 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2343 if (iptr->sx.val.i == 0)
2344 emit_blez(cd, iptr->dst.block, s1);
2346 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2347 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2348 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2351 ICONST(REG_ITMP2, iptr->sx.val.i);
2352 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2353 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2358 case ICMD_IFNE: /* ..., value ==> ... */
2360 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2361 if (iptr->sx.val.i == 0)
2362 emit_bnez(cd, iptr->dst.block, s1);
2364 ICONST(REG_ITMP2, iptr->sx.val.i);
2365 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2369 case ICMD_IFGT: /* ..., value ==> ... */
2371 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2372 if (iptr->sx.val.i == 0)
2373 emit_bgtz(cd, iptr->dst.block, s1);
2375 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2376 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2377 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2380 ICONST(REG_ITMP2, iptr->sx.val.i);
2381 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2382 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2387 case ICMD_IFGE: /* ..., value ==> ... */
2389 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2390 if (iptr->sx.val.i == 0)
2391 emit_bgez(cd, iptr->dst.block, s1);
2393 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2394 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2396 ICONST(REG_ITMP2, iptr->sx.val.i);
2397 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2399 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2403 case ICMD_IF_LEQ: /* ..., value ==> ... */
2405 #if SIZEOF_VOID_P == 8
2406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2407 if (iptr->sx.val.l == 0)
2408 emit_beqz(cd, iptr->dst.block, s1);
2410 LCONST(REG_ITMP2, iptr->sx.val.l);
2411 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2414 if (iptr->sx.val.l == 0) {
2415 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2416 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2417 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2420 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2421 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2422 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2423 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2424 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2425 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2426 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2427 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2432 case ICMD_IF_LLT: /* ..., value ==> ... */
2434 #if SIZEOF_VOID_P == 8
2435 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2436 if (iptr->sx.val.l == 0)
2437 emit_bltz(cd, iptr->dst.block, s1);
2439 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2440 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2442 LCONST(REG_ITMP2, iptr->sx.val.l);
2443 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2445 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2448 if (iptr->sx.val.l == 0) {
2449 /* if high word is less than zero, the whole long is too */
2450 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2451 emit_bltz(cd, iptr->dst.block, s1);
2454 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2455 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2456 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2457 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2458 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2459 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2461 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2462 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2463 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2468 case ICMD_IF_LLE: /* ..., value ==> ... */
2470 #if SIZEOF_VOID_P == 8
2471 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2472 if (iptr->sx.val.l == 0)
2473 emit_blez(cd, iptr->dst.block, s1);
2475 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2476 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2477 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2480 LCONST(REG_ITMP2, iptr->sx.val.l);
2481 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2482 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2486 if (iptr->sx.val.l == 0) {
2487 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2488 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2490 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2491 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2494 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2495 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2496 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2497 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2498 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2499 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2501 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2502 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2503 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2508 case ICMD_IF_LNE: /* ..., value ==> ... */
2510 #if SIZEOF_VOID_P == 8
2511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2512 if (iptr->sx.val.l == 0)
2513 emit_bnez(cd, iptr->dst.block, s1);
2515 LCONST(REG_ITMP2, iptr->sx.val.l);
2516 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2519 if (iptr->sx.val.l == 0) {
2520 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2521 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2522 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2525 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2526 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2527 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2528 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2529 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2530 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2531 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2532 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2537 case ICMD_IF_LGT: /* ..., value ==> ... */
2539 #if SIZEOF_VOID_P == 8
2540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2541 if (iptr->sx.val.l == 0)
2542 emit_bgtz(cd, iptr->dst.block, s1);
2544 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2545 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2546 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2549 LCONST(REG_ITMP2, iptr->sx.val.l);
2550 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2551 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2555 if (iptr->sx.val.l == 0) {
2556 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2557 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2558 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2560 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2563 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2564 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2565 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2566 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2567 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2568 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2570 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2571 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2572 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2577 case ICMD_IF_LGE: /* ..., value ==> ... */
2579 #if SIZEOF_VOID_P == 8
2580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2581 if (iptr->sx.val.l == 0)
2582 emit_bgez(cd, iptr->dst.block, s1);
2584 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2585 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2588 LCONST(REG_ITMP2, iptr->sx.val.l);
2589 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2591 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2594 if (iptr->sx.val.l == 0) {
2595 /* if high word is greater equal zero, the whole long is too */
2596 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2597 emit_bgez(cd, iptr->dst.block, s1);
2600 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2601 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2602 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2603 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2604 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2605 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2607 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2608 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2609 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2614 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2615 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2616 #if SIZEOF_VOID_P == 8
2617 case ICMD_IF_LCMPEQ:
2620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2622 emit_beq(cd, iptr->dst.block, s1, s2);
2625 #if SIZEOF_VOID_P == 4
2626 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2627 /* op1 = target JavaVM pc */
2629 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2630 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2631 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2633 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2634 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2635 emit_beq(cd, iptr->dst.block, s1, s2);
2639 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2640 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2641 #if SIZEOF_VOID_P == 8
2642 case ICMD_IF_LCMPNE:
2645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2647 emit_bne(cd, iptr->dst.block, s1, s2);
2650 #if SIZEOF_VOID_P == 4
2651 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2653 /* TODO: could be optimized (XOR or SUB) */
2654 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2655 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2656 emit_bne(cd, iptr->dst.block, s1, s2);
2657 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2658 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2659 emit_bne(cd, iptr->dst.block, s1, s2);
2663 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2664 #if SIZEOF_VOID_P == 8
2665 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2670 M_CMPLT(s1, s2, REG_ITMP3);
2671 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2674 #if SIZEOF_VOID_P == 4
2675 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2677 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2678 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2679 M_CMPLT(s1, s2, REG_ITMP3);
2680 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2681 M_CMPGT(s1, s2, REG_ITMP3);
2682 /* load low-bits before the branch, so we know the distance */
2683 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2684 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2685 M_BNEZ(REG_ITMP3, 4); /* XXX */
2687 M_CMPULT(s1, s2, REG_ITMP3);
2688 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2692 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2693 #if SIZEOF_VOID_P == 8
2694 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2699 M_CMPGT(s1, s2, REG_ITMP3);
2700 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2703 #if SIZEOF_VOID_P == 4
2704 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2706 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2707 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2708 M_CMPGT(s1, s2, REG_ITMP3);
2709 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2710 M_CMPLT(s1, s2, REG_ITMP3);
2711 /* load low-bits before the branch, so we know the distance */
2712 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2713 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2714 M_BNEZ(REG_ITMP3, 4); /* XXX */
2716 M_CMPUGT(s1, s2, REG_ITMP3);
2717 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2721 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2722 #if SIZEOF_VOID_P == 8
2723 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2727 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2728 M_CMPGT(s1, s2, REG_ITMP3);
2729 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2732 #if SIZEOF_VOID_P == 4
2733 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2735 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2736 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2737 M_CMPLT(s1, s2, REG_ITMP3);
2738 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2739 M_CMPGT(s1, s2, REG_ITMP3);
2740 /* load low-bits before the branch, so we know the distance */
2741 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2742 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2743 M_BNEZ(REG_ITMP3, 4); /* XXX */
2745 M_CMPUGT(s1, s2, REG_ITMP3);
2746 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2750 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2751 #if SIZEOF_VOID_P == 8
2752 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2756 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2757 M_CMPLT(s1, s2, REG_ITMP3);
2758 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2761 #if SIZEOF_VOID_P == 4
2762 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2764 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2765 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2766 M_CMPGT(s1, s2, REG_ITMP3);
2767 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2768 M_CMPLT(s1, s2, REG_ITMP3);
2769 /* load low-bits before the branch, so we know the distance */
2770 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2771 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2772 M_BNEZ(REG_ITMP3, 4); /* XXX */
2774 M_CMPULT(s1, s2, REG_ITMP3);
2775 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2779 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2780 #if SIZEOF_VOID_P == 8
2784 REPLACEMENT_POINT_RETURN(cd, iptr);
2785 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2786 M_INTMOVE(s1, REG_RESULT);
2787 goto nowperformreturn;
2789 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2791 REPLACEMENT_POINT_RETURN(cd, iptr);
2792 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2793 M_INTMOVE(s1, REG_RESULT);
2795 #ifdef ENABLE_VERIFIER
2796 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2797 uc = iptr->sx.s23.s2.uc;
2799 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2801 #endif /* ENABLE_VERIFIER */
2802 goto nowperformreturn;
2804 #if SIZEOF_VOID_P == 4
2805 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2807 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2808 M_LNGMOVE(s1, REG_RESULT_PACKED);
2809 goto nowperformreturn;
2812 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2813 REPLACEMENT_POINT_RETURN(cd, iptr);
2814 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2815 M_FLTMOVE(s1, REG_FRESULT);
2816 goto nowperformreturn;
2818 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2820 REPLACEMENT_POINT_RETURN(cd, iptr);
2821 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2822 M_DBLMOVE(s1, REG_FRESULT);
2823 goto nowperformreturn;
2825 case ICMD_RETURN: /* ... ==> ... */
2827 REPLACEMENT_POINT_RETURN(cd, iptr);
2833 p = cd->stackframesize;
2835 #if !defined(NDEBUG)
2836 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2837 emit_verbosecall_exit(jd);
2840 #if defined(ENABLE_THREADS)
2841 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2842 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2843 M_ALD(REG_ITMP3, REG_PV, disp);
2845 /* we need to save the proper return value */
2847 switch (iptr->opc) {
2850 #if SIZEOF_VOID_P == 8
2853 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2854 M_JSR(REG_RA, REG_ITMP3);
2855 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2857 #if SIZEOF_VOID_P == 4
2859 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2860 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2861 M_JSR(REG_RA, REG_ITMP3);
2867 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2868 M_JSR(REG_RA, REG_ITMP3);
2869 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2872 M_JSR(REG_RA, REG_ITMP3);
2873 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2877 /* and now restore the proper return value */
2879 switch (iptr->opc) {
2882 #if SIZEOF_VOID_P == 8
2885 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2887 #if SIZEOF_VOID_P == 4
2889 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2894 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2900 /* restore return address */
2902 if (!code_is_leafmethod(code)) {
2903 p--; M_ALD(REG_RA, REG_SP, p * 8);
2906 /* restore saved registers */
2908 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2909 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2911 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2912 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2915 /* deallocate stack and return */
2917 if (cd->stackframesize) {
2920 disp = cd->stackframesize * 8;
2921 lo = (short) (disp);
2922 hi = (short) (((disp) - lo) >> 16);
2926 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2928 M_LUI(REG_ITMP3,hi);
2929 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2931 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2944 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2947 branch_target_t *table;
2949 table = iptr->dst.table;
2951 l = iptr->sx.s23.s2.tablelow;
2952 i = iptr->sx.s23.s3.tablehigh;
2954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2956 {M_INTMOVE(s1, REG_ITMP1);}
2957 else if (l <= 32768) {
2958 M_IADD_IMM(s1, -l, REG_ITMP1);
2961 ICONST(REG_ITMP2, l);
2962 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2965 /* number of targets */
2970 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2971 emit_beqz(cd, table[0].block, REG_ITMP2);
2973 /* build jump table top down and use address of lowest entry */
2978 dseg_add_target(cd, table->block);
2983 /* length of dataseg after last dseg_add_target is used by load */
2985 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2986 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2987 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2994 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2997 lookup_target_t *lookup;
2999 lookup = iptr->dst.lookup;
3001 i = iptr->sx.s23.s2.lookupcount;
3003 MCODECHECK((i<<2)+8);
3004 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3007 ICONST(REG_ITMP2, lookup->value);
3008 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3012 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3018 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3020 bte = iptr->sx.s23.s3.bte;
3024 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3026 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3027 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3028 case ICMD_INVOKEINTERFACE:
3030 REPLACEMENT_POINT_INVOKE(cd, iptr);
3032 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3034 um = iptr->sx.s23.s3.um;
3035 md = um->methodref->parseddesc.md;
3038 lm = iptr->sx.s23.s3.fmiref->p.method;
3040 md = lm->parseddesc;
3044 s3 = md->paramcount;
3046 MCODECHECK((s3 << 1) + 64);
3048 /* copy arguments to registers or stack location */
3050 for (s3 = s3 - 1; s3 >= 0; s3--) {
3051 var = VAR(iptr->sx.s23.s2.args[s3]);
3052 d = md->params[s3].regoff;
3054 if (var->flags & PREALLOC)
3057 if (IS_INT_LNG_TYPE(var->type)) {
3058 #if SIZEOF_VOID_P == 8
3059 if (!md->params[s3].inmemory) {
3060 s1 = emit_load(jd, iptr, var, d);
3064 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3065 M_LST(s1, REG_SP, d);
3068 if (!md->params[s3].inmemory) {
3069 s1 = emit_load(jd, iptr, var, d);
3071 if (IS_2_WORD_TYPE(var->type))
3077 if (IS_2_WORD_TYPE(var->type)) {
3078 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3079 M_LST(s1, REG_SP, d);
3082 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3083 M_IST(s1, REG_SP, d);
3089 if (!md->params[s3].inmemory) {
3090 s1 = emit_load(jd, iptr, var, d);
3091 if (IS_2_WORD_TYPE(var->type))
3097 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3098 if (IS_2_WORD_TYPE(var->type))
3099 M_DST(s1, REG_SP, d);
3101 M_FST(s1, REG_SP, d);
3106 switch (iptr->opc) {
3108 if (bte->stub == NULL) {
3109 disp = dseg_add_functionptr(cd, bte->fp);
3110 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3112 /* generate the actual call */
3114 /* TWISTI: i actually don't know the reason for using
3115 REG_ITMP3 here instead of REG_PV. */
3117 M_JSR(REG_RA, REG_ITMP3);
3121 disp = dseg_add_functionptr(cd, bte->stub);
3122 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3124 /* generate the actual call */
3126 M_JSR(REG_RA, REG_PV);
3130 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3131 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3132 M_LDA(REG_PV, REG_RA, -disp);
3135 case ICMD_INVOKESPECIAL:
3136 emit_nullpointer_check(cd, iptr, REG_A0);
3139 case ICMD_INVOKESTATIC:
3141 disp = dseg_add_unique_address(cd, um);
3143 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3147 disp = dseg_add_address(cd, lm->stubroutine);
3149 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3151 /* generate the actual call */
3153 M_JSR(REG_RA, REG_PV);
3155 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3156 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3157 M_LDA(REG_PV, REG_RA, -disp);
3160 case ICMD_INVOKEVIRTUAL:
3161 emit_nullpointer_check(cd, iptr, REG_A0);
3164 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3169 s1 = OFFSET(vftbl_t, table[0]) +
3170 sizeof(methodptr) * lm->vftblindex;
3172 /* implicit null-pointer check */
3173 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3174 M_ALD(REG_PV, REG_METHODPTR, s1);
3176 /* generate the actual call */
3178 M_JSR(REG_RA, REG_PV);
3180 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3181 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3182 M_LDA(REG_PV, REG_RA, -disp);
3185 case ICMD_INVOKEINTERFACE:
3186 emit_nullpointer_check(cd, iptr, REG_A0);
3189 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3195 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3196 sizeof(methodptr*) * lm->class->index;
3198 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3201 /* implicit null-pointer check */
3202 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3203 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3204 M_ALD(REG_PV, REG_METHODPTR, s2);
3206 /* generate the actual call */
3208 M_JSR(REG_RA, REG_PV);
3210 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3211 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3212 M_LDA(REG_PV, REG_RA, -disp);
3216 /* store return value */
3218 d = md->returntype.type;
3220 if (d != TYPE_VOID) {
3221 if (IS_INT_LNG_TYPE(d)) {
3222 #if SIZEOF_VOID_P == 8
3223 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3224 M_INTMOVE(REG_RESULT, s1);
3226 if (IS_2_WORD_TYPE(d)) {
3227 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3228 M_LNGMOVE(REG_RESULT_PACKED, s1);
3231 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3232 M_INTMOVE(REG_RESULT, s1);
3237 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3238 if (IS_2_WORD_TYPE(d))
3239 M_DMOV(REG_FRESULT, s1);
3241 M_FMOV(REG_FRESULT, s1);
3243 emit_store_dst(jd, iptr, s1);
3248 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3250 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3254 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3259 super = iptr->sx.s23.s3.c.cls;
3260 superindex = super->index;
3263 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3264 CODEGEN_CRITICAL_SECTION_NEW;
3266 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3268 /* if class is not resolved, check which code to call */
3270 if (super == NULL) {
3271 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3273 cr = iptr->sx.s23.s3.c.ref;
3274 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3276 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3279 M_ILD(REG_ITMP2, REG_PV, disp);
3280 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3281 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3284 /* interface checkcast code */
3286 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3287 if (super == NULL) {
3288 cr = iptr->sx.s23.s3.c.ref;
3290 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3294 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3297 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3298 M_ILD(REG_ITMP3, REG_ITMP2,
3299 OFFSET(vftbl_t, interfacetablelength));
3300 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3301 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3303 M_ALD(REG_ITMP3, REG_ITMP2,
3304 OFFSET(vftbl_t, interfacetable[0]) -
3305 superindex * sizeof(methodptr*));
3306 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3309 emit_label_br(cd, BRANCH_LABEL_4);
3311 emit_label(cd, BRANCH_LABEL_3);
3314 /* class checkcast code */
3316 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3317 if (super == NULL) {
3318 emit_label(cd, BRANCH_LABEL_2);
3320 cr = iptr->sx.s23.s3.c.ref;
3321 disp = dseg_add_unique_address(cd, NULL);
3323 patcher_add_patch_ref(jd,
3324 PATCHER_resolve_classref_to_vftbl,
3328 disp = dseg_add_address(cd, super->vftbl);
3330 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3333 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3334 M_ALD(REG_ITMP3, REG_PV, disp);
3336 CODEGEN_CRITICAL_SECTION_START;
3338 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3339 /* if (s1 != REG_ITMP1) { */
3340 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3341 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3342 /* #if defined(ENABLE_THREADS) */
3343 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3345 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3347 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3348 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3349 M_ALD(REG_ITMP3, REG_PV, disp);
3350 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3352 CODEGEN_CRITICAL_SECTION_END;
3355 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3356 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3359 emit_label(cd, BRANCH_LABEL_5);
3362 if (super == NULL) {
3363 emit_label(cd, BRANCH_LABEL_1);
3364 emit_label(cd, BRANCH_LABEL_4);
3367 d = codegen_reg_of_dst(jd, iptr, s1);
3370 s1 = emit_load_s1(jd, iptr, REG_A0);
3371 M_INTMOVE(s1, REG_A0);
3373 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3374 cr = iptr->sx.s23.s3.c.ref;
3375 disp = dseg_add_unique_address(cd, NULL);
3377 patcher_add_patch_ref(jd,
3378 PATCHER_resolve_classref_to_classinfo,
3382 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3385 M_ALD(REG_A1, REG_PV, disp);
3386 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3387 M_ALD(REG_ITMP3, REG_PV, disp);
3388 M_JSR(REG_RA, REG_ITMP3);
3391 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3392 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3394 d = codegen_reg_of_dst(jd, iptr, s1);
3398 emit_store_dst(jd, iptr, d);
3401 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3407 super = iptr->sx.s23.s3.c.cls;
3409 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3414 super = iptr->sx.s23.s3.c.cls;
3415 superindex = super->index;
3418 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3419 CODEGEN_CRITICAL_SECTION_NEW;
3421 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3425 M_MOV(s1, REG_ITMP1);
3431 /* if class is not resolved, check which code to call */
3433 if (super == NULL) {
3434 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3436 cr = iptr->sx.s23.s3.c.ref;
3437 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3439 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3442 M_ILD(REG_ITMP3, REG_PV, disp);
3443 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3444 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3447 /* interface instanceof code */
3449 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3450 if (super == NULL) {
3451 cr = iptr->sx.s23.s3.c.ref;
3453 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3457 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3460 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3461 M_ILD(REG_ITMP3, REG_ITMP1,
3462 OFFSET(vftbl_t, interfacetablelength));
3463 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3464 M_BLEZ(REG_ITMP3, 3);
3466 M_ALD(REG_ITMP1, REG_ITMP1,
3467 OFFSET(vftbl_t, interfacetable[0]) -
3468 superindex * sizeof(methodptr*));
3469 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3472 emit_label_br(cd, BRANCH_LABEL_4);
3474 emit_label(cd, BRANCH_LABEL_3);
3477 /* class instanceof code */
3479 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3480 if (super == NULL) {
3481 emit_label(cd, BRANCH_LABEL_2);
3483 cr = iptr->sx.s23.s3.c.ref;
3484 disp = dseg_add_unique_address(cd, NULL);
3486 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3490 disp = dseg_add_address(cd, super->vftbl);
3492 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3495 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3496 M_ALD(REG_ITMP2, REG_PV, disp);
3498 CODEGEN_CRITICAL_SECTION_START;
3500 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3501 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3502 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3504 CODEGEN_CRITICAL_SECTION_END;
3506 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3507 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3511 emit_label(cd, BRANCH_LABEL_5);
3514 if (super == NULL) {
3515 emit_label(cd, BRANCH_LABEL_1);
3516 emit_label(cd, BRANCH_LABEL_4);
3519 emit_store_dst(jd, iptr, d);
3523 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3525 /* check for negative sizes and copy sizes to stack if necessary */
3527 MCODECHECK((iptr->s1.argcount << 1) + 64);
3529 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3531 var = VAR(iptr->sx.s23.s2.args[s1]);
3533 /* copy SAVEDVAR sizes to stack */
3535 if (!(var->flags & PREALLOC)) {
3536 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3537 #if SIZEOF_VOID_P == 8
3538 M_LST(s2, REG_SP, s1 * 8);
3540 M_IST(s2, REG_SP, (s1 + 2) * 8);
3545 /* a0 = dimension count */
3547 ICONST(REG_A0, iptr->s1.argcount);
3549 /* is patcher function set? */
3551 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3552 cr = iptr->sx.s23.s3.c.ref;
3553 disp = dseg_add_unique_address(cd, NULL);
3555 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3559 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3562 /* a1 = arraydescriptor */
3564 M_ALD(REG_A1, REG_PV, disp);
3566 /* a2 = pointer to dimensions = stack pointer */
3568 #if SIZEOF_VOID_P == 8
3569 M_MOV(REG_SP, REG_A2);
3571 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3574 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3575 M_ALD(REG_ITMP3, REG_PV, disp);
3576 M_JSR(REG_RA, REG_ITMP3);
3579 /* check for exception before result assignment */
3581 emit_exception_check(cd, iptr);
3583 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3584 M_INTMOVE(REG_RESULT, d);
3585 emit_store_dst(jd, iptr, d);
3589 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3594 } /* for instruction */
3596 MCODECHECK(64); /* XXX require smaller number? */
3598 /* At the end of a basic block we may have to append some nops,
3599 because the patcher stub calling code might be longer than the
3600 actual instruction. So codepatching does not change the
3601 following block unintentionally. */
3603 if (cd->mcodeptr < cd->lastmcodeptr) {
3604 while (cd->mcodeptr < cd->lastmcodeptr)
3608 } /* if (bptr -> flags >= BBREACHED) */
3609 } /* for basic block */
3611 dseg_createlinenumbertable(cd);
3613 /* generate traps */
3615 emit_patcher_traps(jd);
3617 /* everything's ok */
3623 /* codegen_emit_stub_compiler **************************************************
3625 Emits a stub routine which calls the compiler.
3627 *******************************************************************************/
3629 void codegen_emit_stub_compiler(jitdata *jd)
3634 /* get required compiler data */
3639 /* code for the stub */
3641 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3642 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3648 /* codegen_emit_stub_native ****************************************************
3650 Emits a stub routine which calls a native method.
3652 *******************************************************************************/
3654 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3663 s4 funcdisp; /* displacement of the function */
3665 /* get required compiler data */
3671 /* initialize variables */
3675 /* calculate stack frame size */
3677 cd->stackframesize =
3678 1 + /* return address */
3679 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3680 sizeof(localref_table) / SIZEOF_VOID_P +
3681 md->paramcount + /* for saving arguments over calls */
3682 #if SIZEOF_VOID_P == 4
3683 5 + /* additional save space (MIPS32) */
3685 1 + /* for saving return address */
3688 /* adjust stackframe size for 16-byte alignment */
3690 if (cd->stackframesize & 1)
3691 cd->stackframesize++;
3693 /* create method header */
3695 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3696 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3697 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3698 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3699 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3700 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3701 (void) dseg_addlinenumbertablesize(cd);
3702 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3704 /* generate stub code */
3706 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3707 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3709 #if !defined(NDEBUG)
3710 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3711 emit_verbosecall_enter(jd);
3714 /* get function address (this must happen before the stackframeinfo) */
3716 funcdisp = dseg_add_functionptr(cd, f);
3719 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3721 /* save integer and float argument registers */
3723 #if SIZEOF_VOID_P == 8
3724 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3725 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3726 s1 = md->params[i].regoff;
3727 M_AST(s1, REG_SP, j * 8);
3732 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3733 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3734 if (!md->params[i].inmemory) {
3735 s1 = md->params[i].regoff;
3737 if (IS_2_WORD_TYPE(md->params[i].type))
3738 M_LST(s1, REG_SP, j * 8);
3740 M_IST(s1, REG_SP, j * 8);
3748 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3749 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3750 s1 = md->params[i].regoff;
3752 if (IS_2_WORD_TYPE(md->params[i].type))
3753 M_DST(s1, REG_SP, j * 8);
3755 M_FST(s1, REG_SP, j * 8);
3761 /* prepare data structures for native function call */
3763 M_MOV(REG_SP, REG_A0);
3764 M_MOV(REG_PV, REG_A1);
3765 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3766 M_ALD(REG_ITMP3, REG_PV, disp);
3767 M_JSR(REG_RA, REG_ITMP3);
3768 M_NOP; /* XXX fill me! */
3770 /* remember class argument */
3772 if (m->flags & ACC_STATIC)
3773 M_MOV(REG_RESULT, REG_ITMP3);
3775 /* restore integer and float argument registers */
3777 #if SIZEOF_VOID_P == 8
3778 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3779 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3780 s1 = md->params[i].regoff;
3781 M_LLD(s1, REG_SP, j * 8);
3786 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3787 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3788 if (!md->params[i].inmemory) {
3789 s1 = md->params[i].regoff;
3791 if (IS_2_WORD_TYPE(md->params[i].type))
3792 M_LLD(s1, REG_SP, j * 8);
3794 M_ILD(s1, REG_SP, j * 8);
3802 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3803 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3804 s1 = md->params[i].regoff;
3806 if (IS_2_WORD_TYPE(md->params[i].type))
3807 M_DLD(s1, REG_SP, j * 8);
3809 M_FLD(s1, REG_SP, j * 8);
3815 /* copy or spill arguments to new locations */
3817 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3818 t = md->params[i].type;
3820 if (IS_INT_LNG_TYPE(t)) {
3821 if (!md->params[i].inmemory) {
3822 s1 = md->params[i].regoff;
3823 s2 = nmd->params[j].regoff;
3825 if (!nmd->params[j].inmemory) {
3826 #if SIZEOF_VOID_P == 8
3829 if (IS_2_WORD_TYPE(t))
3836 #if SIZEOF_VOID_P == 8
3837 M_LST(s1, REG_SP, s2);
3839 if (IS_2_WORD_TYPE(t))
3840 M_LST(s1, REG_SP, s2);
3842 M_IST(s1, REG_SP, s2);
3847 s1 = md->params[i].regoff + cd->stackframesize * 8;
3848 s2 = nmd->params[j].regoff;
3850 #if SIZEOF_VOID_P == 8
3851 M_LLD(REG_ITMP1, REG_SP, s1);
3852 M_LST(REG_ITMP1, REG_SP, s2);
3854 if (IS_2_WORD_TYPE(t)) {
3855 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3856 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3859 M_ILD(REG_ITMP1, REG_SP, s1);
3860 M_IST(REG_ITMP1, REG_SP, s2);
3866 if (!md->params[i].inmemory) {
3867 s1 = md->params[i].regoff;
3868 s2 = nmd->params[j].regoff;
3870 if (!nmd->params[j].inmemory) {
3871 #if SIZEOF_VOID_P == 8
3872 if (IS_2_WORD_TYPE(t))
3877 /* On MIPS32 float arguments for native functions
3878 can never be in float argument registers, since
3879 the first argument is _always_ an integer
3880 argument (JNIEnv) */
3882 if (IS_2_WORD_TYPE(t)) {
3883 /* double high/low order is endian
3884 independent: even numbered holds low
3885 32-bits, odd numbered high 32-bits */
3887 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3888 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3895 #if SIZEOF_VOID_P == 8
3896 if (IS_2_WORD_TYPE(t))
3897 M_DST(s1, REG_SP, s2);
3899 M_FST(s1, REG_SP, s2);
3901 /* s1 may have been originally in 2 int registers,
3902 but was moved out by the native function
3903 argument(s), just get low register */
3905 if (IS_2_WORD_TYPE(t))
3906 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3908 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3913 s1 = md->params[i].regoff + cd->stackframesize * 8;
3914 s2 = nmd->params[j].regoff;
3916 #if SIZEOF_VOID_P == 8
3917 if (IS_2_WORD_TYPE(t)) {
3918 M_DLD(REG_FTMP1, REG_SP, s1);
3919 M_DST(REG_FTMP1, REG_SP, s2);
3922 M_FLD(REG_FTMP1, REG_SP, s1);
3923 M_FST(REG_FTMP1, REG_SP, s2);
3926 if (IS_2_WORD_TYPE(t)) {
3927 M_DLD(REG_FTMP1, REG_SP, s1);
3928 M_DST(REG_FTMP1, REG_SP, s2);
3931 M_FLD(REG_FTMP1, REG_SP, s1);
3932 M_FST(REG_FTMP1, REG_SP, s2);
3939 /* Handle native Java methods. */
3941 if (m->flags & ACC_NATIVE) {
3942 /* put class into second argument register */
3944 if (m->flags & ACC_STATIC)
3945 M_MOV(REG_ITMP3, REG_A1);
3947 /* put env into first argument register */
3949 disp = dseg_add_address(cd, _Jv_env);
3950 M_ALD(REG_A0, REG_PV, disp);
3953 /* do the native function call */
3955 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3956 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3957 M_NOP; /* delay slot */
3959 /* save return value */
3961 switch (md->returntype.type) {
3962 #if SIZEOF_VOID_P == 8
3966 M_LST(REG_RESULT, REG_SP, 0 * 8);
3970 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3975 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3978 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3982 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3989 #if !defined(NDEBUG)
3990 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3991 emit_verbosecall_exit(jd);
3994 /* remove native stackframe info */
3996 M_MOV(REG_SP, REG_A0);
3997 M_MOV(REG_PV, REG_A1);
3998 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3999 M_ALD(REG_ITMP3, REG_PV, disp);
4000 M_JSR(REG_RA, REG_ITMP3);
4001 M_NOP; /* XXX fill me! */
4002 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4004 /* restore return value */
4006 switch (md->returntype.type) {
4007 #if SIZEOF_VOID_P == 8
4011 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4015 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4020 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
4023 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
4027 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4034 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4036 /* check for exception */
4038 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4039 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4041 M_RET(REG_RA); /* return to caller */
4042 M_NOP; /* DELAY SLOT */
4044 /* handle exception */
4046 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4047 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4048 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4049 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4051 /* Generate patcher traps. */
4053 emit_patcher_traps(jd);
4058 * These are local overrides for various environment variables in Emacs.
4059 * Please do not remove this and leave it at the end of the file, where
4060 * Emacs will automagically detect them.
4061 * ---------------------------------------------------------------------
4064 * indent-tabs-mode: t
4068 * vim:noexpandtab:sw=4:ts=4: