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 && code_is_synchronized(code)) {
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 code->synchronizedoffset = rd->memuse * 8;
155 /* REMOVEME: We still need it for exception handling in assembler. */
157 if (code_is_leafmethod(code))
158 (void) dseg_add_unique_s4(cd, 1);
160 (void) dseg_add_unique_s4(cd, 0);
162 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
163 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
164 dseg_addlinenumbertablesize(cd);
165 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
167 /* create exception table */
169 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
170 dseg_add_target(cd, ex->start);
171 dseg_add_target(cd, ex->end);
172 dseg_add_target(cd, ex->handler);
173 (void) dseg_add_unique_address(cd, ex->catchtype.any);
176 /* create stack frame (if necessary) */
178 if (cd->stackframesize)
179 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
181 /* save return address and used callee saved registers */
183 p = cd->stackframesize;
184 if (!code_is_leafmethod(code)) {
185 p--; M_AST(REG_RA, REG_SP, p * 8);
187 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
188 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
190 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
191 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
194 /* take arguments out of register or stack frame */
198 for (p = 0, l = 0; p < md->paramcount; p++) {
199 t = md->paramtypes[p].type;
201 varindex = jd->local_map[l * 5 + t];
204 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
207 if (varindex == UNUSED)
211 s1 = md->params[p].regoff;
213 if (IS_INT_LNG_TYPE(t)) { /* integer args */
214 if (!md->params[p].inmemory) { /* register arguments */
215 #if SIZEOF_VOID_P == 8
216 if (!(var->flags & INMEMORY))
217 M_INTMOVE(s1, var->vv.regoff);
219 M_LST(s1, REG_SP, var->vv.regoff);
221 if (!(var->flags & INMEMORY)) {
222 if (IS_2_WORD_TYPE(t))
223 M_LNGMOVE(s1, var->vv.regoff);
225 M_INTMOVE(s1, var->vv.regoff);
228 if (IS_2_WORD_TYPE(t))
229 M_LST(s1, REG_SP, var->vv.regoff);
231 M_IST(s1, REG_SP, var->vv.regoff);
235 else { /* stack arguments */
236 if (!(var->flags & INMEMORY)) {
237 #if SIZEOF_VOID_P == 8
238 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
240 if (IS_2_WORD_TYPE(t))
241 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
243 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
247 var->vv.regoff = cd->stackframesize * 8 + s1;
250 else { /* floating args */
251 if (!md->params[p].inmemory) {
252 if (!(var->flags & INMEMORY)) {
253 if (IS_2_WORD_TYPE(t))
254 M_DBLMOVE(s1, var->vv.regoff);
256 M_FLTMOVE(s1, var->vv.regoff);
259 if (IS_2_WORD_TYPE(t))
260 M_DST(s1, REG_SP, var->vv.regoff);
262 M_FST(s1, REG_SP, var->vv.regoff);
266 if (!(var->flags & INMEMORY)) {
267 if (IS_2_WORD_TYPE(t))
268 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
270 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
273 var->vv.regoff = cd->stackframesize * 8 + s1;
278 /* call monitorenter function */
280 #if defined(ENABLE_THREADS)
281 if (checksync && code_is_synchronized(code)) {
282 /* stack offset for monitor argument */
286 # if !defined(NDEBUG)
287 if (opt_verbosecall) {
288 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
290 for (p = 0; p < INT_ARG_CNT; p++)
291 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
293 for (p = 0; p < FLT_ARG_CNT; p++)
294 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
296 s1 += INT_ARG_CNT + FLT_ARG_CNT;
300 /* get correct lock object */
302 if (m->flags & ACC_STATIC) {
303 disp = dseg_add_address(cd, &m->class->object.header);
304 M_ALD(REG_A0, REG_PV, disp);
305 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
306 M_ALD(REG_ITMP3, REG_PV, disp);
309 /* emit_nullpointer_check(cd, iptr, REG_A0); */
311 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
312 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
313 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
316 M_JSR(REG_RA, REG_ITMP3);
317 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
319 # if !defined(NDEBUG)
320 if (opt_verbosecall) {
321 for (p = 0; p < INT_ARG_CNT; p++)
322 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
324 for (p = 0; p < FLT_ARG_CNT; p++)
325 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
328 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
336 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
337 emit_verbosecall_enter(jd);
340 /* end of header generation */
342 /* create replacement points */
344 REPLACEMENT_POINTS_INIT(cd, jd);
346 /* walk through all basic blocks */
348 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
350 /* handle replacement points */
352 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
354 /* store relative start of block */
356 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
358 if (bptr->flags >= BBREACHED) {
359 /* branch resolving */
361 codegen_resolve_branchrefs(cd, bptr);
363 /* copy interface registers to their destination */
367 #if defined(ENABLE_LSRA)
371 src = bptr->invars[len];
372 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
373 /* d = reg_of_var(m, src, REG_ITMP1); */
374 if (!(src->flags & INMEMORY))
378 M_INTMOVE(REG_ITMP1, d);
379 emit_store(jd, NULL, src, d);
386 var = VAR(bptr->invars[len]);
387 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
388 d = codegen_reg_of_var(0, var, REG_ITMP1);
389 M_INTMOVE(REG_ITMP1, d);
390 emit_store(jd, NULL, var, d);
393 assert((var->flags & INOUT));
396 #if defined(ENABLE_LSRA)
399 /* walk through all instructions */
402 /* currentline = 0; */
404 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
405 if (iptr->line != currentline) {
406 dseg_addlinenumber(cd, iptr->line);
407 currentline = iptr->line;
410 MCODECHECK(64); /* an instruction usually needs < 64 words */
414 case ICMD_NOP: /* ... ==> ... */
415 case ICMD_POP: /* ..., value ==> ... */
416 case ICMD_POP2: /* ..., value, value ==> ... */
419 case ICMD_INLINE_START:
421 REPLACEMENT_POINT_INLINE_START(cd, iptr);
424 case ICMD_INLINE_BODY:
426 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
427 dseg_addlinenumber_inline_start(cd, iptr);
428 dseg_addlinenumber(cd, iptr->line);
431 case ICMD_INLINE_END:
433 dseg_addlinenumber_inline_end(cd, iptr);
434 dseg_addlinenumber(cd, iptr->line);
437 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
440 emit_nullpointer_check(cd, iptr, s1);
443 /* constant operations ************************************************/
445 case ICMD_ICONST: /* ... ==> ..., constant */
447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
448 ICONST(d, iptr->sx.val.i);
449 emit_store_dst(jd, iptr, d);
452 case ICMD_LCONST: /* ... ==> ..., constant */
454 #if SIZEOF_VOID_P == 8
455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
459 LCONST(d, iptr->sx.val.l);
460 emit_store_dst(jd, iptr, d);
463 case ICMD_FCONST: /* ... ==> ..., constant */
465 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
466 disp = dseg_add_float(cd, iptr->sx.val.f);
467 M_FLD(d, REG_PV, disp);
468 emit_store_dst(jd, iptr, d);
471 case ICMD_DCONST: /* ... ==> ..., constant */
473 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
474 disp = dseg_add_double(cd, iptr->sx.val.d);
475 M_DLD(d, REG_PV, disp);
476 emit_store_dst(jd, iptr, d);
479 case ICMD_ACONST: /* ... ==> ..., constant */
481 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
483 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
484 cr = iptr->sx.val.c.ref;
485 disp = dseg_add_unique_address(cd, cr);
487 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
490 M_ALD(d, REG_PV, disp);
493 if (iptr->sx.val.anyptr == NULL)
494 M_INTMOVE(REG_ZERO, d);
496 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
497 M_ALD(d, REG_PV, disp);
500 emit_store_dst(jd, iptr, d);
504 /* load/store/copy/move operations ************************************/
506 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
511 case ICMD_ISTORE: /* ..., value ==> ... */
522 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
527 /* integer operations *************************************************/
529 case ICMD_INEG: /* ..., value ==> ..., - value */
531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
533 M_ISUB(REG_ZERO, s1, d);
534 emit_store_dst(jd, iptr, d);
537 case ICMD_LNEG: /* ..., value ==> ..., - value */
539 #if SIZEOF_VOID_P == 8
540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
542 M_LSUB(REG_ZERO, s1, d);
544 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
546 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
547 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
548 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
549 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
551 emit_store_dst(jd, iptr, d);
554 case ICMD_I2L: /* ..., value ==> ..., value */
556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557 #if SIZEOF_VOID_P == 8
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
562 M_INTMOVE(s1, GET_LOW_REG(d));
563 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
565 emit_store_dst(jd, iptr, d);
568 case ICMD_L2I: /* ..., value ==> ..., value */
570 #if SIZEOF_VOID_P == 8
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 M_ISLL_IMM(s1, 0, d);
575 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
577 M_INTMOVE(GET_LOW_REG(s1), d);
579 emit_store_dst(jd, iptr, d);
582 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586 #if SIZEOF_VOID_P == 8
587 M_LSLL_IMM(s1, 56, d);
588 M_LSRA_IMM( d, 56, d);
590 M_ISLL_IMM(s1, 24, d);
591 M_ISRA_IMM( d, 24, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
600 M_AND_IMM(s1, 0xffff, d);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 #if SIZEOF_VOID_P == 8
609 M_LSLL_IMM(s1, 48, d);
610 M_LSRA_IMM( d, 48, d);
612 M_ISLL_IMM(s1, 16, d);
613 M_ISRA_IMM( d, 16, d);
615 emit_store_dst(jd, iptr, d);
619 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 emit_store_dst(jd, iptr, d);
629 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
630 /* sx.val.i = constant */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
635 M_IADD_IMM(s1, iptr->sx.val.i, d);
637 ICONST(REG_ITMP2, iptr->sx.val.i);
638 M_IADD(s1, REG_ITMP2, d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
645 #if SIZEOF_VOID_P == 8
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
651 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
652 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
654 M_IADD(s1, s2, GET_HIGH_REG(d));
655 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
656 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
657 if (s1 == GET_LOW_REG(d)) {
658 M_MOV(s1, REG_ITMP3);
661 M_IADD(s1, s2, GET_LOW_REG(d));
662 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
663 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
665 emit_store_dst(jd, iptr, d);
668 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
669 /* sx.val.l = constant */
671 #if SIZEOF_VOID_P == 8
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
674 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
675 M_LADD_IMM(s1, iptr->sx.val.l, d);
677 LCONST(REG_ITMP2, iptr->sx.val.l);
678 M_LADD(s1, REG_ITMP2, d);
681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
682 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
683 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
684 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
685 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
686 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
688 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
689 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
690 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
691 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
692 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
693 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
694 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
697 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
698 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
699 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
700 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
701 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
702 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
703 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
704 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
707 emit_store_dst(jd, iptr, d);
710 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
716 emit_store_dst(jd, iptr, d);
719 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
720 /* sx.val.i = constant */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
724 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
725 M_IADD_IMM(s1, -iptr->sx.val.i, d);
727 ICONST(REG_ITMP2, iptr->sx.val.i);
728 M_ISUB(s1, REG_ITMP2, d);
730 emit_store_dst(jd, iptr, d);
733 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
735 #if SIZEOF_VOID_P == 8
736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
737 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
741 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
742 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
744 M_ISUB(s1, s2, GET_HIGH_REG(d));
745 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
746 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
747 M_CMPULT(s1, s2, REG_ITMP3);
748 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
749 /* if s1 is equal to REG_ITMP3 we have to reload it, since
750 the CMPULT instruction destroyed it */
752 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
753 M_ISUB(s1, s2, GET_LOW_REG(d));
756 emit_store_dst(jd, iptr, d);
759 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
760 /* sx.val.l = constant */
762 #if SIZEOF_VOID_P == 8
763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
764 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
765 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
766 M_LADD_IMM(s1, -iptr->sx.val.l, d);
768 LCONST(REG_ITMP2, iptr->sx.val.l);
769 M_LSUB(s1, REG_ITMP2, d);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
773 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
774 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
775 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
776 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
777 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
778 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
779 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
781 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
782 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
783 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
784 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
785 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
788 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
789 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
790 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
791 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
792 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
793 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
794 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
795 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
798 emit_store_dst(jd, iptr, d);
801 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
805 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
814 /* sx.val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
818 ICONST(REG_ITMP2, iptr->sx.val.i);
819 M_IMUL(s1, REG_ITMP2);
823 emit_store_dst(jd, iptr, d);
826 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
828 #if SIZEOF_VOID_P == 8
829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
830 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
837 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
838 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
844 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
846 M_MFHI(GET_HIGH_REG(d));
847 M_MFLO(GET_LOW_REG(d));
850 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
852 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
853 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
856 /* XXX do we need nops here? */
858 emit_store_dst(jd, iptr, d);
861 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
862 /* sx.val.l = constant */
864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 LCONST(REG_ITMP2, iptr->sx.val.l);
867 M_LMUL(s1, REG_ITMP2);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 emit_arithmetic_check(cd, iptr, s2);
884 emit_store_dst(jd, iptr, d);
887 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
890 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
891 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
892 emit_arithmetic_check(cd, iptr, s2);
897 emit_store_dst(jd, iptr, d);
900 #if SIZEOF_VOID_P == 8
902 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
906 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 emit_arithmetic_check(cd, iptr, s2);
912 emit_store_dst(jd, iptr, d);
915 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
920 emit_arithmetic_check(cd, iptr, s2);
925 emit_store_dst(jd, iptr, d);
928 #else /* SIZEOF_VOID_P == 8 */
930 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
931 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
933 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
934 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
936 /* XXX TODO: only do this if arithmetic check is really done! */
937 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
938 emit_arithmetic_check(cd, iptr, REG_ITMP3);
940 M_LNGMOVE(s1, REG_A0_A1_PACKED);
941 M_LNGMOVE(s2, REG_A2_A3_PACKED);
943 bte = iptr->sx.s23.s3.bte;
944 disp = dseg_add_functionptr(cd, bte->fp);
945 M_ALD(REG_ITMP3, REG_PV, disp);
946 M_JSR(REG_RA, REG_ITMP3);
949 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
950 M_LNGMOVE(REG_RESULT_PACKED, d);
951 emit_store_dst(jd, iptr, d);
954 #endif /* SIZEOF_VOID_P == 8 */
956 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
957 /* val.i = constant */
959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
960 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
961 #if SIZEOF_VOID_P == 8
962 M_LSRA_IMM(s1, 63, REG_ITMP2);
963 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
964 M_LADD(s1, REG_ITMP2, REG_ITMP2);
965 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
967 M_ISRA_IMM(s1, 31, REG_ITMP2);
968 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
969 M_IADD(s1, REG_ITMP2, REG_ITMP2);
970 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
972 emit_store_dst(jd, iptr, d);
975 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
976 /* val.i = constant */
978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
979 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
981 M_MOV(s1, REG_ITMP1);
984 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
985 M_AND_IMM(s1, iptr->sx.val.i, d);
988 M_ISUB(REG_ZERO, s1, d);
989 M_AND_IMM(d, iptr->sx.val.i, d);
992 ICONST(REG_ITMP2, iptr->sx.val.i);
993 M_AND(s1, REG_ITMP2, d);
996 M_ISUB(REG_ZERO, s1, d);
997 M_AND(d, REG_ITMP2, d);
999 M_ISUB(REG_ZERO, d, d);
1000 emit_store_dst(jd, iptr, d);
1003 #if SIZEOF_VOID_P == 8
1005 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1006 /* val.i = constant */
1008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1009 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1010 M_LSRA_IMM(s1, 63, REG_ITMP2);
1011 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1012 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1013 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1014 emit_store_dst(jd, iptr, d);
1017 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1018 /* val.l = constant */
1020 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1021 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1023 M_MOV(s1, REG_ITMP1);
1026 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1027 M_AND_IMM(s1, iptr->sx.val.l, d);
1030 M_LSUB(REG_ZERO, s1, d);
1031 M_AND_IMM(d, iptr->sx.val.l, d);
1034 LCONST(REG_ITMP2, iptr->sx.val.l);
1035 M_AND(s1, REG_ITMP2, d);
1038 M_LSUB(REG_ZERO, s1, d);
1039 M_AND(d, REG_ITMP2, d);
1041 M_LSUB(REG_ZERO, d, d);
1042 emit_store_dst(jd, iptr, d);
1045 #endif /* SIZEOF_VOID_P == 8 */
1047 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1053 emit_store_dst(jd, iptr, d);
1056 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1057 /* sx.val.i = constant */
1059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1061 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1062 emit_store_dst(jd, iptr, d);
1065 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1068 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1069 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1075 /* sx.val.i = constant */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1079 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1080 emit_store_dst(jd, iptr, d);
1083 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089 emit_store_dst(jd, iptr, d);
1092 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1093 /* sx.val.i = constant */
1095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1096 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1097 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1098 emit_store_dst(jd, iptr, d);
1101 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1103 #if SIZEOF_VOID_P == 8
1104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1106 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1109 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1110 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1111 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1113 M_ISLL(s2, 26, REG_ITMP1);
1114 M_BGEZ(REG_ITMP1, 3);
1117 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1119 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1122 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1124 M_BEQZ(REG_ITMP1, 4);
1125 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1127 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1128 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1129 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1132 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1135 emit_store_dst(jd, iptr, d);
1138 #if SIZEOF_VOID_P == 8
1140 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1141 /* sx.val.i = constant */
1143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1144 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1145 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1146 emit_store_dst(jd, iptr, d);
1149 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1151 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1152 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1155 emit_store_dst(jd, iptr, d);
1158 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1159 /* sx.val.i = constant */
1161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1162 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1163 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1164 emit_store_dst(jd, iptr, d);
1167 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1169 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1170 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1171 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1173 emit_store_dst(jd, iptr, d);
1176 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1177 /* sx.val.i = constant */
1179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1180 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1181 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1182 emit_store_dst(jd, iptr, d);
1185 #endif /* SIZEOF_VOID_P == 8 */
1187 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1190 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1191 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1193 emit_store_dst(jd, iptr, d);
1196 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1197 /* sx.val.i = constant */
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1201 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1202 M_AND_IMM(s1, iptr->sx.val.i, d);
1204 ICONST(REG_ITMP2, iptr->sx.val.i);
1205 M_AND(s1, REG_ITMP2, d);
1207 emit_store_dst(jd, iptr, d);
1210 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1212 #if SIZEOF_VOID_P == 8
1213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1214 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1215 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1218 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1219 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1221 M_AND(s1, s2, GET_LOW_REG(d));
1222 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1223 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1224 M_AND(s1, s2, GET_HIGH_REG(d));
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1230 /* sx.val.l = constant */
1232 #if SIZEOF_VOID_P == 8
1233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1235 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1236 M_AND_IMM(s1, iptr->sx.val.l, d);
1238 LCONST(REG_ITMP2, iptr->sx.val.l);
1239 M_AND(s1, REG_ITMP2, d);
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1243 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1244 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1245 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1246 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1249 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1250 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1251 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1252 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1253 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1261 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1262 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1263 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1269 /* sx.val.i = constant */
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1273 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1274 M_OR_IMM(s1, iptr->sx.val.i, d);
1276 ICONST(REG_ITMP2, iptr->sx.val.i);
1277 M_OR(s1, REG_ITMP2, d);
1279 emit_store_dst(jd, iptr, d);
1282 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1284 #if SIZEOF_VOID_P == 8
1285 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1286 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1287 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1290 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1291 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1293 M_OR(s1, s2, GET_LOW_REG(d));
1294 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1295 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1296 M_OR(s1, s2, GET_HIGH_REG(d));
1298 emit_store_dst(jd, iptr, d);
1301 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1302 /* sx.val.l = constant */
1304 #if SIZEOF_VOID_P == 8
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1306 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1307 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1308 M_OR_IMM(s1, iptr->sx.val.l, d);
1310 LCONST(REG_ITMP2, iptr->sx.val.l);
1311 M_OR(s1, REG_ITMP2, d);
1314 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1315 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1316 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1317 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1318 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1321 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1322 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1323 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1324 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1325 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1328 emit_store_dst(jd, iptr, d);
1331 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1334 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1335 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1337 emit_store_dst(jd, iptr, d);
1340 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1341 /* sx.val.i = constant */
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1345 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1346 M_XOR_IMM(s1, iptr->sx.val.i, d);
1348 ICONST(REG_ITMP2, iptr->sx.val.i);
1349 M_XOR(s1, REG_ITMP2, d);
1351 emit_store_dst(jd, iptr, d);
1354 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1356 #if SIZEOF_VOID_P == 8
1357 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1358 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1359 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1362 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1363 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1365 M_XOR(s1, s2, GET_LOW_REG(d));
1366 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1367 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1368 M_XOR(s1, s2, GET_HIGH_REG(d));
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1374 /* sx.val.l = constant */
1376 #if SIZEOF_VOID_P == 8
1377 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1379 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1380 M_XOR_IMM(s1, iptr->sx.val.l, d);
1382 LCONST(REG_ITMP2, iptr->sx.val.l);
1383 M_XOR(s1, REG_ITMP2, d);
1386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1387 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1388 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1389 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1390 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1393 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1394 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1395 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1396 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1397 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1400 emit_store_dst(jd, iptr, d);
1404 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1406 #if SIZEOF_VOID_P == 8
1407 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1408 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1410 M_CMPLT(s1, s2, REG_ITMP3);
1411 M_CMPLT(s2, s1, REG_ITMP1);
1412 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1414 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1415 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1416 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1417 M_CMPLT(s1, s2, REG_ITMP3);
1418 M_CMPLT(s2, s1, REG_ITMP1);
1419 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1422 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1423 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1424 M_CMPULT(s1, s2, REG_ITMP3);
1425 M_CMPULT(s2, s1, REG_ITMP1);
1426 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1428 emit_store_dst(jd, iptr, d);
1432 /* floating operations ************************************************/
1434 case ICMD_FNEG: /* ..., value ==> ..., - value */
1436 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1437 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1439 emit_store_dst(jd, iptr, d);
1442 case ICMD_DNEG: /* ..., value ==> ..., - value */
1444 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1445 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1447 emit_store_dst(jd, iptr, d);
1450 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1452 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1454 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1456 emit_store_dst(jd, iptr, d);
1459 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1461 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1462 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1465 emit_store_dst(jd, iptr, d);
1468 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1470 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1472 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1474 emit_store_dst(jd, iptr, d);
1477 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1479 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1480 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1481 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1483 emit_store_dst(jd, iptr, d);
1486 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1488 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1489 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1490 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1492 emit_store_dst(jd, iptr, d);
1495 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1497 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1498 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1499 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1501 emit_store_dst(jd, iptr, d);
1504 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1506 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1508 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1510 emit_store_dst(jd, iptr, d);
1513 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1515 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1517 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1519 emit_store_dst(jd, iptr, d);
1523 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1525 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1527 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1528 M_FDIV(s1,s2, REG_FTMP3);
1529 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1530 M_CVTLF(REG_FTMP3, REG_FTMP3);
1531 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1532 M_FSUB(s1, REG_FTMP3, d);
1533 emit_store_dst(jd, iptr, d);
1536 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1538 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1539 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1540 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1541 M_DDIV(s1,s2, REG_FTMP3);
1542 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1543 M_CVTLD(REG_FTMP3, REG_FTMP3);
1544 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1545 M_DSUB(s1, REG_FTMP3, d);
1546 emit_store_dst(jd, iptr, d);
1550 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1553 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1565 emit_store_dst(jd, iptr, d);
1569 /* XXX these do not work correctly */
1571 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1573 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1575 M_TRUNCFI(s1, REG_FTMP1);
1576 M_MOVDI(REG_FTMP1, d);
1578 emit_store_dst(jd, iptr, d);
1581 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1583 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1585 M_TRUNCDI(s1, REG_FTMP1);
1586 M_MOVDI(REG_FTMP1, d);
1588 emit_store_dst(jd, iptr, d);
1591 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1593 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1595 M_TRUNCFL(s1, REG_FTMP1);
1596 M_MOVDL(REG_FTMP1, d);
1598 emit_store_dst(jd, iptr, d);
1601 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1603 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1605 M_TRUNCDL(s1, REG_FTMP1);
1606 M_MOVDL(REG_FTMP1, d);
1608 emit_store_dst(jd, iptr, d);
1612 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1614 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1615 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1617 emit_store_dst(jd, iptr, d);
1620 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1622 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1623 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1625 emit_store_dst(jd, iptr, d);
1628 #if SUPPORT_FLOAT_CMP
1629 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1631 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1632 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1636 M_AADD_IMM(REG_ZERO, 1, d);
1640 M_ASUB_IMM(REG_ZERO, 1, d);
1641 M_CMOVT(REG_ZERO, d);
1642 emit_store_dst(jd, iptr, d);
1645 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1647 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1648 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1652 M_ASUB_IMM(REG_ZERO, 1, d);
1656 M_AADD_IMM(REG_ZERO, 1, d);
1657 M_CMOVT(REG_ZERO, d);
1658 emit_store_dst(jd, iptr, d);
1662 #if SUPPORT_DOUBLE_CMP
1663 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1665 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1666 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1670 M_AADD_IMM(REG_ZERO, 1, d);
1674 M_ASUB_IMM(REG_ZERO, 1, d);
1675 M_CMOVT(REG_ZERO, d);
1676 emit_store_dst(jd, iptr, d);
1679 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1681 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1682 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1686 M_ASUB_IMM(REG_ZERO, 1, d);
1690 M_AADD_IMM(REG_ZERO, 1, d);
1691 M_CMOVT(REG_ZERO, d);
1692 emit_store_dst(jd, iptr, d);
1697 /* memory operations **************************************************/
1699 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1703 /* implicit null-pointer check */
1704 M_ILD(d, s1, OFFSET(java_array_t, size));
1705 emit_store_dst(jd, iptr, d);
1708 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1711 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1712 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1713 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1714 M_AADD(s2, s1, REG_ITMP3);
1715 /* implicit null-pointer check */
1716 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1717 emit_store_dst(jd, iptr, d);
1720 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1725 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1726 M_AADD(s2, s1, REG_ITMP3);
1727 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1728 /* implicit null-pointer check */
1729 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1730 emit_store_dst(jd, iptr, d);
1733 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1736 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1737 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1738 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1739 M_AADD(s2, s1, REG_ITMP3);
1740 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1741 /* implicit null-pointer check */
1742 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1743 emit_store_dst(jd, iptr, d);
1746 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1751 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1752 M_ASLL_IMM(s2, 2, REG_ITMP3);
1753 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1754 /* implicit null-pointer check */
1755 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1756 emit_store_dst(jd, iptr, d);
1759 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1762 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1763 #if SIZEOF_VOID_P == 8
1764 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1768 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1769 M_ASLL_IMM(s2, 3, REG_ITMP3);
1770 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1771 /* implicit null-pointer check */
1772 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1773 emit_store_dst(jd, iptr, d);
1776 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1780 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1781 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1782 M_ASLL_IMM(s2, 2, REG_ITMP3);
1783 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1784 /* implicit null-pointer check */
1785 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1786 emit_store_dst(jd, iptr, d);
1789 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1792 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1793 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1794 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1795 M_ASLL_IMM(s2, 3, REG_ITMP3);
1796 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1797 /* implicit null-pointer check */
1798 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1799 emit_store_dst(jd, iptr, d);
1802 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1807 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1808 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1809 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1810 /* implicit null-pointer check */
1811 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1812 emit_store_dst(jd, iptr, d);
1816 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1819 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1820 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1821 M_AADD(s2, s1, REG_ITMP1);
1822 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1823 /* implicit null-pointer check */
1824 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1827 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1828 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1831 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1832 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1833 M_AADD(s2, s1, REG_ITMP1);
1834 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1835 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1836 /* implicit null-pointer check */
1837 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1840 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1843 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1844 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1845 M_ASLL_IMM(s2, 2, REG_ITMP2);
1846 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1847 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1848 /* implicit null-pointer check */
1849 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1852 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1854 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1855 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1856 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1857 M_ASLL_IMM(s2, 3, REG_ITMP2);
1858 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1859 #if SIZEOF_VOID_P == 8
1860 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1862 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1864 /* implicit null-pointer check */
1865 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1868 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1871 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1872 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1873 M_ASLL_IMM(s2, 2, REG_ITMP2);
1874 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1875 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1876 /* implicit null-pointer check */
1877 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1880 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1883 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1884 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1885 M_ASLL_IMM(s2, 3, REG_ITMP2);
1886 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1887 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1888 /* implicit null-pointer check */
1889 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1893 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1896 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1897 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1898 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1900 M_INTMOVE(s1, REG_A0);
1901 M_INTMOVE(s3, REG_A1);
1902 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1903 M_ALD(REG_ITMP3, REG_PV, disp);
1904 M_JSR(REG_RA, REG_ITMP3);
1906 emit_arraystore_check(cd, iptr);
1908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1909 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1910 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1911 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1912 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1913 /* implicit null-pointer check */
1914 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1918 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1921 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1922 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1923 M_AADD(s2, s1, REG_ITMP1);
1924 /* implicit null-pointer check */
1925 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1928 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1929 case ICMD_SASTORECONST: /* ..., 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 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1936 /* implicit null-pointer check */
1937 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1940 case ICMD_IASTORECONST: /* ..., 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_ASLL_IMM(s2, 2, REG_ITMP2);
1946 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1947 /* implicit null-pointer check */
1948 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1951 case ICMD_LASTORECONST: /* ..., 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, 3, REG_ITMP2);
1957 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1958 /* implicit null-pointer check */
1959 #if SIZEOF_VOID_P == 8
1960 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1962 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1966 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1969 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1970 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1971 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1972 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1973 /* implicit null-pointer check */
1974 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1978 case ICMD_GETSTATIC: /* ... ==> ..., value */
1980 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1981 uf = iptr->sx.s23.s3.uf;
1982 fieldtype = uf->fieldref->parseddesc.fd->type;
1983 disp = dseg_add_unique_address(cd, uf);
1985 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1988 fi = iptr->sx.s23.s3.fmiref->p.field;
1989 fieldtype = fi->type;
1990 disp = dseg_add_address(cd, fi->value);
1992 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1993 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1997 M_ALD(REG_ITMP1, REG_PV, disp);
1999 switch (fieldtype) {
2001 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2002 M_ILD_INTERN(d, REG_ITMP1, 0);
2005 #if SIZEOF_VOID_P == 8
2006 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2008 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2010 M_LLD_INTERN(d, REG_ITMP1, 0);
2013 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2014 M_ALD_INTERN(d, REG_ITMP1, 0);
2017 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2018 M_FLD_INTERN(d, REG_ITMP1, 0);
2021 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2022 M_DLD_INTERN(d, REG_ITMP1, 0);
2025 emit_store_dst(jd, iptr, d);
2028 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2030 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2031 uf = iptr->sx.s23.s3.uf;
2032 fieldtype = uf->fieldref->parseddesc.fd->type;
2033 disp = dseg_add_unique_address(cd, uf);
2035 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2038 fi = iptr->sx.s23.s3.fmiref->p.field;
2039 fieldtype = fi->type;
2040 disp = dseg_add_address(cd, fi->value);
2042 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2043 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2047 M_ALD(REG_ITMP1, REG_PV, disp);
2049 switch (fieldtype) {
2051 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2052 M_IST_INTERN(s1, REG_ITMP1, 0);
2055 #if SIZEOF_VOID_P == 8
2056 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2060 M_LST_INTERN(s1, REG_ITMP1, 0);
2063 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2064 M_AST_INTERN(s1, REG_ITMP1, 0);
2067 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2068 M_FST_INTERN(s1, REG_ITMP1, 0);
2071 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2072 M_DST_INTERN(s1, REG_ITMP1, 0);
2077 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2079 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2080 uf = iptr->sx.s23.s3.uf;
2081 fieldtype = uf->fieldref->parseddesc.fd->type;
2082 disp = dseg_add_unique_address(cd, uf);
2084 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2087 fi = iptr->sx.s23.s3.fmiref->p.field;
2088 fieldtype = fi->type;
2089 disp = dseg_add_address(cd, fi->value);
2091 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2092 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2096 M_ALD(REG_ITMP1, REG_PV, disp);
2098 switch (fieldtype) {
2100 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2103 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2106 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2109 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2112 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2118 case ICMD_GETFIELD: /* ... ==> ..., value */
2120 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2121 emit_nullpointer_check(cd, iptr, s1);
2123 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2124 uf = iptr->sx.s23.s3.uf;
2125 fieldtype = uf->fieldref->parseddesc.fd->type;
2128 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2131 fi = iptr->sx.s23.s3.fmiref->p.field;
2132 fieldtype = fi->type;
2136 switch (fieldtype) {
2138 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2142 #if SIZEOF_VOID_P == 8
2143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2147 M_LLD_GETFIELD(d, s1, disp);
2151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2159 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2163 emit_store_dst(jd, iptr, d);
2166 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2169 emit_nullpointer_check(cd, iptr, s1);
2171 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2172 uf = iptr->sx.s23.s3.uf;
2173 fieldtype = uf->fieldref->parseddesc.fd->type;
2177 fi = iptr->sx.s23.s3.fmiref->p.field;
2178 fieldtype = fi->type;
2182 #if SIZEOF_VOID_P == 8
2183 if (IS_INT_LNG_TYPE(fieldtype))
2184 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2186 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2188 if (IS_INT_LNG_TYPE(fieldtype)) {
2189 if (IS_2_WORD_TYPE(fieldtype))
2190 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2192 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2195 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2198 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2199 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2201 switch (fieldtype) {
2203 M_IST(s2, s1, disp);
2206 M_LST(s2, s1, disp);
2209 M_AST(s2, s1, disp);
2212 M_FST(s2, s1, disp);
2215 M_DST(s2, s1, disp);
2220 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2223 emit_nullpointer_check(cd, iptr, s1);
2225 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2226 uf = iptr->sx.s23.s3.uf;
2227 fieldtype = uf->fieldref->parseddesc.fd->type;
2230 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2233 fi = iptr->sx.s23.s3.fmiref->p.field;
2234 fieldtype = fi->type;
2238 switch (fieldtype) {
2240 M_IST(REG_ZERO, s1, disp);
2243 M_LST(REG_ZERO, s1, disp);
2246 M_AST(REG_ZERO, s1, disp);
2249 M_FST(REG_ZERO, s1, disp);
2252 M_DST(REG_ZERO, s1, disp);
2258 /* branch operations **************************************************/
2260 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2263 M_INTMOVE(s1, REG_ITMP1_XPTR);
2265 #ifdef ENABLE_VERIFIER
2266 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2267 uc = iptr->sx.s23.s2.uc;
2269 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2271 #endif /* ENABLE_VERIFIER */
2273 disp = dseg_add_functionptr(cd, asm_handle_exception);
2274 M_ALD(REG_ITMP2, REG_PV, disp);
2275 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2277 M_NOP; /* nop ensures that XPC is less than the end */
2278 /* of basic block */
2282 case ICMD_GOTO: /* ... ==> ... */
2283 case ICMD_RET: /* ... ==> ... */
2285 emit_br(cd, iptr->dst.block);
2289 case ICMD_JSR: /* ... ==> ... */
2291 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2295 case ICMD_IFNULL: /* ..., value ==> ... */
2296 case ICMD_IFNONNULL:
2298 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2299 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2302 case ICMD_IFEQ: /* ..., value ==> ... */
2304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2305 if (iptr->sx.val.i == 0)
2306 emit_beqz(cd, iptr->dst.block, s1);
2308 ICONST(REG_ITMP2, iptr->sx.val.i);
2309 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2313 case ICMD_IFLT: /* ..., value ==> ... */
2315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2316 if (iptr->sx.val.i == 0)
2317 emit_bltz(cd, iptr->dst.block, s1);
2319 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2320 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2322 ICONST(REG_ITMP2, iptr->sx.val.i);
2323 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2325 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2329 case ICMD_IFLE: /* ..., value ==> ... */
2331 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2332 if (iptr->sx.val.i == 0)
2333 emit_blez(cd, iptr->dst.block, s1);
2335 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2336 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2337 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2340 ICONST(REG_ITMP2, iptr->sx.val.i);
2341 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2342 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2347 case ICMD_IFNE: /* ..., value ==> ... */
2349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2350 if (iptr->sx.val.i == 0)
2351 emit_bnez(cd, iptr->dst.block, s1);
2353 ICONST(REG_ITMP2, iptr->sx.val.i);
2354 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2358 case ICMD_IFGT: /* ..., value ==> ... */
2360 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2361 if (iptr->sx.val.i == 0)
2362 emit_bgtz(cd, iptr->dst.block, s1);
2364 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2365 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2366 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2369 ICONST(REG_ITMP2, iptr->sx.val.i);
2370 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2371 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2376 case ICMD_IFGE: /* ..., value ==> ... */
2378 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2379 if (iptr->sx.val.i == 0)
2380 emit_bgez(cd, iptr->dst.block, s1);
2382 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2383 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2385 ICONST(REG_ITMP2, iptr->sx.val.i);
2386 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2388 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2392 case ICMD_IF_LEQ: /* ..., value ==> ... */
2394 #if SIZEOF_VOID_P == 8
2395 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2396 if (iptr->sx.val.l == 0)
2397 emit_beqz(cd, iptr->dst.block, s1);
2399 LCONST(REG_ITMP2, iptr->sx.val.l);
2400 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2403 if (iptr->sx.val.l == 0) {
2404 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2405 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2406 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2409 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2410 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2411 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2412 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2413 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2414 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2415 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2416 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2421 case ICMD_IF_LLT: /* ..., value ==> ... */
2423 #if SIZEOF_VOID_P == 8
2424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2425 if (iptr->sx.val.l == 0)
2426 emit_bltz(cd, iptr->dst.block, s1);
2428 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2429 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2431 LCONST(REG_ITMP2, iptr->sx.val.l);
2432 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2434 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2437 if (iptr->sx.val.l == 0) {
2438 /* if high word is less than zero, the whole long is too */
2439 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2440 emit_bltz(cd, iptr->dst.block, s1);
2443 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2444 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2445 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2446 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2447 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2448 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2450 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2451 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2452 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2457 case ICMD_IF_LLE: /* ..., value ==> ... */
2459 #if SIZEOF_VOID_P == 8
2460 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2461 if (iptr->sx.val.l == 0)
2462 emit_blez(cd, iptr->dst.block, s1);
2464 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2465 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2466 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2469 LCONST(REG_ITMP2, iptr->sx.val.l);
2470 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2471 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2475 if (iptr->sx.val.l == 0) {
2476 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2477 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2479 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2480 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2483 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2484 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2485 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2486 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2487 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2488 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2490 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2491 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2492 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2497 case ICMD_IF_LNE: /* ..., value ==> ... */
2499 #if SIZEOF_VOID_P == 8
2500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2501 if (iptr->sx.val.l == 0)
2502 emit_bnez(cd, iptr->dst.block, s1);
2504 LCONST(REG_ITMP2, iptr->sx.val.l);
2505 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2508 if (iptr->sx.val.l == 0) {
2509 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2510 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2511 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2514 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2515 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2516 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2517 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2518 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2519 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2520 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2521 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2526 case ICMD_IF_LGT: /* ..., value ==> ... */
2528 #if SIZEOF_VOID_P == 8
2529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2530 if (iptr->sx.val.l == 0)
2531 emit_bgtz(cd, iptr->dst.block, s1);
2533 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2534 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2535 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2538 LCONST(REG_ITMP2, iptr->sx.val.l);
2539 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2540 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2544 if (iptr->sx.val.l == 0) {
2545 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2546 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2547 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2549 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2552 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2553 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2554 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2555 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2556 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2557 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2559 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2560 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2561 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2566 case ICMD_IF_LGE: /* ..., value ==> ... */
2568 #if SIZEOF_VOID_P == 8
2569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2570 if (iptr->sx.val.l == 0)
2571 emit_bgez(cd, iptr->dst.block, s1);
2573 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2574 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2577 LCONST(REG_ITMP2, iptr->sx.val.l);
2578 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2580 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2583 if (iptr->sx.val.l == 0) {
2584 /* if high word is greater equal zero, the whole long is too */
2585 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2586 emit_bgez(cd, iptr->dst.block, s1);
2589 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2590 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2591 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2592 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2593 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2594 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2596 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2597 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2598 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2603 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2604 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2605 #if SIZEOF_VOID_P == 8
2606 case ICMD_IF_LCMPEQ:
2609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2610 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2611 emit_beq(cd, iptr->dst.block, s1, s2);
2614 #if SIZEOF_VOID_P == 4
2615 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2616 /* op1 = target JavaVM pc */
2618 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2619 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2620 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2622 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2623 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2624 emit_beq(cd, iptr->dst.block, s1, s2);
2628 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2629 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2630 #if SIZEOF_VOID_P == 8
2631 case ICMD_IF_LCMPNE:
2634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2635 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2636 emit_bne(cd, iptr->dst.block, s1, s2);
2639 #if SIZEOF_VOID_P == 4
2640 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2642 /* TODO: could be optimized (XOR or SUB) */
2643 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2644 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2645 emit_bne(cd, iptr->dst.block, s1, s2);
2646 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2647 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2648 emit_bne(cd, iptr->dst.block, s1, s2);
2652 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2653 #if SIZEOF_VOID_P == 8
2654 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2659 M_CMPLT(s1, s2, REG_ITMP3);
2660 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2663 #if SIZEOF_VOID_P == 4
2664 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2666 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2667 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2668 M_CMPLT(s1, s2, REG_ITMP3);
2669 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2670 M_CMPGT(s1, s2, REG_ITMP3);
2671 /* load low-bits before the branch, so we know the distance */
2672 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2673 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2674 M_BNEZ(REG_ITMP3, 4); /* XXX */
2676 M_CMPULT(s1, s2, REG_ITMP3);
2677 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2681 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2682 #if SIZEOF_VOID_P == 8
2683 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2688 M_CMPGT(s1, s2, REG_ITMP3);
2689 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2692 #if SIZEOF_VOID_P == 4
2693 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2695 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2696 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2697 M_CMPGT(s1, s2, REG_ITMP3);
2698 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2699 M_CMPLT(s1, s2, REG_ITMP3);
2700 /* load low-bits before the branch, so we know the distance */
2701 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2702 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2703 M_BNEZ(REG_ITMP3, 4); /* XXX */
2705 M_CMPUGT(s1, s2, REG_ITMP3);
2706 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2710 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2711 #if SIZEOF_VOID_P == 8
2712 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2716 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2717 M_CMPGT(s1, s2, REG_ITMP3);
2718 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2721 #if SIZEOF_VOID_P == 4
2722 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2724 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2725 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2726 M_CMPLT(s1, s2, REG_ITMP3);
2727 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2728 M_CMPGT(s1, s2, REG_ITMP3);
2729 /* load low-bits before the branch, so we know the distance */
2730 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2731 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2732 M_BNEZ(REG_ITMP3, 4); /* XXX */
2734 M_CMPUGT(s1, s2, REG_ITMP3);
2735 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2739 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2740 #if SIZEOF_VOID_P == 8
2741 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2745 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2746 M_CMPLT(s1, s2, REG_ITMP3);
2747 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2750 #if SIZEOF_VOID_P == 4
2751 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2753 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2754 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2755 M_CMPGT(s1, s2, REG_ITMP3);
2756 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2757 M_CMPLT(s1, s2, REG_ITMP3);
2758 /* load low-bits before the branch, so we know the distance */
2759 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2760 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2761 M_BNEZ(REG_ITMP3, 4); /* XXX */
2763 M_CMPULT(s1, s2, REG_ITMP3);
2764 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2768 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2769 #if SIZEOF_VOID_P == 8
2773 REPLACEMENT_POINT_RETURN(cd, iptr);
2774 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2775 M_INTMOVE(s1, REG_RESULT);
2776 goto nowperformreturn;
2778 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2780 REPLACEMENT_POINT_RETURN(cd, iptr);
2781 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2782 M_INTMOVE(s1, REG_RESULT);
2784 #ifdef ENABLE_VERIFIER
2785 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2786 uc = iptr->sx.s23.s2.uc;
2788 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2790 #endif /* ENABLE_VERIFIER */
2791 goto nowperformreturn;
2793 #if SIZEOF_VOID_P == 4
2794 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2796 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2797 M_LNGMOVE(s1, REG_RESULT_PACKED);
2798 goto nowperformreturn;
2801 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2802 REPLACEMENT_POINT_RETURN(cd, iptr);
2803 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2804 M_FLTMOVE(s1, REG_FRESULT);
2805 goto nowperformreturn;
2807 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2809 REPLACEMENT_POINT_RETURN(cd, iptr);
2810 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2811 M_DBLMOVE(s1, REG_FRESULT);
2812 goto nowperformreturn;
2814 case ICMD_RETURN: /* ... ==> ... */
2816 REPLACEMENT_POINT_RETURN(cd, iptr);
2822 p = cd->stackframesize;
2824 #if !defined(NDEBUG)
2825 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2826 emit_verbosecall_exit(jd);
2829 #if defined(ENABLE_THREADS)
2830 if (checksync && code_is_synchronized(code)) {
2831 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2832 M_ALD(REG_ITMP3, REG_PV, disp);
2834 /* we need to save the proper return value */
2836 switch (iptr->opc) {
2839 #if SIZEOF_VOID_P == 8
2842 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2843 M_JSR(REG_RA, REG_ITMP3);
2844 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2846 #if SIZEOF_VOID_P == 4
2848 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2849 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2850 M_JSR(REG_RA, REG_ITMP3);
2856 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2857 M_JSR(REG_RA, REG_ITMP3);
2858 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2861 M_JSR(REG_RA, REG_ITMP3);
2862 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2866 /* and now restore the proper return value */
2868 switch (iptr->opc) {
2871 #if SIZEOF_VOID_P == 8
2874 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2876 #if SIZEOF_VOID_P == 4
2878 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2883 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2889 /* restore return address */
2891 if (!code_is_leafmethod(code)) {
2892 p--; M_ALD(REG_RA, REG_SP, p * 8);
2895 /* restore saved registers */
2897 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2898 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2900 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2901 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2904 /* deallocate stack and return */
2906 if (cd->stackframesize) {
2909 disp = cd->stackframesize * 8;
2910 lo = (short) (disp);
2911 hi = (short) (((disp) - lo) >> 16);
2915 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2917 M_LUI(REG_ITMP3,hi);
2918 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2920 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2933 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2936 branch_target_t *table;
2938 table = iptr->dst.table;
2940 l = iptr->sx.s23.s2.tablelow;
2941 i = iptr->sx.s23.s3.tablehigh;
2943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2945 {M_INTMOVE(s1, REG_ITMP1);}
2946 else if (l <= 32768) {
2947 M_IADD_IMM(s1, -l, REG_ITMP1);
2950 ICONST(REG_ITMP2, l);
2951 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2954 /* number of targets */
2959 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2960 emit_beqz(cd, table[0].block, REG_ITMP2);
2962 /* build jump table top down and use address of lowest entry */
2967 dseg_add_target(cd, table->block);
2972 /* length of dataseg after last dseg_add_target is used by load */
2974 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2975 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2976 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2983 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2986 lookup_target_t *lookup;
2988 lookup = iptr->dst.lookup;
2990 i = iptr->sx.s23.s2.lookupcount;
2992 MCODECHECK((i<<2)+8);
2993 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2996 ICONST(REG_ITMP2, lookup->value);
2997 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3001 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3007 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3009 bte = iptr->sx.s23.s3.bte;
3013 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3015 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3016 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3017 case ICMD_INVOKEINTERFACE:
3019 REPLACEMENT_POINT_INVOKE(cd, iptr);
3021 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3023 um = iptr->sx.s23.s3.um;
3024 md = um->methodref->parseddesc.md;
3027 lm = iptr->sx.s23.s3.fmiref->p.method;
3029 md = lm->parseddesc;
3033 s3 = md->paramcount;
3035 MCODECHECK((s3 << 1) + 64);
3037 /* copy arguments to registers or stack location */
3039 for (s3 = s3 - 1; s3 >= 0; s3--) {
3040 var = VAR(iptr->sx.s23.s2.args[s3]);
3041 d = md->params[s3].regoff;
3043 if (var->flags & PREALLOC)
3046 if (IS_INT_LNG_TYPE(var->type)) {
3047 #if SIZEOF_VOID_P == 8
3048 if (!md->params[s3].inmemory) {
3049 s1 = emit_load(jd, iptr, var, d);
3053 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3054 M_LST(s1, REG_SP, d);
3057 if (!md->params[s3].inmemory) {
3058 s1 = emit_load(jd, iptr, var, d);
3060 if (IS_2_WORD_TYPE(var->type))
3066 if (IS_2_WORD_TYPE(var->type)) {
3067 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3068 M_LST(s1, REG_SP, d);
3071 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3072 M_IST(s1, REG_SP, d);
3078 if (!md->params[s3].inmemory) {
3079 s1 = emit_load(jd, iptr, var, d);
3080 if (IS_2_WORD_TYPE(var->type))
3086 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3087 if (IS_2_WORD_TYPE(var->type))
3088 M_DST(s1, REG_SP, d);
3090 M_FST(s1, REG_SP, d);
3095 switch (iptr->opc) {
3097 if (bte->stub == NULL) {
3098 disp = dseg_add_functionptr(cd, bte->fp);
3099 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3101 /* generate the actual call */
3103 /* TWISTI: i actually don't know the reason for using
3104 REG_ITMP3 here instead of REG_PV. */
3106 M_JSR(REG_RA, REG_ITMP3);
3110 disp = dseg_add_functionptr(cd, bte->stub);
3111 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3113 /* generate the actual call */
3115 M_JSR(REG_RA, REG_PV);
3119 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3120 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3121 M_LDA(REG_PV, REG_RA, -disp);
3124 case ICMD_INVOKESPECIAL:
3125 emit_nullpointer_check(cd, iptr, REG_A0);
3128 case ICMD_INVOKESTATIC:
3130 disp = dseg_add_unique_address(cd, um);
3132 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3136 disp = dseg_add_address(cd, lm->stubroutine);
3138 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3140 /* generate the actual call */
3142 M_JSR(REG_RA, REG_PV);
3144 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3145 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3146 M_LDA(REG_PV, REG_RA, -disp);
3149 case ICMD_INVOKEVIRTUAL:
3150 emit_nullpointer_check(cd, iptr, REG_A0);
3153 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3158 s1 = OFFSET(vftbl_t, table[0]) +
3159 sizeof(methodptr) * lm->vftblindex;
3161 /* implicit null-pointer check */
3162 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3163 M_ALD(REG_PV, REG_METHODPTR, s1);
3165 /* generate the actual call */
3167 M_JSR(REG_RA, REG_PV);
3169 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3170 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3171 M_LDA(REG_PV, REG_RA, -disp);
3174 case ICMD_INVOKEINTERFACE:
3175 emit_nullpointer_check(cd, iptr, REG_A0);
3178 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3184 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3185 sizeof(methodptr*) * lm->class->index;
3187 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3190 /* implicit null-pointer check */
3191 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3192 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3193 M_ALD(REG_PV, REG_METHODPTR, s2);
3195 /* generate the actual call */
3197 M_JSR(REG_RA, REG_PV);
3199 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3200 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3201 M_LDA(REG_PV, REG_RA, -disp);
3205 /* store return value */
3207 d = md->returntype.type;
3209 if (d != TYPE_VOID) {
3210 if (IS_INT_LNG_TYPE(d)) {
3211 #if SIZEOF_VOID_P == 8
3212 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3213 M_INTMOVE(REG_RESULT, s1);
3215 if (IS_2_WORD_TYPE(d)) {
3216 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3217 M_LNGMOVE(REG_RESULT_PACKED, s1);
3220 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3221 M_INTMOVE(REG_RESULT, s1);
3226 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3227 if (IS_2_WORD_TYPE(d))
3228 M_DMOV(REG_FRESULT, s1);
3230 M_FMOV(REG_FRESULT, s1);
3232 emit_store_dst(jd, iptr, s1);
3237 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3239 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3243 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3248 super = iptr->sx.s23.s3.c.cls;
3249 superindex = super->index;
3252 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3253 CODEGEN_CRITICAL_SECTION_NEW;
3255 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3257 /* if class is not resolved, check which code to call */
3259 if (super == NULL) {
3260 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3262 cr = iptr->sx.s23.s3.c.ref;
3263 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3265 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3268 M_ILD(REG_ITMP2, REG_PV, disp);
3269 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3270 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3273 /* interface checkcast code */
3275 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3276 if (super == NULL) {
3277 cr = iptr->sx.s23.s3.c.ref;
3279 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3283 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3286 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3287 M_ILD(REG_ITMP3, REG_ITMP2,
3288 OFFSET(vftbl_t, interfacetablelength));
3289 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3290 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3292 M_ALD(REG_ITMP3, REG_ITMP2,
3293 OFFSET(vftbl_t, interfacetable[0]) -
3294 superindex * sizeof(methodptr*));
3295 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3298 emit_label_br(cd, BRANCH_LABEL_4);
3300 emit_label(cd, BRANCH_LABEL_3);
3303 /* class checkcast code */
3305 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3306 if (super == NULL) {
3307 emit_label(cd, BRANCH_LABEL_2);
3309 cr = iptr->sx.s23.s3.c.ref;
3310 disp = dseg_add_unique_address(cd, NULL);
3312 patcher_add_patch_ref(jd,
3313 PATCHER_resolve_classref_to_vftbl,
3317 disp = dseg_add_address(cd, super->vftbl);
3319 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3322 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3323 M_ALD(REG_ITMP3, REG_PV, disp);
3325 CODEGEN_CRITICAL_SECTION_START;
3327 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3328 /* if (s1 != REG_ITMP1) { */
3329 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3330 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3331 /* #if defined(ENABLE_THREADS) */
3332 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3334 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3336 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3337 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3338 M_ALD(REG_ITMP3, REG_PV, disp);
3339 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3341 CODEGEN_CRITICAL_SECTION_END;
3344 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3345 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3348 emit_label(cd, BRANCH_LABEL_5);
3351 if (super == NULL) {
3352 emit_label(cd, BRANCH_LABEL_1);
3353 emit_label(cd, BRANCH_LABEL_4);
3356 d = codegen_reg_of_dst(jd, iptr, s1);
3359 s1 = emit_load_s1(jd, iptr, REG_A0);
3360 M_INTMOVE(s1, REG_A0);
3362 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3363 cr = iptr->sx.s23.s3.c.ref;
3364 disp = dseg_add_unique_address(cd, NULL);
3366 patcher_add_patch_ref(jd,
3367 PATCHER_resolve_classref_to_classinfo,
3371 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3374 M_ALD(REG_A1, REG_PV, disp);
3375 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3376 M_ALD(REG_ITMP3, REG_PV, disp);
3377 M_JSR(REG_RA, REG_ITMP3);
3380 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3381 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3383 d = codegen_reg_of_dst(jd, iptr, s1);
3387 emit_store_dst(jd, iptr, d);
3390 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3396 super = iptr->sx.s23.s3.c.cls;
3398 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3403 super = iptr->sx.s23.s3.c.cls;
3404 superindex = super->index;
3407 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3408 CODEGEN_CRITICAL_SECTION_NEW;
3410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3411 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3414 M_MOV(s1, REG_ITMP1);
3420 /* if class is not resolved, check which code to call */
3422 if (super == NULL) {
3423 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3425 cr = iptr->sx.s23.s3.c.ref;
3426 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3428 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3431 M_ILD(REG_ITMP3, REG_PV, disp);
3432 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3433 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3436 /* interface instanceof code */
3438 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3439 if (super == NULL) {
3440 cr = iptr->sx.s23.s3.c.ref;
3442 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3446 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3449 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3450 M_ILD(REG_ITMP3, REG_ITMP1,
3451 OFFSET(vftbl_t, interfacetablelength));
3452 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3453 M_BLEZ(REG_ITMP3, 3);
3455 M_ALD(REG_ITMP1, REG_ITMP1,
3456 OFFSET(vftbl_t, interfacetable[0]) -
3457 superindex * sizeof(methodptr*));
3458 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3461 emit_label_br(cd, BRANCH_LABEL_4);
3463 emit_label(cd, BRANCH_LABEL_3);
3466 /* class instanceof code */
3468 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3469 if (super == NULL) {
3470 emit_label(cd, BRANCH_LABEL_2);
3472 cr = iptr->sx.s23.s3.c.ref;
3473 disp = dseg_add_unique_address(cd, NULL);
3475 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3479 disp = dseg_add_address(cd, super->vftbl);
3481 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3484 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3485 M_ALD(REG_ITMP2, REG_PV, disp);
3487 CODEGEN_CRITICAL_SECTION_START;
3489 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3490 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3491 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3493 CODEGEN_CRITICAL_SECTION_END;
3495 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3496 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3500 emit_label(cd, BRANCH_LABEL_5);
3503 if (super == NULL) {
3504 emit_label(cd, BRANCH_LABEL_1);
3505 emit_label(cd, BRANCH_LABEL_4);
3508 emit_store_dst(jd, iptr, d);
3512 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3514 /* check for negative sizes and copy sizes to stack if necessary */
3516 MCODECHECK((iptr->s1.argcount << 1) + 64);
3518 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3520 var = VAR(iptr->sx.s23.s2.args[s1]);
3522 /* copy SAVEDVAR sizes to stack */
3524 if (!(var->flags & PREALLOC)) {
3525 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3526 #if SIZEOF_VOID_P == 8
3527 M_LST(s2, REG_SP, s1 * 8);
3529 M_IST(s2, REG_SP, (s1 + 2) * 8);
3534 /* a0 = dimension count */
3536 ICONST(REG_A0, iptr->s1.argcount);
3538 /* is patcher function set? */
3540 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3541 cr = iptr->sx.s23.s3.c.ref;
3542 disp = dseg_add_unique_address(cd, NULL);
3544 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3548 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3551 /* a1 = arraydescriptor */
3553 M_ALD(REG_A1, REG_PV, disp);
3555 /* a2 = pointer to dimensions = stack pointer */
3557 #if SIZEOF_VOID_P == 8
3558 M_MOV(REG_SP, REG_A2);
3560 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3563 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3564 M_ALD(REG_ITMP3, REG_PV, disp);
3565 M_JSR(REG_RA, REG_ITMP3);
3568 /* check for exception before result assignment */
3570 emit_exception_check(cd, iptr);
3572 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3573 M_INTMOVE(REG_RESULT, d);
3574 emit_store_dst(jd, iptr, d);
3578 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3583 } /* for instruction */
3585 MCODECHECK(64); /* XXX require smaller number? */
3587 /* At the end of a basic block we may have to append some nops,
3588 because the patcher stub calling code might be longer than the
3589 actual instruction. So codepatching does not change the
3590 following block unintentionally. */
3592 if (cd->mcodeptr < cd->lastmcodeptr) {
3593 while (cd->mcodeptr < cd->lastmcodeptr)
3597 } /* if (bptr -> flags >= BBREACHED) */
3598 } /* for basic block */
3600 dseg_createlinenumbertable(cd);
3602 /* generate traps */
3604 emit_patcher_traps(jd);
3606 /* everything's ok */
3612 /* codegen_emit_stub_compiler **************************************************
3614 Emits a stub routine which calls the compiler.
3616 *******************************************************************************/
3618 void codegen_emit_stub_compiler(jitdata *jd)
3623 /* get required compiler data */
3628 /* code for the stub */
3630 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3631 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3637 /* codegen_emit_stub_native ****************************************************
3639 Emits a stub routine which calls a native method.
3641 *******************************************************************************/
3643 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3654 /* get required compiler data */
3660 /* initialize variables */
3664 /* calculate stack frame size */
3666 cd->stackframesize =
3667 1 + /* return address */
3668 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3669 sizeof(localref_table) / SIZEOF_VOID_P +
3670 md->paramcount + /* for saving arguments over calls */
3671 #if SIZEOF_VOID_P == 4
3672 5 + /* additional save space (MIPS32) */
3674 1 + /* for saving return address */
3677 /* adjust stackframe size for 16-byte alignment */
3679 if (cd->stackframesize & 1)
3680 cd->stackframesize++;
3682 /* create method header */
3684 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3685 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3686 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3687 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3688 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3689 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3690 (void) dseg_addlinenumbertablesize(cd);
3691 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3693 /* generate stub code */
3695 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3696 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3698 #if !defined(NDEBUG)
3699 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3700 emit_verbosecall_enter(jd);
3703 /* save integer and float argument registers */
3705 #if SIZEOF_VOID_P == 8
3706 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3707 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3708 s1 = md->params[i].regoff;
3709 M_AST(s1, REG_SP, j * 8);
3714 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3715 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3716 if (!md->params[i].inmemory) {
3717 s1 = md->params[i].regoff;
3719 if (IS_2_WORD_TYPE(md->params[i].type))
3720 M_LST(s1, REG_SP, j * 8);
3722 M_IST(s1, REG_SP, j * 8);
3730 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3731 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3732 s1 = md->params[i].regoff;
3734 if (IS_2_WORD_TYPE(md->params[i].type))
3735 M_DST(s1, REG_SP, j * 8);
3737 M_FST(s1, REG_SP, j * 8);
3743 /* prepare data structures for native function call */
3745 M_MOV(REG_SP, REG_A0);
3746 M_MOV(REG_PV, REG_A1);
3747 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3748 M_ALD(REG_ITMP3, REG_PV, disp);
3749 M_JSR(REG_RA, REG_ITMP3);
3750 M_NOP; /* XXX fill me! */
3752 /* remember class argument */
3754 if (m->flags & ACC_STATIC)
3755 M_MOV(REG_RESULT, REG_ITMP3);
3757 /* restore integer and float argument registers */
3759 #if SIZEOF_VOID_P == 8
3760 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3761 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3762 s1 = md->params[i].regoff;
3763 M_LLD(s1, REG_SP, j * 8);
3768 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3769 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3770 if (!md->params[i].inmemory) {
3771 s1 = md->params[i].regoff;
3773 if (IS_2_WORD_TYPE(md->params[i].type))
3774 M_LLD(s1, REG_SP, j * 8);
3776 M_ILD(s1, REG_SP, j * 8);
3784 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3785 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3786 s1 = md->params[i].regoff;
3788 if (IS_2_WORD_TYPE(md->params[i].type))
3789 M_DLD(s1, REG_SP, j * 8);
3791 M_FLD(s1, REG_SP, j * 8);
3797 /* copy or spill arguments to new locations */
3799 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3800 t = md->params[i].type;
3802 if (IS_INT_LNG_TYPE(t)) {
3803 if (!md->params[i].inmemory) {
3804 s1 = md->params[i].regoff;
3805 s2 = nmd->params[j].regoff;
3807 if (!nmd->params[j].inmemory) {
3808 #if SIZEOF_VOID_P == 8
3811 if (IS_2_WORD_TYPE(t))
3818 #if SIZEOF_VOID_P == 8
3819 M_LST(s1, REG_SP, s2);
3821 if (IS_2_WORD_TYPE(t))
3822 M_LST(s1, REG_SP, s2);
3824 M_IST(s1, REG_SP, s2);
3829 s1 = md->params[i].regoff + cd->stackframesize * 8;
3830 s2 = nmd->params[j].regoff;
3832 #if SIZEOF_VOID_P == 8
3833 M_LLD(REG_ITMP1, REG_SP, s1);
3834 M_LST(REG_ITMP1, REG_SP, s2);
3836 if (IS_2_WORD_TYPE(t)) {
3837 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3838 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3841 M_ILD(REG_ITMP1, REG_SP, s1);
3842 M_IST(REG_ITMP1, REG_SP, s2);
3848 if (!md->params[i].inmemory) {
3849 s1 = md->params[i].regoff;
3850 s2 = nmd->params[j].regoff;
3852 if (!nmd->params[j].inmemory) {
3853 #if SIZEOF_VOID_P == 8
3854 if (IS_2_WORD_TYPE(t))
3859 /* On MIPS32 float arguments for native functions
3860 can never be in float argument registers, since
3861 the first argument is _always_ an integer
3862 argument (JNIEnv) */
3864 if (IS_2_WORD_TYPE(t)) {
3865 /* double high/low order is endian
3866 independent: even numbered holds low
3867 32-bits, odd numbered high 32-bits */
3869 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3870 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3877 #if SIZEOF_VOID_P == 8
3878 if (IS_2_WORD_TYPE(t))
3879 M_DST(s1, REG_SP, s2);
3881 M_FST(s1, REG_SP, s2);
3883 /* s1 may have been originally in 2 int registers,
3884 but was moved out by the native function
3885 argument(s), just get low register */
3887 if (IS_2_WORD_TYPE(t))
3888 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3890 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3895 s1 = md->params[i].regoff + cd->stackframesize * 8;
3896 s2 = nmd->params[j].regoff;
3898 #if SIZEOF_VOID_P == 8
3899 if (IS_2_WORD_TYPE(t)) {
3900 M_DLD(REG_FTMP1, REG_SP, s1);
3901 M_DST(REG_FTMP1, REG_SP, s2);
3904 M_FLD(REG_FTMP1, REG_SP, s1);
3905 M_FST(REG_FTMP1, REG_SP, s2);
3908 if (IS_2_WORD_TYPE(t)) {
3909 M_DLD(REG_FTMP1, REG_SP, s1);
3910 M_DST(REG_FTMP1, REG_SP, s2);
3913 M_FLD(REG_FTMP1, REG_SP, s1);
3914 M_FST(REG_FTMP1, REG_SP, s2);
3921 /* Handle native Java methods. */
3923 if (m->flags & ACC_NATIVE) {
3924 /* put class into second argument register */
3926 if (m->flags & ACC_STATIC)
3927 M_MOV(REG_ITMP3, REG_A1);
3929 /* put env into first argument register */
3931 disp = dseg_add_address(cd, _Jv_env);
3932 M_ALD(REG_A0, REG_PV, disp);
3935 /* Call the native function. */
3937 disp = dseg_add_functionptr(cd, f);
3938 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3939 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3940 M_NOP; /* delay slot */
3942 /* save return value */
3944 switch (md->returntype.type) {
3945 #if SIZEOF_VOID_P == 8
3949 M_LST(REG_RESULT, REG_SP, 0 * 8);
3953 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3958 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3961 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3965 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3972 #if !defined(NDEBUG)
3973 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3974 emit_verbosecall_exit(jd);
3977 /* remove native stackframe info */
3979 M_MOV(REG_SP, REG_A0);
3980 M_MOV(REG_PV, REG_A1);
3981 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3982 M_ALD(REG_ITMP3, REG_PV, disp);
3983 M_JSR(REG_RA, REG_ITMP3);
3984 M_NOP; /* XXX fill me! */
3985 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3987 /* restore return value */
3989 switch (md->returntype.type) {
3990 #if SIZEOF_VOID_P == 8
3994 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3998 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4003 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
4006 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
4010 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4017 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4019 /* check for exception */
4021 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4022 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4024 M_RET(REG_RA); /* return to caller */
4025 M_NOP; /* DELAY SLOT */
4027 /* handle exception */
4029 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4030 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4031 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4032 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4034 /* Generate patcher traps. */
4036 emit_patcher_traps(jd);
4041 * These are local overrides for various environment variables in Emacs.
4042 * Please do not remove this and leave it at the end of the file, where
4043 * Emacs will automagically detect them.
4044 * ---------------------------------------------------------------------
4047 * indent-tabs-mode: t
4051 * vim:noexpandtab:sw=4:ts=4: