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 /* IsSync contains the offset relative to the stack pointer for the
154 argument of monitor_exit used in the exception handler. Since the
155 offset could be zero and give a wrong meaning of the flag it is
158 /* XXX Remove this "offset by one". */
160 code->synchronizedoffset = (rd->memuse + 1) * 8;
162 /* REMOVEME dummy IsSync */
163 (void) dseg_add_unique_s4(cd, 0);
165 /* REMOVEME: We still need it for exception handling in assembler. */
167 if (code_is_leafmethod(code))
168 (void) dseg_add_unique_s4(cd, 1);
170 (void) dseg_add_unique_s4(cd, 0);
172 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
173 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
174 dseg_addlinenumbertablesize(cd);
175 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
177 /* create exception table */
179 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
180 dseg_add_target(cd, ex->start);
181 dseg_add_target(cd, ex->end);
182 dseg_add_target(cd, ex->handler);
183 (void) dseg_add_unique_address(cd, ex->catchtype.any);
186 /* create stack frame (if necessary) */
188 if (cd->stackframesize)
189 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
191 /* save return address and used callee saved registers */
193 p = cd->stackframesize;
194 if (!code_is_leafmethod(code)) {
195 p--; M_AST(REG_RA, REG_SP, p * 8);
197 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
198 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
200 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
201 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
204 /* take arguments out of register or stack frame */
208 for (p = 0, l = 0; p < md->paramcount; p++) {
209 t = md->paramtypes[p].type;
211 varindex = jd->local_map[l * 5 + t];
214 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
217 if (varindex == UNUSED)
221 s1 = md->params[p].regoff;
223 if (IS_INT_LNG_TYPE(t)) { /* integer args */
224 if (!md->params[p].inmemory) { /* register arguments */
225 #if SIZEOF_VOID_P == 8
226 if (!(var->flags & INMEMORY))
227 M_INTMOVE(s1, var->vv.regoff);
229 M_LST(s1, REG_SP, var->vv.regoff);
231 if (!(var->flags & INMEMORY)) {
232 if (IS_2_WORD_TYPE(t))
233 M_LNGMOVE(s1, var->vv.regoff);
235 M_INTMOVE(s1, var->vv.regoff);
238 if (IS_2_WORD_TYPE(t))
239 M_LST(s1, REG_SP, var->vv.regoff);
241 M_IST(s1, REG_SP, var->vv.regoff);
245 else { /* stack arguments */
246 if (!(var->flags & INMEMORY)) {
247 #if SIZEOF_VOID_P == 8
248 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
250 if (IS_2_WORD_TYPE(t))
251 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
253 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
257 var->vv.regoff = cd->stackframesize * 8 + s1;
260 else { /* floating args */
261 if (!md->params[p].inmemory) {
262 if (!(var->flags & INMEMORY)) {
263 if (IS_2_WORD_TYPE(t))
264 M_DBLMOVE(s1, var->vv.regoff);
266 M_FLTMOVE(s1, var->vv.regoff);
269 if (IS_2_WORD_TYPE(t))
270 M_DST(s1, REG_SP, var->vv.regoff);
272 M_FST(s1, REG_SP, var->vv.regoff);
276 if (!(var->flags & INMEMORY)) {
277 if (IS_2_WORD_TYPE(t))
278 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
280 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
283 var->vv.regoff = cd->stackframesize * 8 + s1;
288 /* call monitorenter function */
290 #if defined(ENABLE_THREADS)
291 if (checksync && code_is_synchronized(code)) {
292 /* stack offset for monitor argument */
296 # if !defined(NDEBUG)
297 if (opt_verbosecall) {
298 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
300 for (p = 0; p < INT_ARG_CNT; p++)
301 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
303 for (p = 0; p < FLT_ARG_CNT; p++)
304 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
306 s1 += INT_ARG_CNT + FLT_ARG_CNT;
310 /* get correct lock object */
312 if (m->flags & ACC_STATIC) {
313 disp = dseg_add_address(cd, &m->class->object.header);
314 M_ALD(REG_A0, REG_PV, disp);
315 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
316 M_ALD(REG_ITMP3, REG_PV, disp);
319 /* emit_nullpointer_check(cd, iptr, REG_A0); */
321 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
322 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
323 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
326 M_JSR(REG_RA, REG_ITMP3);
327 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
329 # if !defined(NDEBUG)
330 if (opt_verbosecall) {
331 for (p = 0; p < INT_ARG_CNT; p++)
332 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
334 for (p = 0; p < FLT_ARG_CNT; p++)
335 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
338 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
346 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
347 emit_verbosecall_enter(jd);
350 /* end of header generation */
352 /* create replacement points */
354 REPLACEMENT_POINTS_INIT(cd, jd);
356 /* walk through all basic blocks */
358 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
360 /* handle replacement points */
362 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
364 /* store relative start of block */
366 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
368 if (bptr->flags >= BBREACHED) {
369 /* branch resolving */
371 codegen_resolve_branchrefs(cd, bptr);
373 /* copy interface registers to their destination */
377 #if defined(ENABLE_LSRA)
381 src = bptr->invars[len];
382 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
383 /* d = reg_of_var(m, src, REG_ITMP1); */
384 if (!(src->flags & INMEMORY))
388 M_INTMOVE(REG_ITMP1, d);
389 emit_store(jd, NULL, src, d);
396 var = VAR(bptr->invars[len]);
397 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
398 d = codegen_reg_of_var(0, var, REG_ITMP1);
399 M_INTMOVE(REG_ITMP1, d);
400 emit_store(jd, NULL, var, d);
403 assert((var->flags & INOUT));
406 #if defined(ENABLE_LSRA)
409 /* walk through all instructions */
412 /* currentline = 0; */
414 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
415 if (iptr->line != currentline) {
416 dseg_addlinenumber(cd, iptr->line);
417 currentline = iptr->line;
420 MCODECHECK(64); /* an instruction usually needs < 64 words */
424 case ICMD_NOP: /* ... ==> ... */
425 case ICMD_POP: /* ..., value ==> ... */
426 case ICMD_POP2: /* ..., value, value ==> ... */
429 case ICMD_INLINE_START:
431 REPLACEMENT_POINT_INLINE_START(cd, iptr);
434 case ICMD_INLINE_BODY:
436 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
437 dseg_addlinenumber_inline_start(cd, iptr);
438 dseg_addlinenumber(cd, iptr->line);
441 case ICMD_INLINE_END:
443 dseg_addlinenumber_inline_end(cd, iptr);
444 dseg_addlinenumber(cd, iptr->line);
447 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
450 emit_nullpointer_check(cd, iptr, s1);
453 /* constant operations ************************************************/
455 case ICMD_ICONST: /* ... ==> ..., constant */
457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
458 ICONST(d, iptr->sx.val.i);
459 emit_store_dst(jd, iptr, d);
462 case ICMD_LCONST: /* ... ==> ..., constant */
464 #if SIZEOF_VOID_P == 8
465 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
469 LCONST(d, iptr->sx.val.l);
470 emit_store_dst(jd, iptr, d);
473 case ICMD_FCONST: /* ... ==> ..., constant */
475 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
476 disp = dseg_add_float(cd, iptr->sx.val.f);
477 M_FLD(d, REG_PV, disp);
478 emit_store_dst(jd, iptr, d);
481 case ICMD_DCONST: /* ... ==> ..., constant */
483 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
484 disp = dseg_add_double(cd, iptr->sx.val.d);
485 M_DLD(d, REG_PV, disp);
486 emit_store_dst(jd, iptr, d);
489 case ICMD_ACONST: /* ... ==> ..., constant */
491 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
493 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
494 cr = iptr->sx.val.c.ref;
495 disp = dseg_add_unique_address(cd, cr);
497 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
500 M_ALD(d, REG_PV, disp);
503 if (iptr->sx.val.anyptr == NULL)
504 M_INTMOVE(REG_ZERO, d);
506 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
507 M_ALD(d, REG_PV, disp);
510 emit_store_dst(jd, iptr, d);
514 /* load/store/copy/move operations ************************************/
516 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
521 case ICMD_ISTORE: /* ..., value ==> ... */
532 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
537 /* integer operations *************************************************/
539 case ICMD_INEG: /* ..., value ==> ..., - value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543 M_ISUB(REG_ZERO, s1, d);
544 emit_store_dst(jd, iptr, d);
547 case ICMD_LNEG: /* ..., value ==> ..., - value */
549 #if SIZEOF_VOID_P == 8
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552 M_LSUB(REG_ZERO, s1, d);
554 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
556 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
557 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
558 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
559 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
561 emit_store_dst(jd, iptr, d);
564 case ICMD_I2L: /* ..., value ==> ..., value */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 #if SIZEOF_VOID_P == 8
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
572 M_INTMOVE(s1, GET_LOW_REG(d));
573 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
575 emit_store_dst(jd, iptr, d);
578 case ICMD_L2I: /* ..., value ==> ..., value */
580 #if SIZEOF_VOID_P == 8
581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
583 M_ISLL_IMM(s1, 0, d);
585 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 M_INTMOVE(GET_LOW_REG(s1), d);
589 emit_store_dst(jd, iptr, d);
592 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596 #if SIZEOF_VOID_P == 8
597 M_LSLL_IMM(s1, 56, d);
598 M_LSRA_IMM( d, 56, d);
600 M_ISLL_IMM(s1, 24, d);
601 M_ISRA_IMM( d, 24, d);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610 M_AND_IMM(s1, 0xffff, d);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618 #if SIZEOF_VOID_P == 8
619 M_LSLL_IMM(s1, 48, d);
620 M_LSRA_IMM( d, 48, d);
622 M_ISLL_IMM(s1, 16, d);
623 M_ISRA_IMM( d, 16, d);
625 emit_store_dst(jd, iptr, d);
629 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
635 emit_store_dst(jd, iptr, d);
639 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
640 /* sx.val.i = constant */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
645 M_IADD_IMM(s1, iptr->sx.val.i, d);
647 ICONST(REG_ITMP2, iptr->sx.val.i);
648 M_IADD(s1, REG_ITMP2, d);
650 emit_store_dst(jd, iptr, d);
653 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
655 #if SIZEOF_VOID_P == 8
656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
662 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
664 M_IADD(s1, s2, GET_HIGH_REG(d));
665 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
666 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
667 if (s1 == GET_LOW_REG(d)) {
668 M_MOV(s1, REG_ITMP3);
671 M_IADD(s1, s2, GET_LOW_REG(d));
672 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
673 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
675 emit_store_dst(jd, iptr, d);
678 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
679 /* sx.val.l = constant */
681 #if SIZEOF_VOID_P == 8
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
685 M_LADD_IMM(s1, iptr->sx.val.l, d);
687 LCONST(REG_ITMP2, iptr->sx.val.l);
688 M_LADD(s1, REG_ITMP2, d);
691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
692 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
693 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
694 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
695 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
696 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
698 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
699 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
700 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
701 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
702 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
703 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
704 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
707 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
708 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
709 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
710 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
711 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
712 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
713 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
714 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
717 emit_store_dst(jd, iptr, d);
720 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
726 emit_store_dst(jd, iptr, d);
729 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
730 /* sx.val.i = constant */
732 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
734 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
735 M_IADD_IMM(s1, -iptr->sx.val.i, d);
737 ICONST(REG_ITMP2, iptr->sx.val.i);
738 M_ISUB(s1, REG_ITMP2, d);
740 emit_store_dst(jd, iptr, d);
743 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
745 #if SIZEOF_VOID_P == 8
746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
747 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
748 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
751 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
752 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
754 M_ISUB(s1, s2, GET_HIGH_REG(d));
755 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
756 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
757 M_CMPULT(s1, s2, REG_ITMP3);
758 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
759 /* if s1 is equal to REG_ITMP3 we have to reload it, since
760 the CMPULT instruction destroyed it */
762 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
763 M_ISUB(s1, s2, GET_LOW_REG(d));
766 emit_store_dst(jd, iptr, d);
769 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
770 /* sx.val.l = constant */
772 #if SIZEOF_VOID_P == 8
773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
775 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
776 M_LADD_IMM(s1, -iptr->sx.val.l, d);
778 LCONST(REG_ITMP2, iptr->sx.val.l);
779 M_LSUB(s1, REG_ITMP2, d);
782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
783 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
784 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
785 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
786 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
787 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
788 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
789 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
791 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
792 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
793 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
794 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
795 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
798 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
799 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
800 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
801 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
802 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
803 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
804 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
805 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
808 emit_store_dst(jd, iptr, d);
811 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
813 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
814 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
820 emit_store_dst(jd, iptr, d);
823 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
824 /* sx.val.i = constant */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 ICONST(REG_ITMP2, iptr->sx.val.i);
829 M_IMUL(s1, REG_ITMP2);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
838 #if SIZEOF_VOID_P == 8
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
847 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
854 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
856 M_MFHI(GET_HIGH_REG(d));
857 M_MFLO(GET_LOW_REG(d));
860 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
862 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
863 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
866 /* XXX do we need nops here? */
868 emit_store_dst(jd, iptr, d);
871 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
872 /* sx.val.l = constant */
874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 LCONST(REG_ITMP2, iptr->sx.val.l);
877 M_LMUL(s1, REG_ITMP2);
881 emit_store_dst(jd, iptr, d);
884 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889 emit_arithmetic_check(cd, iptr, s2);
894 emit_store_dst(jd, iptr, d);
897 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
899 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
900 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
901 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
902 emit_arithmetic_check(cd, iptr, s2);
907 emit_store_dst(jd, iptr, d);
910 #if SIZEOF_VOID_P == 8
912 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
915 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
916 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
917 emit_arithmetic_check(cd, iptr, s2);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
928 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
929 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
930 emit_arithmetic_check(cd, iptr, s2);
935 emit_store_dst(jd, iptr, d);
938 #else /* SIZEOF_VOID_P == 8 */
940 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
941 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
943 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
944 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
946 /* XXX TODO: only do this if arithmetic check is really done! */
947 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
948 emit_arithmetic_check(cd, iptr, REG_ITMP3);
950 M_LNGMOVE(s1, REG_A0_A1_PACKED);
951 M_LNGMOVE(s2, REG_A2_A3_PACKED);
953 bte = iptr->sx.s23.s3.bte;
954 disp = dseg_add_functionptr(cd, bte->fp);
955 M_ALD(REG_ITMP3, REG_PV, disp);
956 M_JSR(REG_RA, REG_ITMP3);
959 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
960 M_LNGMOVE(REG_RESULT_PACKED, d);
961 emit_store_dst(jd, iptr, d);
964 #endif /* SIZEOF_VOID_P == 8 */
966 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
967 /* val.i = constant */
969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
970 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
971 #if SIZEOF_VOID_P == 8
972 M_LSRA_IMM(s1, 63, REG_ITMP2);
973 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
974 M_LADD(s1, REG_ITMP2, REG_ITMP2);
975 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
977 M_ISRA_IMM(s1, 31, REG_ITMP2);
978 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
979 M_IADD(s1, REG_ITMP2, REG_ITMP2);
980 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
982 emit_store_dst(jd, iptr, d);
985 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
986 /* val.i = constant */
988 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
989 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
991 M_MOV(s1, REG_ITMP1);
994 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
995 M_AND_IMM(s1, iptr->sx.val.i, d);
998 M_ISUB(REG_ZERO, s1, d);
999 M_AND_IMM(d, iptr->sx.val.i, d);
1002 ICONST(REG_ITMP2, iptr->sx.val.i);
1003 M_AND(s1, REG_ITMP2, d);
1006 M_ISUB(REG_ZERO, s1, d);
1007 M_AND(d, REG_ITMP2, d);
1009 M_ISUB(REG_ZERO, d, d);
1010 emit_store_dst(jd, iptr, d);
1013 #if SIZEOF_VOID_P == 8
1015 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1016 /* val.i = constant */
1018 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1019 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1020 M_LSRA_IMM(s1, 63, REG_ITMP2);
1021 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1022 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1023 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1024 emit_store_dst(jd, iptr, d);
1027 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1028 /* val.l = constant */
1030 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1031 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1033 M_MOV(s1, REG_ITMP1);
1036 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1037 M_AND_IMM(s1, iptr->sx.val.l, d);
1040 M_LSUB(REG_ZERO, s1, d);
1041 M_AND_IMM(d, iptr->sx.val.l, d);
1044 LCONST(REG_ITMP2, iptr->sx.val.l);
1045 M_AND(s1, REG_ITMP2, d);
1048 M_LSUB(REG_ZERO, s1, d);
1049 M_AND(d, REG_ITMP2, d);
1051 M_LSUB(REG_ZERO, d, d);
1052 emit_store_dst(jd, iptr, d);
1055 #endif /* SIZEOF_VOID_P == 8 */
1057 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1060 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1063 emit_store_dst(jd, iptr, d);
1066 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1067 /* sx.val.i = constant */
1069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1070 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1081 emit_store_dst(jd, iptr, d);
1084 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1085 /* sx.val.i = constant */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1090 emit_store_dst(jd, iptr, d);
1093 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1096 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1097 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1099 emit_store_dst(jd, iptr, d);
1102 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1103 /* sx.val.i = constant */
1105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1106 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1107 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1113 #if SIZEOF_VOID_P == 8
1114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1115 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1116 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1120 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1121 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1123 M_ISLL(s2, 26, REG_ITMP1);
1124 M_BGEZ(REG_ITMP1, 3);
1127 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1129 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1132 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1134 M_BEQZ(REG_ITMP1, 4);
1135 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1137 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1138 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1139 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1142 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1145 emit_store_dst(jd, iptr, d);
1148 #if SIZEOF_VOID_P == 8
1150 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1151 /* sx.val.i = constant */
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1155 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1162 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1163 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1165 emit_store_dst(jd, iptr, d);
1168 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1169 /* sx.val.i = constant */
1171 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1172 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1173 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1180 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1183 emit_store_dst(jd, iptr, d);
1186 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1187 /* sx.val.i = constant */
1189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1190 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1191 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1192 emit_store_dst(jd, iptr, d);
1195 #endif /* SIZEOF_VOID_P == 8 */
1197 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1201 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1207 /* sx.val.i = constant */
1209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1210 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1211 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1212 M_AND_IMM(s1, iptr->sx.val.i, d);
1214 ICONST(REG_ITMP2, iptr->sx.val.i);
1215 M_AND(s1, REG_ITMP2, d);
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1222 #if SIZEOF_VOID_P == 8
1223 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1224 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1225 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1228 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1229 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1231 M_AND(s1, s2, GET_LOW_REG(d));
1232 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1233 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1234 M_AND(s1, s2, GET_HIGH_REG(d));
1236 emit_store_dst(jd, iptr, d);
1239 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1240 /* sx.val.l = constant */
1242 #if SIZEOF_VOID_P == 8
1243 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1244 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1245 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1246 M_AND_IMM(s1, iptr->sx.val.l, d);
1248 LCONST(REG_ITMP2, iptr->sx.val.l);
1249 M_AND(s1, REG_ITMP2, d);
1252 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1253 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1254 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1255 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1256 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1259 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1260 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1261 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1262 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1263 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1273 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1275 emit_store_dst(jd, iptr, d);
1278 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1279 /* sx.val.i = constant */
1281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1282 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1283 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1284 M_OR_IMM(s1, iptr->sx.val.i, d);
1286 ICONST(REG_ITMP2, iptr->sx.val.i);
1287 M_OR(s1, REG_ITMP2, d);
1289 emit_store_dst(jd, iptr, d);
1292 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1294 #if SIZEOF_VOID_P == 8
1295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1296 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1297 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1300 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1301 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1303 M_OR(s1, s2, GET_LOW_REG(d));
1304 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1305 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1306 M_OR(s1, s2, GET_HIGH_REG(d));
1308 emit_store_dst(jd, iptr, d);
1311 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1312 /* sx.val.l = constant */
1314 #if SIZEOF_VOID_P == 8
1315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1317 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1318 M_OR_IMM(s1, iptr->sx.val.l, d);
1320 LCONST(REG_ITMP2, iptr->sx.val.l);
1321 M_OR(s1, REG_ITMP2, d);
1324 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1325 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1326 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1327 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1328 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1331 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1332 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1333 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1334 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1335 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1338 emit_store_dst(jd, iptr, d);
1341 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1345 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1351 /* sx.val.i = constant */
1353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1355 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1356 M_XOR_IMM(s1, iptr->sx.val.i, d);
1358 ICONST(REG_ITMP2, iptr->sx.val.i);
1359 M_XOR(s1, REG_ITMP2, d);
1361 emit_store_dst(jd, iptr, d);
1364 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1366 #if SIZEOF_VOID_P == 8
1367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1368 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1372 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1373 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1375 M_XOR(s1, s2, GET_LOW_REG(d));
1376 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1377 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1378 M_XOR(s1, s2, GET_HIGH_REG(d));
1380 emit_store_dst(jd, iptr, d);
1383 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1384 /* sx.val.l = constant */
1386 #if SIZEOF_VOID_P == 8
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1389 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1390 M_XOR_IMM(s1, iptr->sx.val.l, d);
1392 LCONST(REG_ITMP2, iptr->sx.val.l);
1393 M_XOR(s1, REG_ITMP2, d);
1396 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1397 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1398 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1399 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1400 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1403 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1404 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1405 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1406 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1407 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1410 emit_store_dst(jd, iptr, d);
1414 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1416 #if SIZEOF_VOID_P == 8
1417 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1418 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1420 M_CMPLT(s1, s2, REG_ITMP3);
1421 M_CMPLT(s2, s1, REG_ITMP1);
1422 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1424 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1425 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1427 M_CMPLT(s1, s2, REG_ITMP3);
1428 M_CMPLT(s2, s1, REG_ITMP1);
1429 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1432 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1433 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1434 M_CMPULT(s1, s2, REG_ITMP3);
1435 M_CMPULT(s2, s1, REG_ITMP1);
1436 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1438 emit_store_dst(jd, iptr, d);
1442 /* floating operations ************************************************/
1444 case ICMD_FNEG: /* ..., value ==> ..., - value */
1446 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1447 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1449 emit_store_dst(jd, iptr, d);
1452 case ICMD_DNEG: /* ..., value ==> ..., - value */
1454 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1455 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1466 emit_store_dst(jd, iptr, d);
1469 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1471 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1473 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1475 emit_store_dst(jd, iptr, d);
1478 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1480 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1481 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1482 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1484 emit_store_dst(jd, iptr, d);
1487 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1489 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1491 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1493 emit_store_dst(jd, iptr, d);
1496 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1498 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1499 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1500 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1502 emit_store_dst(jd, iptr, d);
1505 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1507 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1508 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1509 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1511 emit_store_dst(jd, iptr, d);
1514 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1516 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1517 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1518 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1520 emit_store_dst(jd, iptr, d);
1523 case ICMD_DDIV: /* ..., 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_FTMP2);
1529 emit_store_dst(jd, iptr, d);
1533 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1535 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1536 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1537 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1538 M_FDIV(s1,s2, REG_FTMP3);
1539 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1540 M_CVTLF(REG_FTMP3, REG_FTMP3);
1541 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1542 M_FSUB(s1, REG_FTMP3, d);
1543 emit_store_dst(jd, iptr, d);
1546 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1548 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1550 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1551 M_DDIV(s1,s2, REG_FTMP3);
1552 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1553 M_CVTLD(REG_FTMP3, REG_FTMP3);
1554 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1555 M_DSUB(s1, REG_FTMP3, d);
1556 emit_store_dst(jd, iptr, d);
1560 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1563 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1566 emit_store_dst(jd, iptr, d);
1569 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1572 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1575 emit_store_dst(jd, iptr, d);
1579 /* XXX these do not work correctly */
1581 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1583 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1585 M_TRUNCFI(s1, REG_FTMP1);
1586 M_MOVDI(REG_FTMP1, d);
1588 emit_store_dst(jd, iptr, d);
1591 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1593 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1595 M_TRUNCDI(s1, REG_FTMP1);
1596 M_MOVDI(REG_FTMP1, d);
1598 emit_store_dst(jd, iptr, d);
1601 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1603 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1605 M_TRUNCFL(s1, REG_FTMP1);
1606 M_MOVDL(REG_FTMP1, d);
1608 emit_store_dst(jd, iptr, d);
1611 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1613 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1615 M_TRUNCDL(s1, REG_FTMP1);
1616 M_MOVDL(REG_FTMP1, d);
1618 emit_store_dst(jd, iptr, d);
1622 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1624 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1625 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1627 emit_store_dst(jd, iptr, d);
1630 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1632 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1633 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1635 emit_store_dst(jd, iptr, d);
1638 #if SUPPORT_FLOAT_CMP
1639 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1641 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1642 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1646 M_AADD_IMM(REG_ZERO, 1, d);
1650 M_ASUB_IMM(REG_ZERO, 1, d);
1651 M_CMOVT(REG_ZERO, d);
1652 emit_store_dst(jd, iptr, d);
1655 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1657 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1658 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1662 M_ASUB_IMM(REG_ZERO, 1, d);
1666 M_AADD_IMM(REG_ZERO, 1, d);
1667 M_CMOVT(REG_ZERO, d);
1668 emit_store_dst(jd, iptr, d);
1672 #if SUPPORT_DOUBLE_CMP
1673 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1675 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1676 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1680 M_AADD_IMM(REG_ZERO, 1, d);
1684 M_ASUB_IMM(REG_ZERO, 1, d);
1685 M_CMOVT(REG_ZERO, d);
1686 emit_store_dst(jd, iptr, d);
1689 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1691 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1692 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1693 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1696 M_ASUB_IMM(REG_ZERO, 1, d);
1700 M_AADD_IMM(REG_ZERO, 1, d);
1701 M_CMOVT(REG_ZERO, d);
1702 emit_store_dst(jd, iptr, d);
1707 /* memory operations **************************************************/
1709 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1713 /* implicit null-pointer check */
1714 M_ILD(d, s1, OFFSET(java_array_t, size));
1715 emit_store_dst(jd, iptr, d);
1718 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1722 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1723 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1724 M_AADD(s2, s1, REG_ITMP3);
1725 /* implicit null-pointer check */
1726 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1727 emit_store_dst(jd, iptr, d);
1730 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1732 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1733 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1735 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1736 M_AADD(s2, s1, REG_ITMP3);
1737 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1738 /* implicit null-pointer check */
1739 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1740 emit_store_dst(jd, iptr, d);
1743 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1746 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1747 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1748 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1749 M_AADD(s2, s1, REG_ITMP3);
1750 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1751 /* implicit null-pointer check */
1752 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1753 emit_store_dst(jd, iptr, d);
1756 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1759 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1760 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1761 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1762 M_ASLL_IMM(s2, 2, REG_ITMP3);
1763 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1764 /* implicit null-pointer check */
1765 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1766 emit_store_dst(jd, iptr, d);
1769 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1772 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773 #if SIZEOF_VOID_P == 8
1774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1776 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1778 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1779 M_ASLL_IMM(s2, 3, REG_ITMP3);
1780 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1781 /* implicit null-pointer check */
1782 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1783 emit_store_dst(jd, iptr, d);
1786 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1789 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1790 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1791 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1792 M_ASLL_IMM(s2, 2, REG_ITMP3);
1793 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1794 /* implicit null-pointer check */
1795 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1796 emit_store_dst(jd, iptr, d);
1799 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1802 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1803 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1804 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1805 M_ASLL_IMM(s2, 3, REG_ITMP3);
1806 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1807 /* implicit null-pointer check */
1808 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1809 emit_store_dst(jd, iptr, d);
1812 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1815 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1817 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1818 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1819 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1820 /* implicit null-pointer check */
1821 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1822 emit_store_dst(jd, iptr, d);
1826 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1829 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1830 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1831 M_AADD(s2, s1, REG_ITMP1);
1832 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1833 /* implicit null-pointer check */
1834 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1837 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1838 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1842 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1843 M_AADD(s2, s1, REG_ITMP1);
1844 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1845 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1846 /* implicit null-pointer check */
1847 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1850 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1852 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1853 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1854 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1855 M_ASLL_IMM(s2, 2, REG_ITMP2);
1856 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1857 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1858 /* implicit null-pointer check */
1859 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1862 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1866 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1867 M_ASLL_IMM(s2, 3, REG_ITMP2);
1868 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1869 #if SIZEOF_VOID_P == 8
1870 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1872 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1874 /* implicit null-pointer check */
1875 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1878 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1880 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1881 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1882 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1883 M_ASLL_IMM(s2, 2, REG_ITMP2);
1884 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1885 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1886 /* implicit null-pointer check */
1887 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1890 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1892 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1893 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1894 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1895 M_ASLL_IMM(s2, 3, REG_ITMP2);
1896 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1897 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1898 /* implicit null-pointer check */
1899 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1903 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1905 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1906 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1907 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1908 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1910 M_INTMOVE(s1, REG_A0);
1911 M_INTMOVE(s3, REG_A1);
1912 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1913 M_ALD(REG_ITMP3, REG_PV, disp);
1914 M_JSR(REG_RA, REG_ITMP3);
1916 emit_arraystore_check(cd, iptr);
1918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1920 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1921 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1922 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1923 /* implicit null-pointer check */
1924 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1928 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1931 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1932 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1933 M_AADD(s2, s1, REG_ITMP1);
1934 /* implicit null-pointer check */
1935 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1938 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1939 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1942 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1943 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1944 M_AADD(s2, s1, REG_ITMP1);
1945 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1946 /* implicit null-pointer check */
1947 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1950 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1954 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1955 M_ASLL_IMM(s2, 2, REG_ITMP2);
1956 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1957 /* implicit null-pointer check */
1958 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1961 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1964 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1965 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1966 M_ASLL_IMM(s2, 3, REG_ITMP2);
1967 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1968 /* implicit null-pointer check */
1969 #if SIZEOF_VOID_P == 8
1970 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1972 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1976 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1979 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1980 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1981 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1982 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1983 /* implicit null-pointer check */
1984 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1988 case ICMD_GETSTATIC: /* ... ==> ..., value */
1990 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1991 uf = iptr->sx.s23.s3.uf;
1992 fieldtype = uf->fieldref->parseddesc.fd->type;
1993 disp = dseg_add_unique_address(cd, uf);
1995 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1998 fi = iptr->sx.s23.s3.fmiref->p.field;
1999 fieldtype = fi->type;
2000 disp = dseg_add_address(cd, fi->value);
2002 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2003 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2007 M_ALD(REG_ITMP1, REG_PV, disp);
2009 switch (fieldtype) {
2011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2012 M_ILD_INTERN(d, REG_ITMP1, 0);
2015 #if SIZEOF_VOID_P == 8
2016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2018 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2020 M_LLD_INTERN(d, REG_ITMP1, 0);
2023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2024 M_ALD_INTERN(d, REG_ITMP1, 0);
2027 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2028 M_FLD_INTERN(d, REG_ITMP1, 0);
2031 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2032 M_DLD_INTERN(d, REG_ITMP1, 0);
2035 emit_store_dst(jd, iptr, d);
2038 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2040 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2041 uf = iptr->sx.s23.s3.uf;
2042 fieldtype = uf->fieldref->parseddesc.fd->type;
2043 disp = dseg_add_unique_address(cd, uf);
2045 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2048 fi = iptr->sx.s23.s3.fmiref->p.field;
2049 fieldtype = fi->type;
2050 disp = dseg_add_address(cd, fi->value);
2052 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2053 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2057 M_ALD(REG_ITMP1, REG_PV, disp);
2059 switch (fieldtype) {
2061 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2062 M_IST_INTERN(s1, REG_ITMP1, 0);
2065 #if SIZEOF_VOID_P == 8
2066 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2068 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2070 M_LST_INTERN(s1, REG_ITMP1, 0);
2073 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2074 M_AST_INTERN(s1, REG_ITMP1, 0);
2077 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2078 M_FST_INTERN(s1, REG_ITMP1, 0);
2081 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2082 M_DST_INTERN(s1, REG_ITMP1, 0);
2087 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2089 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2090 uf = iptr->sx.s23.s3.uf;
2091 fieldtype = uf->fieldref->parseddesc.fd->type;
2092 disp = dseg_add_unique_address(cd, uf);
2094 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2097 fi = iptr->sx.s23.s3.fmiref->p.field;
2098 fieldtype = fi->type;
2099 disp = dseg_add_address(cd, fi->value);
2101 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2102 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2106 M_ALD(REG_ITMP1, REG_PV, disp);
2108 switch (fieldtype) {
2110 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2113 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2116 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2119 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2122 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2128 case ICMD_GETFIELD: /* ... ==> ..., value */
2130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131 emit_nullpointer_check(cd, iptr, s1);
2133 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2134 uf = iptr->sx.s23.s3.uf;
2135 fieldtype = uf->fieldref->parseddesc.fd->type;
2138 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2141 fi = iptr->sx.s23.s3.fmiref->p.field;
2142 fieldtype = fi->type;
2146 switch (fieldtype) {
2148 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2152 #if SIZEOF_VOID_P == 8
2153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2156 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2157 M_LLD_GETFIELD(d, s1, disp);
2161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2165 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2169 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2173 emit_store_dst(jd, iptr, d);
2176 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 emit_nullpointer_check(cd, iptr, s1);
2181 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2182 uf = iptr->sx.s23.s3.uf;
2183 fieldtype = uf->fieldref->parseddesc.fd->type;
2187 fi = iptr->sx.s23.s3.fmiref->p.field;
2188 fieldtype = fi->type;
2192 #if SIZEOF_VOID_P == 8
2193 if (IS_INT_LNG_TYPE(fieldtype))
2194 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2196 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2198 if (IS_INT_LNG_TYPE(fieldtype)) {
2199 if (IS_2_WORD_TYPE(fieldtype))
2200 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2202 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2205 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2208 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2209 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2211 switch (fieldtype) {
2213 M_IST(s2, s1, disp);
2216 M_LST(s2, s1, disp);
2219 M_AST(s2, s1, disp);
2222 M_FST(s2, s1, disp);
2225 M_DST(s2, s1, disp);
2230 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2233 emit_nullpointer_check(cd, iptr, s1);
2235 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2236 uf = iptr->sx.s23.s3.uf;
2237 fieldtype = uf->fieldref->parseddesc.fd->type;
2240 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2243 fi = iptr->sx.s23.s3.fmiref->p.field;
2244 fieldtype = fi->type;
2248 switch (fieldtype) {
2250 M_IST(REG_ZERO, s1, disp);
2253 M_LST(REG_ZERO, s1, disp);
2256 M_AST(REG_ZERO, s1, disp);
2259 M_FST(REG_ZERO, s1, disp);
2262 M_DST(REG_ZERO, s1, disp);
2268 /* branch operations **************************************************/
2270 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2272 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2273 M_INTMOVE(s1, REG_ITMP1_XPTR);
2275 #ifdef ENABLE_VERIFIER
2276 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2277 uc = iptr->sx.s23.s2.uc;
2279 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2281 #endif /* ENABLE_VERIFIER */
2283 disp = dseg_add_functionptr(cd, asm_handle_exception);
2284 M_ALD(REG_ITMP2, REG_PV, disp);
2285 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2287 M_NOP; /* nop ensures that XPC is less than the end */
2288 /* of basic block */
2292 case ICMD_GOTO: /* ... ==> ... */
2293 case ICMD_RET: /* ... ==> ... */
2295 emit_br(cd, iptr->dst.block);
2299 case ICMD_JSR: /* ... ==> ... */
2301 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2305 case ICMD_IFNULL: /* ..., value ==> ... */
2306 case ICMD_IFNONNULL:
2308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2309 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2312 case ICMD_IFEQ: /* ..., value ==> ... */
2314 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2315 if (iptr->sx.val.i == 0)
2316 emit_beqz(cd, iptr->dst.block, s1);
2318 ICONST(REG_ITMP2, iptr->sx.val.i);
2319 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2323 case ICMD_IFLT: /* ..., value ==> ... */
2325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2326 if (iptr->sx.val.i == 0)
2327 emit_bltz(cd, iptr->dst.block, s1);
2329 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2330 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2332 ICONST(REG_ITMP2, iptr->sx.val.i);
2333 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2335 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2339 case ICMD_IFLE: /* ..., value ==> ... */
2341 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2342 if (iptr->sx.val.i == 0)
2343 emit_blez(cd, iptr->dst.block, s1);
2345 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2346 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2347 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2350 ICONST(REG_ITMP2, iptr->sx.val.i);
2351 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2352 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2357 case ICMD_IFNE: /* ..., value ==> ... */
2359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360 if (iptr->sx.val.i == 0)
2361 emit_bnez(cd, iptr->dst.block, s1);
2363 ICONST(REG_ITMP2, iptr->sx.val.i);
2364 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2368 case ICMD_IFGT: /* ..., value ==> ... */
2370 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2371 if (iptr->sx.val.i == 0)
2372 emit_bgtz(cd, iptr->dst.block, s1);
2374 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2375 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2376 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2379 ICONST(REG_ITMP2, iptr->sx.val.i);
2380 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2381 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2386 case ICMD_IFGE: /* ..., value ==> ... */
2388 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2389 if (iptr->sx.val.i == 0)
2390 emit_bgez(cd, iptr->dst.block, s1);
2392 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2393 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2395 ICONST(REG_ITMP2, iptr->sx.val.i);
2396 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2398 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2402 case ICMD_IF_LEQ: /* ..., value ==> ... */
2404 #if SIZEOF_VOID_P == 8
2405 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2406 if (iptr->sx.val.l == 0)
2407 emit_beqz(cd, iptr->dst.block, s1);
2409 LCONST(REG_ITMP2, iptr->sx.val.l);
2410 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2413 if (iptr->sx.val.l == 0) {
2414 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2415 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2416 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2419 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2420 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2421 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2422 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2423 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2424 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2425 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2426 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2431 case ICMD_IF_LLT: /* ..., value ==> ... */
2433 #if SIZEOF_VOID_P == 8
2434 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2435 if (iptr->sx.val.l == 0)
2436 emit_bltz(cd, iptr->dst.block, s1);
2438 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2439 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2441 LCONST(REG_ITMP2, iptr->sx.val.l);
2442 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2444 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2447 if (iptr->sx.val.l == 0) {
2448 /* if high word is less than zero, the whole long is too */
2449 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2450 emit_bltz(cd, iptr->dst.block, s1);
2453 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2454 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2455 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2456 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2457 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2458 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2460 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2461 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2462 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2467 case ICMD_IF_LLE: /* ..., value ==> ... */
2469 #if SIZEOF_VOID_P == 8
2470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2471 if (iptr->sx.val.l == 0)
2472 emit_blez(cd, iptr->dst.block, s1);
2474 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2475 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2476 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2479 LCONST(REG_ITMP2, iptr->sx.val.l);
2480 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2481 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2485 if (iptr->sx.val.l == 0) {
2486 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2487 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2489 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2490 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2493 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2494 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2495 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2496 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2497 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2498 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2500 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2501 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2502 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2507 case ICMD_IF_LNE: /* ..., value ==> ... */
2509 #if SIZEOF_VOID_P == 8
2510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2511 if (iptr->sx.val.l == 0)
2512 emit_bnez(cd, iptr->dst.block, s1);
2514 LCONST(REG_ITMP2, iptr->sx.val.l);
2515 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2518 if (iptr->sx.val.l == 0) {
2519 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2520 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2521 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2524 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2525 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2526 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2527 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2528 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2529 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2530 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2531 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2536 case ICMD_IF_LGT: /* ..., value ==> ... */
2538 #if SIZEOF_VOID_P == 8
2539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2540 if (iptr->sx.val.l == 0)
2541 emit_bgtz(cd, iptr->dst.block, s1);
2543 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2544 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2545 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2548 LCONST(REG_ITMP2, iptr->sx.val.l);
2549 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2550 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2554 if (iptr->sx.val.l == 0) {
2555 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2556 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2557 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2559 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2562 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2563 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2564 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2565 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2566 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2567 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2569 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2570 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2571 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2576 case ICMD_IF_LGE: /* ..., value ==> ... */
2578 #if SIZEOF_VOID_P == 8
2579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2580 if (iptr->sx.val.l == 0)
2581 emit_bgez(cd, iptr->dst.block, s1);
2583 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2584 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2587 LCONST(REG_ITMP2, iptr->sx.val.l);
2588 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2590 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2593 if (iptr->sx.val.l == 0) {
2594 /* if high word is greater equal zero, the whole long is too */
2595 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2596 emit_bgez(cd, iptr->dst.block, s1);
2599 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2600 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2601 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2602 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2603 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2604 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2606 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2607 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2608 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2613 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2614 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2615 #if SIZEOF_VOID_P == 8
2616 case ICMD_IF_LCMPEQ:
2619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2621 emit_beq(cd, iptr->dst.block, s1, s2);
2624 #if SIZEOF_VOID_P == 4
2625 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2626 /* op1 = target JavaVM pc */
2628 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2629 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2630 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2632 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2633 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2634 emit_beq(cd, iptr->dst.block, s1, s2);
2638 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2639 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2640 #if SIZEOF_VOID_P == 8
2641 case ICMD_IF_LCMPNE:
2644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2646 emit_bne(cd, iptr->dst.block, s1, s2);
2649 #if SIZEOF_VOID_P == 4
2650 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2652 /* TODO: could be optimized (XOR or SUB) */
2653 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2654 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2655 emit_bne(cd, iptr->dst.block, s1, s2);
2656 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2657 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2658 emit_bne(cd, iptr->dst.block, s1, s2);
2662 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2663 #if SIZEOF_VOID_P == 8
2664 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2669 M_CMPLT(s1, s2, REG_ITMP3);
2670 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2673 #if SIZEOF_VOID_P == 4
2674 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2676 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2677 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2678 M_CMPLT(s1, s2, REG_ITMP3);
2679 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2680 M_CMPGT(s1, s2, REG_ITMP3);
2681 /* load low-bits before the branch, so we know the distance */
2682 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2683 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2684 M_BNEZ(REG_ITMP3, 4); /* XXX */
2686 M_CMPULT(s1, s2, REG_ITMP3);
2687 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2691 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2692 #if SIZEOF_VOID_P == 8
2693 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2698 M_CMPGT(s1, s2, REG_ITMP3);
2699 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2702 #if SIZEOF_VOID_P == 4
2703 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2705 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2706 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2707 M_CMPGT(s1, s2, REG_ITMP3);
2708 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2709 M_CMPLT(s1, s2, REG_ITMP3);
2710 /* load low-bits before the branch, so we know the distance */
2711 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2712 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2713 M_BNEZ(REG_ITMP3, 4); /* XXX */
2715 M_CMPUGT(s1, s2, REG_ITMP3);
2716 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2720 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2721 #if SIZEOF_VOID_P == 8
2722 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2727 M_CMPGT(s1, s2, REG_ITMP3);
2728 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2731 #if SIZEOF_VOID_P == 4
2732 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2734 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2735 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2736 M_CMPLT(s1, s2, REG_ITMP3);
2737 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2738 M_CMPGT(s1, s2, REG_ITMP3);
2739 /* load low-bits before the branch, so we know the distance */
2740 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2741 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2742 M_BNEZ(REG_ITMP3, 4); /* XXX */
2744 M_CMPUGT(s1, s2, REG_ITMP3);
2745 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2749 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2750 #if SIZEOF_VOID_P == 8
2751 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2755 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2756 M_CMPLT(s1, s2, REG_ITMP3);
2757 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2760 #if SIZEOF_VOID_P == 4
2761 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2763 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2764 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2765 M_CMPGT(s1, s2, REG_ITMP3);
2766 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2767 M_CMPLT(s1, s2, REG_ITMP3);
2768 /* load low-bits before the branch, so we know the distance */
2769 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2770 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2771 M_BNEZ(REG_ITMP3, 4); /* XXX */
2773 M_CMPULT(s1, s2, REG_ITMP3);
2774 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2778 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2779 #if SIZEOF_VOID_P == 8
2783 REPLACEMENT_POINT_RETURN(cd, iptr);
2784 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2785 M_INTMOVE(s1, REG_RESULT);
2786 goto nowperformreturn;
2788 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2790 REPLACEMENT_POINT_RETURN(cd, iptr);
2791 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2792 M_INTMOVE(s1, REG_RESULT);
2794 #ifdef ENABLE_VERIFIER
2795 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2796 uc = iptr->sx.s23.s2.uc;
2798 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2800 #endif /* ENABLE_VERIFIER */
2801 goto nowperformreturn;
2803 #if SIZEOF_VOID_P == 4
2804 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2806 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2807 M_LNGMOVE(s1, REG_RESULT_PACKED);
2808 goto nowperformreturn;
2811 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2812 REPLACEMENT_POINT_RETURN(cd, iptr);
2813 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2814 M_FLTMOVE(s1, REG_FRESULT);
2815 goto nowperformreturn;
2817 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2819 REPLACEMENT_POINT_RETURN(cd, iptr);
2820 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2821 M_DBLMOVE(s1, REG_FRESULT);
2822 goto nowperformreturn;
2824 case ICMD_RETURN: /* ... ==> ... */
2826 REPLACEMENT_POINT_RETURN(cd, iptr);
2832 p = cd->stackframesize;
2834 #if !defined(NDEBUG)
2835 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2836 emit_verbosecall_exit(jd);
2839 #if defined(ENABLE_THREADS)
2840 if (checksync && code_is_synchronized(code)) {
2841 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2842 M_ALD(REG_ITMP3, REG_PV, disp);
2844 /* we need to save the proper return value */
2846 switch (iptr->opc) {
2849 #if SIZEOF_VOID_P == 8
2852 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2853 M_JSR(REG_RA, REG_ITMP3);
2854 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2856 #if SIZEOF_VOID_P == 4
2858 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2859 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2860 M_JSR(REG_RA, REG_ITMP3);
2866 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2867 M_JSR(REG_RA, REG_ITMP3);
2868 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2871 M_JSR(REG_RA, REG_ITMP3);
2872 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2876 /* and now restore the proper return value */
2878 switch (iptr->opc) {
2881 #if SIZEOF_VOID_P == 8
2884 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2886 #if SIZEOF_VOID_P == 4
2888 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2893 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2899 /* restore return address */
2901 if (!code_is_leafmethod(code)) {
2902 p--; M_ALD(REG_RA, REG_SP, p * 8);
2905 /* restore saved registers */
2907 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2908 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2910 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2911 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2914 /* deallocate stack and return */
2916 if (cd->stackframesize) {
2919 disp = cd->stackframesize * 8;
2920 lo = (short) (disp);
2921 hi = (short) (((disp) - lo) >> 16);
2925 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2927 M_LUI(REG_ITMP3,hi);
2928 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2930 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2943 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2946 branch_target_t *table;
2948 table = iptr->dst.table;
2950 l = iptr->sx.s23.s2.tablelow;
2951 i = iptr->sx.s23.s3.tablehigh;
2953 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2955 {M_INTMOVE(s1, REG_ITMP1);}
2956 else if (l <= 32768) {
2957 M_IADD_IMM(s1, -l, REG_ITMP1);
2960 ICONST(REG_ITMP2, l);
2961 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2964 /* number of targets */
2969 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2970 emit_beqz(cd, table[0].block, REG_ITMP2);
2972 /* build jump table top down and use address of lowest entry */
2977 dseg_add_target(cd, table->block);
2982 /* length of dataseg after last dseg_add_target is used by load */
2984 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2985 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2986 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2993 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2996 lookup_target_t *lookup;
2998 lookup = iptr->dst.lookup;
3000 i = iptr->sx.s23.s2.lookupcount;
3002 MCODECHECK((i<<2)+8);
3003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3006 ICONST(REG_ITMP2, lookup->value);
3007 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3011 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3017 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3019 bte = iptr->sx.s23.s3.bte;
3023 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3025 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3026 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3027 case ICMD_INVOKEINTERFACE:
3029 REPLACEMENT_POINT_INVOKE(cd, iptr);
3031 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3033 um = iptr->sx.s23.s3.um;
3034 md = um->methodref->parseddesc.md;
3037 lm = iptr->sx.s23.s3.fmiref->p.method;
3039 md = lm->parseddesc;
3043 s3 = md->paramcount;
3045 MCODECHECK((s3 << 1) + 64);
3047 /* copy arguments to registers or stack location */
3049 for (s3 = s3 - 1; s3 >= 0; s3--) {
3050 var = VAR(iptr->sx.s23.s2.args[s3]);
3051 d = md->params[s3].regoff;
3053 if (var->flags & PREALLOC)
3056 if (IS_INT_LNG_TYPE(var->type)) {
3057 #if SIZEOF_VOID_P == 8
3058 if (!md->params[s3].inmemory) {
3059 s1 = emit_load(jd, iptr, var, d);
3063 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3064 M_LST(s1, REG_SP, d);
3067 if (!md->params[s3].inmemory) {
3068 s1 = emit_load(jd, iptr, var, d);
3070 if (IS_2_WORD_TYPE(var->type))
3076 if (IS_2_WORD_TYPE(var->type)) {
3077 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3078 M_LST(s1, REG_SP, d);
3081 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3082 M_IST(s1, REG_SP, d);
3088 if (!md->params[s3].inmemory) {
3089 s1 = emit_load(jd, iptr, var, d);
3090 if (IS_2_WORD_TYPE(var->type))
3096 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3097 if (IS_2_WORD_TYPE(var->type))
3098 M_DST(s1, REG_SP, d);
3100 M_FST(s1, REG_SP, d);
3105 switch (iptr->opc) {
3107 if (bte->stub == NULL) {
3108 disp = dseg_add_functionptr(cd, bte->fp);
3109 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3111 /* generate the actual call */
3113 /* TWISTI: i actually don't know the reason for using
3114 REG_ITMP3 here instead of REG_PV. */
3116 M_JSR(REG_RA, REG_ITMP3);
3120 disp = dseg_add_functionptr(cd, bte->stub);
3121 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3123 /* generate the actual call */
3125 M_JSR(REG_RA, REG_PV);
3129 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3130 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3131 M_LDA(REG_PV, REG_RA, -disp);
3134 case ICMD_INVOKESPECIAL:
3135 emit_nullpointer_check(cd, iptr, REG_A0);
3138 case ICMD_INVOKESTATIC:
3140 disp = dseg_add_unique_address(cd, um);
3142 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3146 disp = dseg_add_address(cd, lm->stubroutine);
3148 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3150 /* generate the actual call */
3152 M_JSR(REG_RA, REG_PV);
3154 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3155 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3156 M_LDA(REG_PV, REG_RA, -disp);
3159 case ICMD_INVOKEVIRTUAL:
3160 emit_nullpointer_check(cd, iptr, REG_A0);
3163 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3168 s1 = OFFSET(vftbl_t, table[0]) +
3169 sizeof(methodptr) * lm->vftblindex;
3171 /* implicit null-pointer check */
3172 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3173 M_ALD(REG_PV, REG_METHODPTR, s1);
3175 /* generate the actual call */
3177 M_JSR(REG_RA, REG_PV);
3179 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3180 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3181 M_LDA(REG_PV, REG_RA, -disp);
3184 case ICMD_INVOKEINTERFACE:
3185 emit_nullpointer_check(cd, iptr, REG_A0);
3188 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3194 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3195 sizeof(methodptr*) * lm->class->index;
3197 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3200 /* implicit null-pointer check */
3201 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3202 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3203 M_ALD(REG_PV, REG_METHODPTR, s2);
3205 /* generate the actual call */
3207 M_JSR(REG_RA, REG_PV);
3209 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3210 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3211 M_LDA(REG_PV, REG_RA, -disp);
3215 /* store return value */
3217 d = md->returntype.type;
3219 if (d != TYPE_VOID) {
3220 if (IS_INT_LNG_TYPE(d)) {
3221 #if SIZEOF_VOID_P == 8
3222 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3223 M_INTMOVE(REG_RESULT, s1);
3225 if (IS_2_WORD_TYPE(d)) {
3226 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3227 M_LNGMOVE(REG_RESULT_PACKED, s1);
3230 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3231 M_INTMOVE(REG_RESULT, s1);
3236 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3237 if (IS_2_WORD_TYPE(d))
3238 M_DMOV(REG_FRESULT, s1);
3240 M_FMOV(REG_FRESULT, s1);
3242 emit_store_dst(jd, iptr, s1);
3247 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3249 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3253 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3258 super = iptr->sx.s23.s3.c.cls;
3259 superindex = super->index;
3262 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3263 CODEGEN_CRITICAL_SECTION_NEW;
3265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3267 /* if class is not resolved, check which code to call */
3269 if (super == NULL) {
3270 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3272 cr = iptr->sx.s23.s3.c.ref;
3273 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3275 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3278 M_ILD(REG_ITMP2, REG_PV, disp);
3279 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3280 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3283 /* interface checkcast code */
3285 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3286 if (super == NULL) {
3287 cr = iptr->sx.s23.s3.c.ref;
3289 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3293 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3296 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3297 M_ILD(REG_ITMP3, REG_ITMP2,
3298 OFFSET(vftbl_t, interfacetablelength));
3299 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3300 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3302 M_ALD(REG_ITMP3, REG_ITMP2,
3303 OFFSET(vftbl_t, interfacetable[0]) -
3304 superindex * sizeof(methodptr*));
3305 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3308 emit_label_br(cd, BRANCH_LABEL_4);
3310 emit_label(cd, BRANCH_LABEL_3);
3313 /* class checkcast code */
3315 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3316 if (super == NULL) {
3317 emit_label(cd, BRANCH_LABEL_2);
3319 cr = iptr->sx.s23.s3.c.ref;
3320 disp = dseg_add_unique_address(cd, NULL);
3322 patcher_add_patch_ref(jd,
3323 PATCHER_resolve_classref_to_vftbl,
3327 disp = dseg_add_address(cd, super->vftbl);
3329 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3332 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3333 M_ALD(REG_ITMP3, REG_PV, disp);
3335 CODEGEN_CRITICAL_SECTION_START;
3337 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3338 /* if (s1 != REG_ITMP1) { */
3339 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3340 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3341 /* #if defined(ENABLE_THREADS) */
3342 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3344 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3346 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3347 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3348 M_ALD(REG_ITMP3, REG_PV, disp);
3349 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3351 CODEGEN_CRITICAL_SECTION_END;
3354 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3355 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3358 emit_label(cd, BRANCH_LABEL_5);
3361 if (super == NULL) {
3362 emit_label(cd, BRANCH_LABEL_1);
3363 emit_label(cd, BRANCH_LABEL_4);
3366 d = codegen_reg_of_dst(jd, iptr, s1);
3369 s1 = emit_load_s1(jd, iptr, REG_A0);
3370 M_INTMOVE(s1, REG_A0);
3372 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3373 cr = iptr->sx.s23.s3.c.ref;
3374 disp = dseg_add_unique_address(cd, NULL);
3376 patcher_add_patch_ref(jd,
3377 PATCHER_resolve_classref_to_classinfo,
3381 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3384 M_ALD(REG_A1, REG_PV, disp);
3385 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3386 M_ALD(REG_ITMP3, REG_PV, disp);
3387 M_JSR(REG_RA, REG_ITMP3);
3390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3391 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3393 d = codegen_reg_of_dst(jd, iptr, s1);
3397 emit_store_dst(jd, iptr, d);
3400 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3406 super = iptr->sx.s23.s3.c.cls;
3408 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3413 super = iptr->sx.s23.s3.c.cls;
3414 superindex = super->index;
3417 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3418 CODEGEN_CRITICAL_SECTION_NEW;
3420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3424 M_MOV(s1, REG_ITMP1);
3430 /* if class is not resolved, check which code to call */
3432 if (super == NULL) {
3433 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3435 cr = iptr->sx.s23.s3.c.ref;
3436 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3438 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3441 M_ILD(REG_ITMP3, REG_PV, disp);
3442 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3443 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3446 /* interface instanceof code */
3448 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3449 if (super == NULL) {
3450 cr = iptr->sx.s23.s3.c.ref;
3452 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3456 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3459 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3460 M_ILD(REG_ITMP3, REG_ITMP1,
3461 OFFSET(vftbl_t, interfacetablelength));
3462 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3463 M_BLEZ(REG_ITMP3, 3);
3465 M_ALD(REG_ITMP1, REG_ITMP1,
3466 OFFSET(vftbl_t, interfacetable[0]) -
3467 superindex * sizeof(methodptr*));
3468 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3471 emit_label_br(cd, BRANCH_LABEL_4);
3473 emit_label(cd, BRANCH_LABEL_3);
3476 /* class instanceof code */
3478 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3479 if (super == NULL) {
3480 emit_label(cd, BRANCH_LABEL_2);
3482 cr = iptr->sx.s23.s3.c.ref;
3483 disp = dseg_add_unique_address(cd, NULL);
3485 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3489 disp = dseg_add_address(cd, super->vftbl);
3491 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3494 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3495 M_ALD(REG_ITMP2, REG_PV, disp);
3497 CODEGEN_CRITICAL_SECTION_START;
3499 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3500 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3501 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3503 CODEGEN_CRITICAL_SECTION_END;
3505 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3506 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3510 emit_label(cd, BRANCH_LABEL_5);
3513 if (super == NULL) {
3514 emit_label(cd, BRANCH_LABEL_1);
3515 emit_label(cd, BRANCH_LABEL_4);
3518 emit_store_dst(jd, iptr, d);
3522 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3524 /* check for negative sizes and copy sizes to stack if necessary */
3526 MCODECHECK((iptr->s1.argcount << 1) + 64);
3528 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3530 var = VAR(iptr->sx.s23.s2.args[s1]);
3532 /* copy SAVEDVAR sizes to stack */
3534 if (!(var->flags & PREALLOC)) {
3535 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3536 #if SIZEOF_VOID_P == 8
3537 M_LST(s2, REG_SP, s1 * 8);
3539 M_IST(s2, REG_SP, (s1 + 2) * 8);
3544 /* a0 = dimension count */
3546 ICONST(REG_A0, iptr->s1.argcount);
3548 /* is patcher function set? */
3550 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3551 cr = iptr->sx.s23.s3.c.ref;
3552 disp = dseg_add_unique_address(cd, NULL);
3554 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3558 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3561 /* a1 = arraydescriptor */
3563 M_ALD(REG_A1, REG_PV, disp);
3565 /* a2 = pointer to dimensions = stack pointer */
3567 #if SIZEOF_VOID_P == 8
3568 M_MOV(REG_SP, REG_A2);
3570 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3573 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3574 M_ALD(REG_ITMP3, REG_PV, disp);
3575 M_JSR(REG_RA, REG_ITMP3);
3578 /* check for exception before result assignment */
3580 emit_exception_check(cd, iptr);
3582 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3583 M_INTMOVE(REG_RESULT, d);
3584 emit_store_dst(jd, iptr, d);
3588 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3593 } /* for instruction */
3595 MCODECHECK(64); /* XXX require smaller number? */
3597 /* At the end of a basic block we may have to append some nops,
3598 because the patcher stub calling code might be longer than the
3599 actual instruction. So codepatching does not change the
3600 following block unintentionally. */
3602 if (cd->mcodeptr < cd->lastmcodeptr) {
3603 while (cd->mcodeptr < cd->lastmcodeptr)
3607 } /* if (bptr -> flags >= BBREACHED) */
3608 } /* for basic block */
3610 dseg_createlinenumbertable(cd);
3612 /* generate traps */
3614 emit_patcher_traps(jd);
3616 /* everything's ok */
3622 /* codegen_emit_stub_compiler **************************************************
3624 Emits a stub routine which calls the compiler.
3626 *******************************************************************************/
3628 void codegen_emit_stub_compiler(jitdata *jd)
3633 /* get required compiler data */
3638 /* code for the stub */
3640 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3641 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3647 /* codegen_emit_stub_native ****************************************************
3649 Emits a stub routine which calls a native method.
3651 *******************************************************************************/
3653 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3664 /* get required compiler data */
3670 /* initialize variables */
3674 /* calculate stack frame size */
3676 cd->stackframesize =
3677 1 + /* return address */
3678 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3679 sizeof(localref_table) / SIZEOF_VOID_P +
3680 md->paramcount + /* for saving arguments over calls */
3681 #if SIZEOF_VOID_P == 4
3682 5 + /* additional save space (MIPS32) */
3684 1 + /* for saving return address */
3687 /* adjust stackframe size for 16-byte alignment */
3689 if (cd->stackframesize & 1)
3690 cd->stackframesize++;
3692 /* create method header */
3694 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3695 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3696 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3697 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3698 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3699 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3700 (void) dseg_addlinenumbertablesize(cd);
3701 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3703 /* generate stub code */
3705 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3706 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3708 #if !defined(NDEBUG)
3709 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3710 emit_verbosecall_enter(jd);
3713 /* save integer and float argument registers */
3715 #if SIZEOF_VOID_P == 8
3716 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3717 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3718 s1 = md->params[i].regoff;
3719 M_AST(s1, REG_SP, j * 8);
3724 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3725 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3726 if (!md->params[i].inmemory) {
3727 s1 = md->params[i].regoff;
3729 if (IS_2_WORD_TYPE(md->params[i].type))
3730 M_LST(s1, REG_SP, j * 8);
3732 M_IST(s1, REG_SP, j * 8);
3740 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3741 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3742 s1 = md->params[i].regoff;
3744 if (IS_2_WORD_TYPE(md->params[i].type))
3745 M_DST(s1, REG_SP, j * 8);
3747 M_FST(s1, REG_SP, j * 8);
3753 /* prepare data structures for native function call */
3755 M_MOV(REG_SP, REG_A0);
3756 M_MOV(REG_PV, REG_A1);
3757 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3758 M_ALD(REG_ITMP3, REG_PV, disp);
3759 M_JSR(REG_RA, REG_ITMP3);
3760 M_NOP; /* XXX fill me! */
3762 /* remember class argument */
3764 if (m->flags & ACC_STATIC)
3765 M_MOV(REG_RESULT, REG_ITMP3);
3767 /* restore integer and float argument registers */
3769 #if SIZEOF_VOID_P == 8
3770 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3771 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3772 s1 = md->params[i].regoff;
3773 M_LLD(s1, REG_SP, j * 8);
3778 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3779 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3780 if (!md->params[i].inmemory) {
3781 s1 = md->params[i].regoff;
3783 if (IS_2_WORD_TYPE(md->params[i].type))
3784 M_LLD(s1, REG_SP, j * 8);
3786 M_ILD(s1, REG_SP, j * 8);
3794 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3795 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3796 s1 = md->params[i].regoff;
3798 if (IS_2_WORD_TYPE(md->params[i].type))
3799 M_DLD(s1, REG_SP, j * 8);
3801 M_FLD(s1, REG_SP, j * 8);
3807 /* copy or spill arguments to new locations */
3809 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3810 t = md->params[i].type;
3812 if (IS_INT_LNG_TYPE(t)) {
3813 if (!md->params[i].inmemory) {
3814 s1 = md->params[i].regoff;
3815 s2 = nmd->params[j].regoff;
3817 if (!nmd->params[j].inmemory) {
3818 #if SIZEOF_VOID_P == 8
3821 if (IS_2_WORD_TYPE(t))
3828 #if SIZEOF_VOID_P == 8
3829 M_LST(s1, REG_SP, s2);
3831 if (IS_2_WORD_TYPE(t))
3832 M_LST(s1, REG_SP, s2);
3834 M_IST(s1, REG_SP, s2);
3839 s1 = md->params[i].regoff + cd->stackframesize * 8;
3840 s2 = nmd->params[j].regoff;
3842 #if SIZEOF_VOID_P == 8
3843 M_LLD(REG_ITMP1, REG_SP, s1);
3844 M_LST(REG_ITMP1, REG_SP, s2);
3846 if (IS_2_WORD_TYPE(t)) {
3847 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3848 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3851 M_ILD(REG_ITMP1, REG_SP, s1);
3852 M_IST(REG_ITMP1, REG_SP, s2);
3858 if (!md->params[i].inmemory) {
3859 s1 = md->params[i].regoff;
3860 s2 = nmd->params[j].regoff;
3862 if (!nmd->params[j].inmemory) {
3863 #if SIZEOF_VOID_P == 8
3864 if (IS_2_WORD_TYPE(t))
3869 /* On MIPS32 float arguments for native functions
3870 can never be in float argument registers, since
3871 the first argument is _always_ an integer
3872 argument (JNIEnv) */
3874 if (IS_2_WORD_TYPE(t)) {
3875 /* double high/low order is endian
3876 independent: even numbered holds low
3877 32-bits, odd numbered high 32-bits */
3879 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3880 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3887 #if SIZEOF_VOID_P == 8
3888 if (IS_2_WORD_TYPE(t))
3889 M_DST(s1, REG_SP, s2);
3891 M_FST(s1, REG_SP, s2);
3893 /* s1 may have been originally in 2 int registers,
3894 but was moved out by the native function
3895 argument(s), just get low register */
3897 if (IS_2_WORD_TYPE(t))
3898 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3900 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3905 s1 = md->params[i].regoff + cd->stackframesize * 8;
3906 s2 = nmd->params[j].regoff;
3908 #if SIZEOF_VOID_P == 8
3909 if (IS_2_WORD_TYPE(t)) {
3910 M_DLD(REG_FTMP1, REG_SP, s1);
3911 M_DST(REG_FTMP1, REG_SP, s2);
3914 M_FLD(REG_FTMP1, REG_SP, s1);
3915 M_FST(REG_FTMP1, REG_SP, s2);
3918 if (IS_2_WORD_TYPE(t)) {
3919 M_DLD(REG_FTMP1, REG_SP, s1);
3920 M_DST(REG_FTMP1, REG_SP, s2);
3923 M_FLD(REG_FTMP1, REG_SP, s1);
3924 M_FST(REG_FTMP1, REG_SP, s2);
3931 /* Handle native Java methods. */
3933 if (m->flags & ACC_NATIVE) {
3934 /* put class into second argument register */
3936 if (m->flags & ACC_STATIC)
3937 M_MOV(REG_ITMP3, REG_A1);
3939 /* put env into first argument register */
3941 disp = dseg_add_address(cd, _Jv_env);
3942 M_ALD(REG_A0, REG_PV, disp);
3945 /* Call the native function. */
3947 disp = dseg_add_functionptr(cd, f);
3948 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3949 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3950 M_NOP; /* delay slot */
3952 /* save return value */
3954 switch (md->returntype.type) {
3955 #if SIZEOF_VOID_P == 8
3959 M_LST(REG_RESULT, REG_SP, 0 * 8);
3963 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3968 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3971 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3975 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3982 #if !defined(NDEBUG)
3983 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3984 emit_verbosecall_exit(jd);
3987 /* remove native stackframe info */
3989 M_MOV(REG_SP, REG_A0);
3990 M_MOV(REG_PV, REG_A1);
3991 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3992 M_ALD(REG_ITMP3, REG_PV, disp);
3993 M_JSR(REG_RA, REG_ITMP3);
3994 M_NOP; /* XXX fill me! */
3995 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3997 /* restore return value */
3999 switch (md->returntype.type) {
4000 #if SIZEOF_VOID_P == 8
4004 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4008 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4013 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
4016 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
4020 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4027 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4029 /* check for exception */
4031 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4032 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4034 M_RET(REG_RA); /* return to caller */
4035 M_NOP; /* DELAY SLOT */
4037 /* handle exception */
4039 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4040 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4041 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4042 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4044 /* Generate patcher traps. */
4046 emit_patcher_traps(jd);
4051 * These are local overrides for various environment variables in Emacs.
4052 * Please do not remove this and leave it at the end of the file, where
4053 * Emacs will automagically detect them.
4054 * ---------------------------------------------------------------------
4057 * indent-tabs-mode: t
4061 * vim:noexpandtab:sw=4:ts=4: