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
25 $Id: codegen.c 8268 2007-08-07 13:24:43Z twisti $
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
42 #include "mm/memory.h"
44 #include "native/native.h"
46 #include "threads/lock-common.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/md.h"
59 #include "vm/jit/patcher-common.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
63 #if defined(ENABLE_LSRA)
64 # include "vm/jit/allocator/lsra.h"
67 #include "vmcore/class.h"
68 #include "vmcore/options.h"
71 /* codegen_emit ****************************************************************
73 Generates machine code.
75 *******************************************************************************/
77 bool codegen_emit(jitdata *jd)
83 s4 len, s1, s2, s3, d, disp;
89 constant_classref *cr;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 unresolved_method *um;
93 builtintable_entry *bte;
100 /* get required compiler data */
107 /* prevent compiler warnings */
122 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
124 /* space to save used callee saved registers */
126 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
127 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
129 cd->stackframesize = rd->memuse + savedregs_num;
131 #if defined(ENABLE_THREADS)
132 /* space to save argument of monitor_enter */
134 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
135 # if SIZEOF_VOID_P == 8
136 cd->stackframesize++;
139 cd->stackframesize += 2;
144 /* keep stack 16-byte aligned */
146 if (cd->stackframesize & 1)
147 cd->stackframesize++;
149 /* create method header */
151 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
152 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
154 #if defined(ENABLE_THREADS)
155 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
161 if (checksync && (m->flags & ACC_SYNCHRONIZED))
162 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
165 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
167 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
168 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
169 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 dseg_addlinenumbertablesize(cd);
171 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
173 /* create exception table */
175 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
176 dseg_add_target(cd, ex->start);
177 dseg_add_target(cd, ex->end);
178 dseg_add_target(cd, ex->handler);
179 (void) dseg_add_unique_address(cd, ex->catchtype.any);
182 /* create stack frame (if necessary) */
184 if (cd->stackframesize)
185 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
187 /* save return address and used callee saved registers */
189 p = cd->stackframesize;
190 if (!jd->isleafmethod) {
191 p--; M_AST(REG_RA, REG_SP, p * 8);
193 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
194 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
196 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
197 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
200 /* take arguments out of register or stack frame */
204 for (p = 0, l = 0; p < md->paramcount; p++) {
205 t = md->paramtypes[p].type;
207 varindex = jd->local_map[l * 5 + t];
210 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
213 if (varindex == UNUSED)
217 s1 = md->params[p].regoff;
219 if (IS_INT_LNG_TYPE(t)) { /* integer args */
220 if (!md->params[p].inmemory) { /* register arguments */
221 #if SIZEOF_VOID_P == 8
222 if (!(var->flags & INMEMORY))
223 M_INTMOVE(s1, var->vv.regoff);
225 M_LST(s1, REG_SP, var->vv.regoff);
227 if (!(var->flags & INMEMORY)) {
228 if (IS_2_WORD_TYPE(t))
229 M_LNGMOVE(s1, var->vv.regoff);
231 M_INTMOVE(s1, var->vv.regoff);
234 if (IS_2_WORD_TYPE(t))
235 M_LST(s1, REG_SP, var->vv.regoff);
237 M_IST(s1, REG_SP, var->vv.regoff);
241 else { /* stack arguments */
242 if (!(var->flags & INMEMORY)) {
243 #if SIZEOF_VOID_P == 8
244 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
246 if (IS_2_WORD_TYPE(t))
247 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
249 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
253 var->vv.regoff = cd->stackframesize * 8 + s1;
256 else { /* floating args */
257 if (!md->params[p].inmemory) {
258 if (!(var->flags & INMEMORY)) {
259 if (IS_2_WORD_TYPE(t))
260 M_DBLMOVE(s1, var->vv.regoff);
262 M_FLTMOVE(s1, var->vv.regoff);
265 if (IS_2_WORD_TYPE(t))
266 M_DST(s1, REG_SP, var->vv.regoff);
268 M_FST(s1, REG_SP, var->vv.regoff);
272 if (!(var->flags & INMEMORY)) {
273 if (IS_2_WORD_TYPE(t))
274 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
276 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
279 var->vv.regoff = cd->stackframesize * 8 + s1;
284 /* call monitorenter function */
286 #if defined(ENABLE_THREADS)
287 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
288 /* stack offset for monitor argument */
292 # if !defined(NDEBUG)
293 if (opt_verbosecall) {
294 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
296 for (p = 0; p < INT_ARG_CNT; p++)
297 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
299 for (p = 0; p < FLT_ARG_CNT; p++)
300 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
302 s1 += INT_ARG_CNT + FLT_ARG_CNT;
306 /* get correct lock object */
308 if (m->flags & ACC_STATIC) {
309 disp = dseg_add_address(cd, &m->class->object.header);
310 M_ALD(REG_A0, REG_PV, disp);
311 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
312 M_ALD(REG_ITMP3, REG_PV, disp);
315 /* emit_nullpointer_check(cd, iptr, REG_A0); */
317 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
318 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
319 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
322 M_JSR(REG_RA, REG_ITMP3);
323 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
325 # if !defined(NDEBUG)
326 if (opt_verbosecall) {
327 for (p = 0; p < INT_ARG_CNT; p++)
328 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
330 for (p = 0; p < FLT_ARG_CNT; p++)
331 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
334 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
342 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
343 emit_verbosecall_enter(jd);
346 /* end of header generation */
348 /* create replacement points */
350 REPLACEMENT_POINTS_INIT(cd, jd);
352 /* walk through all basic blocks */
354 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
356 /* handle replacement points */
358 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
360 /* store relative start of block */
362 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
364 if (bptr->flags >= BBREACHED) {
365 /* branch resolving */
367 codegen_resolve_branchrefs(cd, bptr);
369 /* copy interface registers to their destination */
373 #if defined(ENABLE_LSRA)
377 src = bptr->invars[len];
378 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
379 /* d = reg_of_var(m, src, REG_ITMP1); */
380 if (!(src->flags & INMEMORY))
384 M_INTMOVE(REG_ITMP1, d);
385 emit_store(jd, NULL, src, d);
392 var = VAR(bptr->invars[len]);
393 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
394 d = codegen_reg_of_var(0, var, REG_ITMP1);
395 M_INTMOVE(REG_ITMP1, d);
396 emit_store(jd, NULL, var, d);
399 assert((var->flags & INOUT));
402 #if defined(ENABLE_LSRA)
405 /* walk through all instructions */
408 /* currentline = 0; */
410 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
411 if (iptr->line != currentline) {
412 dseg_addlinenumber(cd, iptr->line);
413 currentline = iptr->line;
416 MCODECHECK(64); /* an instruction usually needs < 64 words */
420 case ICMD_NOP: /* ... ==> ... */
421 case ICMD_POP: /* ..., value ==> ... */
422 case ICMD_POP2: /* ..., value, value ==> ... */
425 case ICMD_INLINE_START:
427 REPLACEMENT_POINT_INLINE_START(cd, iptr);
430 case ICMD_INLINE_BODY:
432 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
433 dseg_addlinenumber_inline_start(cd, iptr);
434 dseg_addlinenumber(cd, iptr->line);
437 case ICMD_INLINE_END:
439 dseg_addlinenumber_inline_end(cd, iptr);
440 dseg_addlinenumber(cd, iptr->line);
443 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
446 emit_nullpointer_check(cd, iptr, s1);
449 /* constant operations ************************************************/
451 case ICMD_ICONST: /* ... ==> ..., constant */
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454 ICONST(d, iptr->sx.val.i);
455 emit_store_dst(jd, iptr, d);
458 case ICMD_LCONST: /* ... ==> ..., constant */
460 #if SIZEOF_VOID_P == 8
461 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
465 LCONST(d, iptr->sx.val.l);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_FCONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
472 disp = dseg_add_float(cd, iptr->sx.val.f);
473 M_FLD(d, REG_PV, disp);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_DCONST: /* ... ==> ..., constant */
479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
480 disp = dseg_add_double(cd, iptr->sx.val.d);
481 M_DLD(d, REG_PV, disp);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_ACONST: /* ... ==> ..., constant */
487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
489 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
490 cr = iptr->sx.val.c.ref;
491 disp = dseg_add_unique_address(cd, cr);
493 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
496 M_ALD(d, REG_PV, disp);
499 if (iptr->sx.val.anyptr == NULL)
500 M_INTMOVE(REG_ZERO, d);
502 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
503 M_ALD(d, REG_PV, disp);
506 emit_store_dst(jd, iptr, d);
510 /* load/store/copy/move operations ************************************/
512 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
517 case ICMD_ISTORE: /* ..., value ==> ... */
528 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
533 /* integer operations *************************************************/
535 case ICMD_INEG: /* ..., value ==> ..., - value */
537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
539 M_ISUB(REG_ZERO, s1, d);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_LNEG: /* ..., value ==> ..., - value */
545 #if SIZEOF_VOID_P == 8
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
548 M_LSUB(REG_ZERO, s1, d);
550 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
552 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
553 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
554 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
555 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
557 emit_store_dst(jd, iptr, d);
560 case ICMD_I2L: /* ..., value ==> ..., value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 #if SIZEOF_VOID_P == 8
564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
568 M_INTMOVE(s1, GET_LOW_REG(d));
569 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
571 emit_store_dst(jd, iptr, d);
574 case ICMD_L2I: /* ..., value ==> ..., value */
576 #if SIZEOF_VOID_P == 8
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
579 M_ISLL_IMM(s1, 0, d);
581 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
583 M_INTMOVE(GET_LOW_REG(s1), d);
585 emit_store_dst(jd, iptr, d);
588 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
592 #if SIZEOF_VOID_P == 8
593 M_LSLL_IMM(s1, 56, d);
594 M_LSRA_IMM( d, 56, d);
596 M_ISLL_IMM(s1, 24, d);
597 M_ISRA_IMM( d, 24, d);
599 emit_store_dst(jd, iptr, d);
602 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
606 M_AND_IMM(s1, 0xffff, d);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
613 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
614 #if SIZEOF_VOID_P == 8
615 M_LSLL_IMM(s1, 48, d);
616 M_LSRA_IMM( d, 48, d);
618 M_ISLL_IMM(s1, 16, d);
619 M_ISRA_IMM( d, 16, d);
621 emit_store_dst(jd, iptr, d);
625 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 emit_store_dst(jd, iptr, d);
635 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
636 /* sx.val.i = constant */
638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
640 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
641 M_IADD_IMM(s1, iptr->sx.val.i, d);
643 ICONST(REG_ITMP2, iptr->sx.val.i);
644 M_IADD(s1, REG_ITMP2, d);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
651 #if SIZEOF_VOID_P == 8
652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
658 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
660 M_IADD(s1, s2, GET_HIGH_REG(d));
661 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
662 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
663 if (s1 == GET_LOW_REG(d)) {
664 M_MOV(s1, REG_ITMP3);
667 M_IADD(s1, s2, GET_LOW_REG(d));
668 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
669 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
671 emit_store_dst(jd, iptr, d);
674 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
675 /* sx.val.l = constant */
677 #if SIZEOF_VOID_P == 8
678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
679 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
681 M_LADD_IMM(s1, iptr->sx.val.l, d);
683 LCONST(REG_ITMP2, iptr->sx.val.l);
684 M_LADD(s1, REG_ITMP2, d);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
688 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
689 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
690 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
691 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
692 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
694 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
695 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
696 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
697 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
698 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
699 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
700 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
703 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
704 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
705 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
706 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
707 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
708 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
709 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
710 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
713 emit_store_dst(jd, iptr, d);
716 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
719 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
722 emit_store_dst(jd, iptr, d);
725 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
726 /* sx.val.i = constant */
728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
729 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
730 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
731 M_IADD_IMM(s1, -iptr->sx.val.i, d);
733 ICONST(REG_ITMP2, iptr->sx.val.i);
734 M_ISUB(s1, REG_ITMP2, d);
736 emit_store_dst(jd, iptr, d);
739 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
741 #if SIZEOF_VOID_P == 8
742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
747 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
748 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
749 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
750 M_ISUB(s1, s2, GET_HIGH_REG(d));
751 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
752 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
753 M_CMPULT(s1, s2, REG_ITMP3);
754 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
755 /* if s1 is equal to REG_ITMP3 we have to reload it, since
756 the CMPULT instruction destroyed it */
758 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
759 M_ISUB(s1, s2, GET_LOW_REG(d));
762 emit_store_dst(jd, iptr, d);
765 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
766 /* sx.val.l = constant */
768 #if SIZEOF_VOID_P == 8
769 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
771 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
772 M_LADD_IMM(s1, -iptr->sx.val.l, d);
774 LCONST(REG_ITMP2, iptr->sx.val.l);
775 M_LSUB(s1, REG_ITMP2, d);
778 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
779 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
780 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
781 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
782 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
783 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
784 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
785 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
787 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
788 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
789 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
790 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
791 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
794 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
795 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
796 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
797 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
798 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
799 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
800 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
801 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
804 emit_store_dst(jd, iptr, d);
807 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
816 emit_store_dst(jd, iptr, d);
819 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
820 /* sx.val.i = constant */
822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
823 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 ICONST(REG_ITMP2, iptr->sx.val.i);
825 M_IMUL(s1, REG_ITMP2);
829 emit_store_dst(jd, iptr, d);
832 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
834 #if SIZEOF_VOID_P == 8
835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
836 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
844 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
845 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
850 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
852 M_MFHI(GET_HIGH_REG(d));
853 M_MFLO(GET_LOW_REG(d));
856 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
858 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
859 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
862 /* XXX do we need nops here? */
864 emit_store_dst(jd, iptr, d);
867 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
868 /* sx.val.l = constant */
870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
872 LCONST(REG_ITMP2, iptr->sx.val.l);
873 M_LMUL(s1, REG_ITMP2);
877 emit_store_dst(jd, iptr, d);
880 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
883 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
885 emit_arithmetic_check(cd, iptr, s2);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
896 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 emit_arithmetic_check(cd, iptr, s2);
903 emit_store_dst(jd, iptr, d);
906 #if SIZEOF_VOID_P == 8
908 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913 emit_arithmetic_check(cd, iptr, s2);
918 emit_store_dst(jd, iptr, d);
921 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
923 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
924 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
926 emit_arithmetic_check(cd, iptr, s2);
931 emit_store_dst(jd, iptr, d);
934 #else /* SIZEOF_VOID_P == 8 */
936 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
937 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
939 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
940 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
942 /* XXX TODO: only do this if arithmetic check is really done! */
943 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
944 emit_arithmetic_check(cd, iptr, REG_ITMP3);
946 M_LNGMOVE(s1, REG_A0_A1_PACKED);
947 M_LNGMOVE(s2, REG_A2_A3_PACKED);
949 bte = iptr->sx.s23.s3.bte;
950 disp = dseg_add_functionptr(cd, bte->fp);
951 M_ALD(REG_ITMP3, REG_PV, disp);
952 M_JSR(REG_RA, REG_ITMP3);
955 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
956 M_LNGMOVE(REG_RESULT_PACKED, d);
957 emit_store_dst(jd, iptr, d);
960 #endif /* SIZEOF_VOID_P == 8 */
962 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
963 /* val.i = constant */
965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
966 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
967 #if SIZEOF_VOID_P == 8
968 M_LSRA_IMM(s1, 63, REG_ITMP2);
969 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
970 M_LADD(s1, REG_ITMP2, REG_ITMP2);
971 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
973 M_ISRA_IMM(s1, 31, REG_ITMP2);
974 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
975 M_IADD(s1, REG_ITMP2, REG_ITMP2);
976 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
982 /* val.i = constant */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987 M_MOV(s1, REG_ITMP1);
990 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
991 M_AND_IMM(s1, iptr->sx.val.i, d);
994 M_ISUB(REG_ZERO, s1, d);
995 M_AND_IMM(d, iptr->sx.val.i, d);
998 ICONST(REG_ITMP2, iptr->sx.val.i);
999 M_AND(s1, REG_ITMP2, d);
1002 M_ISUB(REG_ZERO, s1, d);
1003 M_AND(d, REG_ITMP2, d);
1005 M_ISUB(REG_ZERO, d, d);
1006 emit_store_dst(jd, iptr, d);
1009 #if SIZEOF_VOID_P == 8
1011 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1012 /* val.i = constant */
1014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 M_LSRA_IMM(s1, 63, REG_ITMP2);
1017 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1018 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1019 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1020 emit_store_dst(jd, iptr, d);
1023 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1024 /* val.l = constant */
1026 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1027 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1029 M_MOV(s1, REG_ITMP1);
1032 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1033 M_AND_IMM(s1, iptr->sx.val.l, d);
1036 M_LSUB(REG_ZERO, s1, d);
1037 M_AND_IMM(d, iptr->sx.val.l, d);
1040 LCONST(REG_ITMP2, iptr->sx.val.l);
1041 M_AND(s1, REG_ITMP2, d);
1044 M_LSUB(REG_ZERO, s1, d);
1045 M_AND(d, REG_ITMP2, d);
1047 M_LSUB(REG_ZERO, d, d);
1048 emit_store_dst(jd, iptr, d);
1051 #endif /* SIZEOF_VOID_P == 8 */
1053 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1056 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1057 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1063 /* sx.val.i = constant */
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1067 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1068 emit_store_dst(jd, iptr, d);
1071 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1077 emit_store_dst(jd, iptr, d);
1080 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1081 /* sx.val.i = constant */
1083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1084 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1085 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1099 /* sx.val.i = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1103 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1109 #if SIZEOF_VOID_P == 8
1110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1111 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1116 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1119 M_ISLL(s2, 26, REG_ITMP1);
1120 M_BGEZ(REG_ITMP1, 3);
1123 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1125 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1128 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1130 M_BEQZ(REG_ITMP1, 4);
1131 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1133 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1134 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1135 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1138 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1141 emit_store_dst(jd, iptr, d);
1144 #if SIZEOF_VOID_P == 8
1146 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1147 /* sx.val.i = constant */
1149 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1151 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1158 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1159 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1165 /* sx.val.i = constant */
1167 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1168 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1169 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1179 emit_store_dst(jd, iptr, d);
1182 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1183 /* sx.val.i = constant */
1185 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1186 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1187 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1188 emit_store_dst(jd, iptr, d);
1191 #endif /* SIZEOF_VOID_P == 8 */
1193 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1196 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1197 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1199 emit_store_dst(jd, iptr, d);
1202 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1203 /* sx.val.i = constant */
1205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1206 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1207 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1208 M_AND_IMM(s1, iptr->sx.val.i, d);
1210 ICONST(REG_ITMP2, iptr->sx.val.i);
1211 M_AND(s1, REG_ITMP2, d);
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1218 #if SIZEOF_VOID_P == 8
1219 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1221 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1224 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1225 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1227 M_AND(s1, s2, GET_LOW_REG(d));
1228 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1229 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1230 M_AND(s1, s2, GET_HIGH_REG(d));
1232 emit_store_dst(jd, iptr, d);
1235 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1236 /* sx.val.l = constant */
1238 #if SIZEOF_VOID_P == 8
1239 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1240 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1241 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1242 M_AND_IMM(s1, iptr->sx.val.l, d);
1244 LCONST(REG_ITMP2, iptr->sx.val.l);
1245 M_AND(s1, REG_ITMP2, d);
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1249 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1250 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1251 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1252 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1255 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1256 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1257 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1258 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1259 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1262 emit_store_dst(jd, iptr, d);
1265 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1268 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1269 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1271 emit_store_dst(jd, iptr, d);
1274 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1275 /* sx.val.i = constant */
1277 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1279 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1280 M_OR_IMM(s1, iptr->sx.val.i, d);
1282 ICONST(REG_ITMP2, iptr->sx.val.i);
1283 M_OR(s1, REG_ITMP2, d);
1285 emit_store_dst(jd, iptr, d);
1288 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1290 #if SIZEOF_VOID_P == 8
1291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1296 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1297 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1298 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1299 M_OR(s1, s2, GET_LOW_REG(d));
1300 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1301 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1302 M_OR(s1, s2, GET_HIGH_REG(d));
1304 emit_store_dst(jd, iptr, d);
1307 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1308 /* sx.val.l = constant */
1310 #if SIZEOF_VOID_P == 8
1311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1312 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1313 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1314 M_OR_IMM(s1, iptr->sx.val.l, d);
1316 LCONST(REG_ITMP2, iptr->sx.val.l);
1317 M_OR(s1, REG_ITMP2, d);
1320 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1321 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1322 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1323 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1324 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1327 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1328 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1329 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1330 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1331 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1340 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1341 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1343 emit_store_dst(jd, iptr, d);
1346 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1347 /* sx.val.i = constant */
1349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1351 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1352 M_XOR_IMM(s1, iptr->sx.val.i, d);
1354 ICONST(REG_ITMP2, iptr->sx.val.i);
1355 M_XOR(s1, REG_ITMP2, d);
1357 emit_store_dst(jd, iptr, d);
1360 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1362 #if SIZEOF_VOID_P == 8
1363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1369 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1371 M_XOR(s1, s2, GET_LOW_REG(d));
1372 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1373 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1374 M_XOR(s1, s2, GET_HIGH_REG(d));
1376 emit_store_dst(jd, iptr, d);
1379 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1380 /* sx.val.l = constant */
1382 #if SIZEOF_VOID_P == 8
1383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1384 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1385 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1386 M_XOR_IMM(s1, iptr->sx.val.l, d);
1388 LCONST(REG_ITMP2, iptr->sx.val.l);
1389 M_XOR(s1, REG_ITMP2, d);
1392 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1393 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1394 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1395 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1396 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1399 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1400 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1401 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1402 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1403 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1406 emit_store_dst(jd, iptr, d);
1410 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1412 #if SIZEOF_VOID_P == 8
1413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1416 M_CMPLT(s1, s2, REG_ITMP3);
1417 M_CMPLT(s2, s1, REG_ITMP1);
1418 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1420 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1421 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1423 M_CMPLT(s1, s2, REG_ITMP3);
1424 M_CMPLT(s2, s1, REG_ITMP1);
1425 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1428 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1430 M_CMPULT(s1, s2, REG_ITMP3);
1431 M_CMPULT(s2, s1, REG_ITMP1);
1432 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1434 emit_store_dst(jd, iptr, d);
1438 /* floating operations ************************************************/
1440 case ICMD_FNEG: /* ..., value ==> ..., - value */
1442 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1445 emit_store_dst(jd, iptr, d);
1448 case ICMD_DNEG: /* ..., value ==> ..., - value */
1450 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1451 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1453 emit_store_dst(jd, iptr, d);
1456 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1458 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1459 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1467 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1469 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1471 emit_store_dst(jd, iptr, d);
1474 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1476 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1480 emit_store_dst(jd, iptr, d);
1483 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1485 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1486 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1487 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1489 emit_store_dst(jd, iptr, d);
1492 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1494 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1495 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1496 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1498 emit_store_dst(jd, iptr, d);
1501 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1503 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1504 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1505 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1507 emit_store_dst(jd, iptr, d);
1510 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1512 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1513 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1514 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1521 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1523 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1525 emit_store_dst(jd, iptr, d);
1529 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1531 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1533 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1534 M_FDIV(s1,s2, REG_FTMP3);
1535 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1536 M_CVTLF(REG_FTMP3, REG_FTMP3);
1537 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1538 M_FSUB(s1, REG_FTMP3, d);
1539 emit_store_dst(jd, iptr, d);
1542 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1544 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1545 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1546 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1547 M_DDIV(s1,s2, REG_FTMP3);
1548 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1549 M_CVTLD(REG_FTMP3, REG_FTMP3);
1550 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1551 M_DSUB(s1, REG_FTMP3, d);
1552 emit_store_dst(jd, iptr, d);
1556 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1559 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1562 emit_store_dst(jd, iptr, d);
1565 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1568 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1571 emit_store_dst(jd, iptr, d);
1575 /* XXX these do not work correctly */
1577 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1579 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1581 M_TRUNCFI(s1, REG_FTMP1);
1582 M_MOVDI(REG_FTMP1, d);
1584 emit_store_dst(jd, iptr, d);
1587 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1589 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1591 M_TRUNCDI(s1, REG_FTMP1);
1592 M_MOVDI(REG_FTMP1, d);
1594 emit_store_dst(jd, iptr, d);
1597 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1599 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1601 M_TRUNCFL(s1, REG_FTMP1);
1602 M_MOVDL(REG_FTMP1, d);
1604 emit_store_dst(jd, iptr, d);
1607 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1609 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1611 M_TRUNCDL(s1, REG_FTMP1);
1612 M_MOVDL(REG_FTMP1, d);
1614 emit_store_dst(jd, iptr, d);
1618 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1620 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1621 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1623 emit_store_dst(jd, iptr, d);
1626 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1628 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1629 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1631 emit_store_dst(jd, iptr, d);
1634 #if SUPPORT_FLOAT_CMP
1635 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1637 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1638 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1642 M_AADD_IMM(REG_ZERO, 1, d);
1646 M_ASUB_IMM(REG_ZERO, 1, d);
1647 M_CMOVT(REG_ZERO, d);
1648 emit_store_dst(jd, iptr, d);
1651 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1653 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1654 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1658 M_ASUB_IMM(REG_ZERO, 1, d);
1662 M_AADD_IMM(REG_ZERO, 1, d);
1663 M_CMOVT(REG_ZERO, d);
1664 emit_store_dst(jd, iptr, d);
1668 #if SUPPORT_DOUBLE_CMP
1669 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1671 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1672 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1676 M_AADD_IMM(REG_ZERO, 1, d);
1680 M_ASUB_IMM(REG_ZERO, 1, d);
1681 M_CMOVT(REG_ZERO, d);
1682 emit_store_dst(jd, iptr, d);
1685 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1687 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1688 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1689 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1692 M_ASUB_IMM(REG_ZERO, 1, d);
1696 M_AADD_IMM(REG_ZERO, 1, d);
1697 M_CMOVT(REG_ZERO, d);
1698 emit_store_dst(jd, iptr, d);
1703 /* memory operations **************************************************/
1705 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1708 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1709 /* implicit null-pointer check */
1710 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1711 emit_store_dst(jd, iptr, d);
1714 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1717 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1719 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1720 M_AADD(s2, s1, REG_ITMP3);
1721 /* implicit null-pointer check */
1722 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1723 emit_store_dst(jd, iptr, d);
1726 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1731 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1732 M_AADD(s2, s1, REG_ITMP3);
1733 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1734 /* implicit null-pointer check */
1735 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1736 emit_store_dst(jd, iptr, d);
1739 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1744 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1745 M_AADD(s2, s1, REG_ITMP3);
1746 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1747 /* implicit null-pointer check */
1748 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1749 emit_store_dst(jd, iptr, d);
1752 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1755 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1757 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1758 M_ASLL_IMM(s2, 2, REG_ITMP3);
1759 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1760 /* implicit null-pointer check */
1761 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1762 emit_store_dst(jd, iptr, d);
1765 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1768 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1769 #if SIZEOF_VOID_P == 8
1770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1774 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1775 M_ASLL_IMM(s2, 3, REG_ITMP3);
1776 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1777 /* implicit null-pointer check */
1778 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1779 emit_store_dst(jd, iptr, d);
1782 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1786 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1787 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1788 M_ASLL_IMM(s2, 2, REG_ITMP3);
1789 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1790 /* implicit null-pointer check */
1791 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1792 emit_store_dst(jd, iptr, d);
1795 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1798 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1799 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1800 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1801 M_ASLL_IMM(s2, 3, REG_ITMP3);
1802 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1803 /* implicit null-pointer check */
1804 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1805 emit_store_dst(jd, iptr, d);
1808 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1813 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1814 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1815 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1816 /* implicit null-pointer check */
1817 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1818 emit_store_dst(jd, iptr, d);
1822 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1825 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1826 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1827 M_AADD(s2, s1, REG_ITMP1);
1828 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1829 /* implicit null-pointer check */
1830 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1833 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1834 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1837 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1838 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1839 M_AADD(s2, s1, REG_ITMP1);
1840 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1841 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1842 /* implicit null-pointer check */
1843 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1846 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1850 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1851 M_ASLL_IMM(s2, 2, REG_ITMP2);
1852 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1853 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1854 /* implicit null-pointer check */
1855 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1858 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1861 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1862 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1863 M_ASLL_IMM(s2, 3, REG_ITMP2);
1864 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1865 #if SIZEOF_VOID_P == 8
1866 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1868 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1870 /* implicit null-pointer check */
1871 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1874 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1877 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1878 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1879 M_ASLL_IMM(s2, 2, REG_ITMP2);
1880 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1881 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1882 /* implicit null-pointer check */
1883 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1886 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1889 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1890 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1891 M_ASLL_IMM(s2, 3, REG_ITMP2);
1892 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1893 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1894 /* implicit null-pointer check */
1895 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1899 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1902 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1903 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1904 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1906 M_INTMOVE(s1, REG_A0);
1907 M_INTMOVE(s3, REG_A1);
1908 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1909 M_ALD(REG_ITMP3, REG_PV, disp);
1910 M_JSR(REG_RA, REG_ITMP3);
1912 emit_exception_check(cd, iptr);
1914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1915 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1916 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1917 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1918 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1919 /* implicit null-pointer check */
1920 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1924 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1928 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1929 M_AADD(s2, s1, REG_ITMP1);
1930 /* implicit null-pointer check */
1931 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1934 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1935 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1938 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1939 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1940 M_AADD(s2, s1, REG_ITMP1);
1941 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1942 /* implicit null-pointer check */
1943 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1946 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1949 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1950 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1951 M_ASLL_IMM(s2, 2, REG_ITMP2);
1952 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1953 /* implicit null-pointer check */
1954 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1957 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1960 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1961 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1962 M_ASLL_IMM(s2, 3, REG_ITMP2);
1963 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1964 /* implicit null-pointer check */
1965 #if SIZEOF_VOID_P == 8
1966 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1968 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
1972 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1974 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1976 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1977 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1978 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1979 /* implicit null-pointer check */
1980 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1984 case ICMD_GETSTATIC: /* ... ==> ..., value */
1986 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1987 uf = iptr->sx.s23.s3.uf;
1988 fieldtype = uf->fieldref->parseddesc.fd->type;
1989 disp = dseg_add_unique_address(cd, uf);
1991 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1994 fi = iptr->sx.s23.s3.fmiref->p.field;
1995 fieldtype = fi->type;
1996 disp = dseg_add_address(cd, fi->value);
1998 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1999 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2003 M_ALD(REG_ITMP1, REG_PV, disp);
2005 switch (fieldtype) {
2007 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2008 M_ILD_INTERN(d, REG_ITMP1, 0);
2011 #if SIZEOF_VOID_P == 8
2012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2014 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2016 M_LLD_INTERN(d, REG_ITMP1, 0);
2019 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2020 M_ALD_INTERN(d, REG_ITMP1, 0);
2023 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2024 M_FLD_INTERN(d, REG_ITMP1, 0);
2027 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2028 M_DLD_INTERN(d, REG_ITMP1, 0);
2031 emit_store_dst(jd, iptr, d);
2034 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2036 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2037 uf = iptr->sx.s23.s3.uf;
2038 fieldtype = uf->fieldref->parseddesc.fd->type;
2039 disp = dseg_add_unique_address(cd, uf);
2041 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2044 fi = iptr->sx.s23.s3.fmiref->p.field;
2045 fieldtype = fi->type;
2046 disp = dseg_add_address(cd, fi->value);
2048 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2049 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2053 M_ALD(REG_ITMP1, REG_PV, disp);
2055 switch (fieldtype) {
2057 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2058 M_IST_INTERN(s1, REG_ITMP1, 0);
2061 #if SIZEOF_VOID_P == 8
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2064 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2066 M_LST_INTERN(s1, REG_ITMP1, 0);
2069 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2070 M_AST_INTERN(s1, REG_ITMP1, 0);
2073 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2074 M_FST_INTERN(s1, REG_ITMP1, 0);
2077 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2078 M_DST_INTERN(s1, REG_ITMP1, 0);
2083 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2085 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2086 uf = iptr->sx.s23.s3.uf;
2087 fieldtype = uf->fieldref->parseddesc.fd->type;
2088 disp = dseg_add_unique_address(cd, uf);
2090 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2093 fi = iptr->sx.s23.s3.fmiref->p.field;
2094 fieldtype = fi->type;
2095 disp = dseg_add_address(cd, fi->value);
2097 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2098 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2102 M_ALD(REG_ITMP1, REG_PV, disp);
2104 switch (fieldtype) {
2106 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2109 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2112 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2115 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2118 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2124 case ICMD_GETFIELD: /* ... ==> ..., value */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 emit_nullpointer_check(cd, iptr, s1);
2129 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2130 uf = iptr->sx.s23.s3.uf;
2131 fieldtype = uf->fieldref->parseddesc.fd->type;
2134 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2137 fi = iptr->sx.s23.s3.fmiref->p.field;
2138 fieldtype = fi->type;
2142 switch (fieldtype) {
2144 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2148 #if SIZEOF_VOID_P == 8
2149 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2152 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2153 M_LLD_GETFIELD(d, s1, disp);
2157 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2161 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2165 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2169 emit_store_dst(jd, iptr, d);
2172 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2175 emit_nullpointer_check(cd, iptr, s1);
2177 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2178 uf = iptr->sx.s23.s3.uf;
2179 fieldtype = uf->fieldref->parseddesc.fd->type;
2183 fi = iptr->sx.s23.s3.fmiref->p.field;
2184 fieldtype = fi->type;
2188 #if SIZEOF_VOID_P == 8
2189 if (IS_INT_LNG_TYPE(fieldtype))
2190 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2192 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2194 if (IS_INT_LNG_TYPE(fieldtype)) {
2195 if (IS_2_WORD_TYPE(fieldtype))
2196 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2198 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2201 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2204 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2205 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2207 switch (fieldtype) {
2209 M_IST(s2, s1, disp);
2212 M_LST(s2, s1, disp);
2215 M_AST(s2, s1, disp);
2218 M_FST(s2, s1, disp);
2221 M_DST(s2, s1, disp);
2226 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2229 emit_nullpointer_check(cd, iptr, s1);
2231 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2232 uf = iptr->sx.s23.s3.uf;
2233 fieldtype = uf->fieldref->parseddesc.fd->type;
2236 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2239 fi = iptr->sx.s23.s3.fmiref->p.field;
2240 fieldtype = fi->type;
2244 switch (fieldtype) {
2246 M_IST(REG_ZERO, s1, disp);
2249 M_LST(REG_ZERO, s1, disp);
2252 M_AST(REG_ZERO, s1, disp);
2255 M_FST(REG_ZERO, s1, disp);
2258 M_DST(REG_ZERO, s1, disp);
2264 /* branch operations **************************************************/
2266 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 M_INTMOVE(s1, REG_ITMP1_XPTR);
2271 #ifdef ENABLE_VERIFIER
2272 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2273 uc = iptr->sx.s23.s2.uc;
2275 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2277 #endif /* ENABLE_VERIFIER */
2279 disp = dseg_add_functionptr(cd, asm_handle_exception);
2280 M_ALD(REG_ITMP2, REG_PV, disp);
2281 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2283 M_NOP; /* nop ensures that XPC is less than the end */
2284 /* of basic block */
2288 case ICMD_GOTO: /* ... ==> ... */
2289 case ICMD_RET: /* ... ==> ... */
2291 emit_br(cd, iptr->dst.block);
2295 case ICMD_JSR: /* ... ==> ... */
2297 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2301 case ICMD_IFNULL: /* ..., value ==> ... */
2302 case ICMD_IFNONNULL:
2304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2305 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2308 case ICMD_IFEQ: /* ..., value ==> ... */
2310 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2311 if (iptr->sx.val.i == 0)
2312 emit_beqz(cd, iptr->dst.block, s1);
2314 ICONST(REG_ITMP2, iptr->sx.val.i);
2315 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2319 case ICMD_IFLT: /* ..., value ==> ... */
2321 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2322 if (iptr->sx.val.i == 0)
2323 emit_bltz(cd, iptr->dst.block, s1);
2325 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2326 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2328 ICONST(REG_ITMP2, iptr->sx.val.i);
2329 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2331 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2335 case ICMD_IFLE: /* ..., value ==> ... */
2337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2338 if (iptr->sx.val.i == 0)
2339 emit_blez(cd, iptr->dst.block, s1);
2341 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2342 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2343 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2346 ICONST(REG_ITMP2, iptr->sx.val.i);
2347 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2348 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2353 case ICMD_IFNE: /* ..., value ==> ... */
2355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2356 if (iptr->sx.val.i == 0)
2357 emit_bnez(cd, iptr->dst.block, s1);
2359 ICONST(REG_ITMP2, iptr->sx.val.i);
2360 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2364 case ICMD_IFGT: /* ..., value ==> ... */
2366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2367 if (iptr->sx.val.i == 0)
2368 emit_bgtz(cd, iptr->dst.block, s1);
2370 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2371 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2372 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2375 ICONST(REG_ITMP2, iptr->sx.val.i);
2376 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2377 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2382 case ICMD_IFGE: /* ..., value ==> ... */
2384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2385 if (iptr->sx.val.i == 0)
2386 emit_bgez(cd, iptr->dst.block, s1);
2388 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2389 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2391 ICONST(REG_ITMP2, iptr->sx.val.i);
2392 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2394 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2398 case ICMD_IF_LEQ: /* ..., value ==> ... */
2400 #if SIZEOF_VOID_P == 8
2401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2402 if (iptr->sx.val.l == 0)
2403 emit_beqz(cd, iptr->dst.block, s1);
2405 LCONST(REG_ITMP2, iptr->sx.val.l);
2406 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2409 if (iptr->sx.val.l == 0) {
2410 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2411 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2412 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2415 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2416 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2417 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2418 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2419 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2420 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2421 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2422 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2427 case ICMD_IF_LLT: /* ..., value ==> ... */
2429 #if SIZEOF_VOID_P == 8
2430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2431 if (iptr->sx.val.l == 0)
2432 emit_bltz(cd, iptr->dst.block, s1);
2434 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2435 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2437 LCONST(REG_ITMP2, iptr->sx.val.l);
2438 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2440 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2443 if (iptr->sx.val.l == 0) {
2444 /* if high word is less than zero, the whole long is too */
2445 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2446 emit_bltz(cd, iptr->dst.block, s1);
2449 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2450 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2451 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2452 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2453 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2454 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2456 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2457 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2458 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2463 case ICMD_IF_LLE: /* ..., value ==> ... */
2465 #if SIZEOF_VOID_P == 8
2466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2467 if (iptr->sx.val.l == 0)
2468 emit_blez(cd, iptr->dst.block, s1);
2470 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2471 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2472 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2475 LCONST(REG_ITMP2, iptr->sx.val.l);
2476 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2477 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2481 if (iptr->sx.val.l == 0) {
2482 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2483 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2485 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2486 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2489 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2490 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2491 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2492 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2493 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2494 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2496 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2497 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2498 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2503 case ICMD_IF_LNE: /* ..., value ==> ... */
2505 #if SIZEOF_VOID_P == 8
2506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2507 if (iptr->sx.val.l == 0)
2508 emit_bnez(cd, iptr->dst.block, s1);
2510 LCONST(REG_ITMP2, iptr->sx.val.l);
2511 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2514 if (iptr->sx.val.l == 0) {
2515 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2516 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2517 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2520 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2521 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2522 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2523 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2524 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2525 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2526 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2527 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2532 case ICMD_IF_LGT: /* ..., value ==> ... */
2534 #if SIZEOF_VOID_P == 8
2535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2536 if (iptr->sx.val.l == 0)
2537 emit_bgtz(cd, iptr->dst.block, s1);
2539 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2540 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2541 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2544 LCONST(REG_ITMP2, iptr->sx.val.l);
2545 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2546 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2550 if (iptr->sx.val.l == 0) {
2551 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2552 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2553 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2555 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2558 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2559 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2560 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2561 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2562 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2563 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2565 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2566 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2567 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2572 case ICMD_IF_LGE: /* ..., value ==> ... */
2574 #if SIZEOF_VOID_P == 8
2575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2576 if (iptr->sx.val.l == 0)
2577 emit_bgez(cd, iptr->dst.block, s1);
2579 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2580 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2583 LCONST(REG_ITMP2, iptr->sx.val.l);
2584 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2586 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2589 if (iptr->sx.val.l == 0) {
2590 /* if high word is greater equal zero, the whole long is too */
2591 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2592 emit_bgez(cd, iptr->dst.block, s1);
2595 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2596 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2597 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2598 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2599 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2600 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2602 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2603 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2604 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2609 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2610 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2611 #if SIZEOF_VOID_P == 8
2612 case ICMD_IF_LCMPEQ:
2615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2616 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2617 emit_beq(cd, iptr->dst.block, s1, s2);
2620 #if SIZEOF_VOID_P == 4
2621 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2622 /* op1 = target JavaVM pc */
2624 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2625 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2626 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2628 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2629 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2630 emit_beq(cd, iptr->dst.block, s1, s2);
2634 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2635 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2636 #if SIZEOF_VOID_P == 8
2637 case ICMD_IF_LCMPNE:
2640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2641 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2642 emit_bne(cd, iptr->dst.block, s1, s2);
2645 #if SIZEOF_VOID_P == 4
2646 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2648 /* TODO: could be optimized (XOR or SUB) */
2649 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2650 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2651 emit_bne(cd, iptr->dst.block, s1, s2);
2652 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2653 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2654 emit_bne(cd, iptr->dst.block, s1, s2);
2658 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2659 #if SIZEOF_VOID_P == 8
2660 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2664 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2665 M_CMPLT(s1, s2, REG_ITMP3);
2666 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2669 #if SIZEOF_VOID_P == 4
2670 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2672 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2673 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2674 M_CMPLT(s1, s2, REG_ITMP3);
2675 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2676 M_CMPGT(s1, s2, REG_ITMP3);
2677 /* load low-bits before the branch, so we know the distance */
2678 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2679 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2680 M_BNEZ(REG_ITMP3, 4); /* XXX */
2682 M_CMPULT(s1, s2, REG_ITMP3);
2683 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2687 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2688 #if SIZEOF_VOID_P == 8
2689 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2692 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2693 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2694 M_CMPGT(s1, s2, REG_ITMP3);
2695 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2698 #if SIZEOF_VOID_P == 4
2699 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2701 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2702 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2703 M_CMPGT(s1, s2, REG_ITMP3);
2704 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2705 M_CMPLT(s1, s2, REG_ITMP3);
2706 /* load low-bits before the branch, so we know the distance */
2707 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2708 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2709 M_BNEZ(REG_ITMP3, 4); /* XXX */
2711 M_CMPUGT(s1, s2, REG_ITMP3);
2712 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2716 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2717 #if SIZEOF_VOID_P == 8
2718 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2722 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2723 M_CMPGT(s1, s2, REG_ITMP3);
2724 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2727 #if SIZEOF_VOID_P == 4
2728 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2730 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2731 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2732 M_CMPLT(s1, s2, REG_ITMP3);
2733 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2734 M_CMPGT(s1, s2, REG_ITMP3);
2735 /* load low-bits before the branch, so we know the distance */
2736 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2737 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2738 M_BNEZ(REG_ITMP3, 4); /* XXX */
2740 M_CMPUGT(s1, s2, REG_ITMP3);
2741 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2745 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2746 #if SIZEOF_VOID_P == 8
2747 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2752 M_CMPLT(s1, s2, REG_ITMP3);
2753 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2756 #if SIZEOF_VOID_P == 4
2757 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2759 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2760 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2761 M_CMPGT(s1, s2, REG_ITMP3);
2762 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2763 M_CMPLT(s1, s2, REG_ITMP3);
2764 /* load low-bits before the branch, so we know the distance */
2765 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2766 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2767 M_BNEZ(REG_ITMP3, 4); /* XXX */
2769 M_CMPULT(s1, s2, REG_ITMP3);
2770 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2774 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2775 #if SIZEOF_VOID_P == 8
2779 REPLACEMENT_POINT_RETURN(cd, iptr);
2780 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2781 M_INTMOVE(s1, REG_RESULT);
2782 goto nowperformreturn;
2784 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2786 REPLACEMENT_POINT_RETURN(cd, iptr);
2787 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2788 M_INTMOVE(s1, REG_RESULT);
2790 #ifdef ENABLE_VERIFIER
2791 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2792 uc = iptr->sx.s23.s2.uc;
2794 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2796 #endif /* ENABLE_VERIFIER */
2797 goto nowperformreturn;
2799 #if SIZEOF_VOID_P == 4
2800 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2802 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2803 M_LNGMOVE(s1, REG_RESULT_PACKED);
2804 goto nowperformreturn;
2807 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2808 REPLACEMENT_POINT_RETURN(cd, iptr);
2809 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2810 M_FLTMOVE(s1, REG_FRESULT);
2811 goto nowperformreturn;
2813 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2815 REPLACEMENT_POINT_RETURN(cd, iptr);
2816 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2817 M_DBLMOVE(s1, REG_FRESULT);
2818 goto nowperformreturn;
2820 case ICMD_RETURN: /* ... ==> ... */
2822 REPLACEMENT_POINT_RETURN(cd, iptr);
2828 p = cd->stackframesize;
2830 #if !defined(NDEBUG)
2831 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2832 emit_verbosecall_exit(jd);
2835 #if defined(ENABLE_THREADS)
2836 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2837 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2838 M_ALD(REG_ITMP3, REG_PV, disp);
2840 /* we need to save the proper return value */
2842 switch (iptr->opc) {
2845 #if SIZEOF_VOID_P == 8
2848 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2849 M_JSR(REG_RA, REG_ITMP3);
2850 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2852 #if SIZEOF_VOID_P == 4
2854 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2855 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2856 M_JSR(REG_RA, REG_ITMP3);
2862 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2863 M_JSR(REG_RA, REG_ITMP3);
2864 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2867 M_JSR(REG_RA, REG_ITMP3);
2868 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2872 /* and now restore the proper return value */
2874 switch (iptr->opc) {
2877 #if SIZEOF_VOID_P == 8
2880 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2882 #if SIZEOF_VOID_P == 4
2884 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2889 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2895 /* restore return address */
2897 if (!jd->isleafmethod) {
2898 p--; M_ALD(REG_RA, REG_SP, p * 8);
2901 /* restore saved registers */
2903 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2904 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2906 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2907 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2910 /* deallocate stack and return */
2912 if (cd->stackframesize) {
2915 disp = cd->stackframesize * 8;
2916 lo = (short) (disp);
2917 hi = (short) (((disp) - lo) >> 16);
2921 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2923 M_LUI(REG_ITMP3,hi);
2924 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2926 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2939 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2942 branch_target_t *table;
2944 table = iptr->dst.table;
2946 l = iptr->sx.s23.s2.tablelow;
2947 i = iptr->sx.s23.s3.tablehigh;
2949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2951 {M_INTMOVE(s1, REG_ITMP1);}
2952 else if (l <= 32768) {
2953 M_IADD_IMM(s1, -l, REG_ITMP1);
2956 ICONST(REG_ITMP2, l);
2957 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2960 /* number of targets */
2965 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2966 emit_beqz(cd, table[0].block, REG_ITMP2);
2968 /* build jump table top down and use address of lowest entry */
2973 dseg_add_target(cd, table->block);
2978 /* length of dataseg after last dseg_add_target is used by load */
2980 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2981 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2982 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2989 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2992 lookup_target_t *lookup;
2994 lookup = iptr->dst.lookup;
2996 i = iptr->sx.s23.s2.lookupcount;
2998 MCODECHECK((i<<2)+8);
2999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3002 ICONST(REG_ITMP2, lookup->value);
3003 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3007 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3013 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3015 bte = iptr->sx.s23.s3.bte;
3019 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3021 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3022 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3023 case ICMD_INVOKEINTERFACE:
3025 REPLACEMENT_POINT_INVOKE(cd, iptr);
3027 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3029 um = iptr->sx.s23.s3.um;
3030 md = um->methodref->parseddesc.md;
3033 lm = iptr->sx.s23.s3.fmiref->p.method;
3035 md = lm->parseddesc;
3039 s3 = md->paramcount;
3041 MCODECHECK((s3 << 1) + 64);
3043 /* copy arguments to registers or stack location */
3045 for (s3 = s3 - 1; s3 >= 0; s3--) {
3046 var = VAR(iptr->sx.s23.s2.args[s3]);
3047 d = md->params[s3].regoff;
3049 if (var->flags & PREALLOC)
3052 if (IS_INT_LNG_TYPE(var->type)) {
3053 #if SIZEOF_VOID_P == 8
3054 if (!md->params[s3].inmemory) {
3055 s1 = emit_load(jd, iptr, var, d);
3059 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3060 M_LST(s1, REG_SP, d);
3063 if (!md->params[s3].inmemory) {
3064 s1 = emit_load(jd, iptr, var, d);
3066 if (IS_2_WORD_TYPE(var->type))
3072 if (IS_2_WORD_TYPE(var->type)) {
3073 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3074 M_LST(s1, REG_SP, d);
3077 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3078 M_IST(s1, REG_SP, d);
3084 if (!md->params[s3].inmemory) {
3085 s1 = emit_load(jd, iptr, var, d);
3086 if (IS_2_WORD_TYPE(var->type))
3092 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3093 if (IS_2_WORD_TYPE(var->type))
3094 M_DST(s1, REG_SP, d);
3096 M_FST(s1, REG_SP, d);
3101 switch (iptr->opc) {
3103 disp = dseg_add_functionptr(cd, bte->fp);
3105 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3107 /* generate the actual call */
3109 /* TWISTI: i actually don't know the reason for using
3110 REG_ITMP3 here instead of REG_PV. */
3112 M_JSR(REG_RA, REG_ITMP3);
3114 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3115 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3116 M_LDA(REG_PV, REG_RA, -disp);
3118 emit_exception_check(cd, iptr);
3121 case ICMD_INVOKESPECIAL:
3122 emit_nullpointer_check(cd, iptr, REG_A0);
3125 case ICMD_INVOKESTATIC:
3127 disp = dseg_add_unique_address(cd, um);
3129 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3133 disp = dseg_add_address(cd, lm->stubroutine);
3135 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3137 /* generate the actual call */
3139 M_JSR(REG_RA, REG_PV);
3141 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3142 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3143 M_LDA(REG_PV, REG_RA, -disp);
3146 case ICMD_INVOKEVIRTUAL:
3147 emit_nullpointer_check(cd, iptr, REG_A0);
3150 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3155 s1 = OFFSET(vftbl_t, table[0]) +
3156 sizeof(methodptr) * lm->vftblindex;
3158 /* implicit null-pointer check */
3159 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3160 M_ALD(REG_PV, REG_METHODPTR, s1);
3162 /* generate the actual call */
3164 M_JSR(REG_RA, REG_PV);
3166 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3167 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3168 M_LDA(REG_PV, REG_RA, -disp);
3171 case ICMD_INVOKEINTERFACE:
3172 emit_nullpointer_check(cd, iptr, REG_A0);
3175 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3181 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3182 sizeof(methodptr*) * lm->class->index;
3184 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3187 /* implicit null-pointer check */
3188 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3189 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3190 M_ALD(REG_PV, REG_METHODPTR, s2);
3192 /* generate the actual call */
3194 M_JSR(REG_RA, REG_PV);
3196 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3197 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3198 M_LDA(REG_PV, REG_RA, -disp);
3202 /* store return value */
3204 d = md->returntype.type;
3206 if (d != TYPE_VOID) {
3207 if (IS_INT_LNG_TYPE(d)) {
3208 #if SIZEOF_VOID_P == 8
3209 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3210 M_INTMOVE(REG_RESULT, s1);
3212 if (IS_2_WORD_TYPE(d)) {
3213 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3214 M_LNGMOVE(REG_RESULT_PACKED, s1);
3217 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3218 M_INTMOVE(REG_RESULT, s1);
3223 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3224 if (IS_2_WORD_TYPE(d))
3225 M_DMOV(REG_FRESULT, s1);
3227 M_FMOV(REG_FRESULT, s1);
3229 emit_store_dst(jd, iptr, s1);
3234 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3236 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3240 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3245 super = iptr->sx.s23.s3.c.cls;
3246 superindex = super->index;
3249 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3250 CODEGEN_CRITICAL_SECTION_NEW;
3252 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3254 /* if class is not resolved, check which code to call */
3256 if (super == NULL) {
3257 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3259 cr = iptr->sx.s23.s3.c.ref;
3260 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3262 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3265 M_ILD(REG_ITMP2, REG_PV, disp);
3266 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3267 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3270 /* interface checkcast code */
3272 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3273 if (super == NULL) {
3274 cr = iptr->sx.s23.s3.c.ref;
3276 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3280 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3283 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3284 M_ILD(REG_ITMP3, REG_ITMP2,
3285 OFFSET(vftbl_t, interfacetablelength));
3286 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3287 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3289 M_ALD(REG_ITMP3, REG_ITMP2,
3290 OFFSET(vftbl_t, interfacetable[0]) -
3291 superindex * sizeof(methodptr*));
3292 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3295 emit_label_br(cd, BRANCH_LABEL_4);
3297 emit_label(cd, BRANCH_LABEL_3);
3300 /* class checkcast code */
3302 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3303 if (super == NULL) {
3304 emit_label(cd, BRANCH_LABEL_2);
3306 cr = iptr->sx.s23.s3.c.ref;
3307 disp = dseg_add_unique_address(cd, NULL);
3309 patcher_add_patch_ref(jd,
3310 PATCHER_resolve_classref_to_vftbl,
3314 disp = dseg_add_address(cd, super->vftbl);
3316 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3319 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3320 M_ALD(REG_ITMP3, REG_PV, disp);
3322 CODEGEN_CRITICAL_SECTION_START;
3324 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3325 /* if (s1 != REG_ITMP1) { */
3326 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3327 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3328 /* #if defined(ENABLE_THREADS) */
3329 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3331 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3333 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3334 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3335 M_ALD(REG_ITMP3, REG_PV, disp);
3336 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3338 CODEGEN_CRITICAL_SECTION_END;
3341 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3342 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3345 emit_label(cd, BRANCH_LABEL_5);
3348 if (super == NULL) {
3349 emit_label(cd, BRANCH_LABEL_1);
3350 emit_label(cd, BRANCH_LABEL_4);
3353 d = codegen_reg_of_dst(jd, iptr, s1);
3356 s1 = emit_load_s1(jd, iptr, REG_A0);
3357 M_INTMOVE(s1, REG_A0);
3359 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3360 cr = iptr->sx.s23.s3.c.ref;
3361 disp = dseg_add_unique_address(cd, NULL);
3363 patcher_add_patch_ref(jd,
3364 PATCHER_resolve_classref_to_classinfo,
3368 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3371 M_ALD(REG_A1, REG_PV, disp);
3372 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3373 M_ALD(REG_ITMP3, REG_PV, disp);
3374 M_JSR(REG_RA, REG_ITMP3);
3377 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3378 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3380 d = codegen_reg_of_dst(jd, iptr, s1);
3384 emit_store_dst(jd, iptr, d);
3387 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3393 super = iptr->sx.s23.s3.c.cls;
3395 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3400 super = iptr->sx.s23.s3.c.cls;
3401 superindex = super->index;
3404 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3405 CODEGEN_CRITICAL_SECTION_NEW;
3407 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3408 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3411 M_MOV(s1, REG_ITMP1);
3417 /* if class is not resolved, check which code to call */
3419 if (super == NULL) {
3420 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3422 cr = iptr->sx.s23.s3.c.ref;
3423 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3425 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3428 M_ILD(REG_ITMP3, REG_PV, disp);
3429 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3430 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3433 /* interface instanceof code */
3435 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3436 if (super == NULL) {
3437 cr = iptr->sx.s23.s3.c.ref;
3439 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3443 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3446 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3447 M_ILD(REG_ITMP3, REG_ITMP1,
3448 OFFSET(vftbl_t, interfacetablelength));
3449 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3450 M_BLEZ(REG_ITMP3, 3);
3452 M_ALD(REG_ITMP1, REG_ITMP1,
3453 OFFSET(vftbl_t, interfacetable[0]) -
3454 superindex * sizeof(methodptr*));
3455 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3458 emit_label_br(cd, BRANCH_LABEL_4);
3460 emit_label(cd, BRANCH_LABEL_3);
3463 /* class instanceof code */
3465 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3466 if (super == NULL) {
3467 emit_label(cd, BRANCH_LABEL_2);
3469 cr = iptr->sx.s23.s3.c.ref;
3470 disp = dseg_add_unique_address(cd, NULL);
3472 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3476 disp = dseg_add_address(cd, super->vftbl);
3478 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3481 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3482 M_ALD(REG_ITMP2, REG_PV, disp);
3484 CODEGEN_CRITICAL_SECTION_START;
3486 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3487 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3488 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3490 CODEGEN_CRITICAL_SECTION_END;
3492 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3493 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3497 emit_label(cd, BRANCH_LABEL_5);
3500 if (super == NULL) {
3501 emit_label(cd, BRANCH_LABEL_1);
3502 emit_label(cd, BRANCH_LABEL_4);
3505 emit_store_dst(jd, iptr, d);
3509 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3511 /* check for negative sizes and copy sizes to stack if necessary */
3513 MCODECHECK((iptr->s1.argcount << 1) + 64);
3515 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3517 var = VAR(iptr->sx.s23.s2.args[s1]);
3519 /* copy SAVEDVAR sizes to stack */
3521 if (!(var->flags & PREALLOC)) {
3522 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3523 #if SIZEOF_VOID_P == 8
3524 M_LST(s2, REG_SP, s1 * 8);
3526 M_IST(s2, REG_SP, (s1 + 2) * 8);
3531 /* a0 = dimension count */
3533 ICONST(REG_A0, iptr->s1.argcount);
3535 /* is patcher function set? */
3537 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3538 cr = iptr->sx.s23.s3.c.ref;
3539 disp = dseg_add_unique_address(cd, NULL);
3541 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3545 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3548 /* a1 = arraydescriptor */
3550 M_ALD(REG_A1, REG_PV, disp);
3552 /* a2 = pointer to dimensions = stack pointer */
3554 #if SIZEOF_VOID_P == 8
3555 M_MOV(REG_SP, REG_A2);
3557 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3560 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3561 M_ALD(REG_ITMP3, REG_PV, disp);
3562 M_JSR(REG_RA, REG_ITMP3);
3565 /* check for exception before result assignment */
3567 emit_exception_check(cd, iptr);
3569 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3570 M_INTMOVE(REG_RESULT, d);
3571 emit_store_dst(jd, iptr, d);
3575 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3580 } /* for instruction */
3582 MCODECHECK(64); /* XXX require smaller number? */
3584 /* At the end of a basic block we may have to append some nops,
3585 because the patcher stub calling code might be longer than the
3586 actual instruction. So codepatching does not change the
3587 following block unintentionally. */
3589 if (cd->mcodeptr < cd->lastmcodeptr) {
3590 while (cd->mcodeptr < cd->lastmcodeptr)
3594 } /* if (bptr -> flags >= BBREACHED) */
3595 } /* for basic block */
3597 dseg_createlinenumbertable(cd);
3599 /* generate traps */
3601 emit_patcher_traps(jd);
3603 /* everything's ok */
3609 /* codegen_emit_stub_compiler **************************************************
3611 Emits a stub routine which calls the compiler.
3613 *******************************************************************************/
3615 void codegen_emit_stub_compiler(jitdata *jd)
3620 /* get required compiler data */
3625 /* code for the stub */
3627 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3628 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3634 /* codegen_emit_stub_native ****************************************************
3636 Emits a stub routine which calls a native method.
3638 *******************************************************************************/
3640 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3650 s4 funcdisp; /* displacement of the function */
3652 /* get required compiler data */
3658 /* initialize variables */
3661 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3663 /* calculate stack frame size */
3665 cd->stackframesize =
3666 1 + /* return address */
3667 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3668 sizeof(localref_table) / SIZEOF_VOID_P +
3669 md->paramcount + /* for saving arguments over calls */
3670 #if SIZEOF_VOID_P == 4
3671 5 + /* additional save space (MIPS32) */
3673 1 + /* for saving return address */
3676 /* adjust stackframe size for 16-byte alignment */
3678 if (cd->stackframesize & 1)
3679 cd->stackframesize++;
3681 /* create method header */
3683 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3684 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3685 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3686 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3687 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3688 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3689 (void) dseg_addlinenumbertablesize(cd);
3690 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3692 /* generate stub code */
3694 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3695 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3697 #if !defined(NDEBUG)
3698 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3699 emit_verbosecall_enter(jd);
3702 /* get function address (this must happen before the stackframeinfo) */
3704 funcdisp = dseg_add_functionptr(cd, f);
3706 #if !defined(WITH_STATIC_CLASSPATH)
3708 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3711 /* save integer and float argument registers */
3713 #if SIZEOF_VOID_P == 8
3714 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3715 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3716 s1 = md->params[i].regoff;
3717 M_AST(s1, REG_SP, j * 8);
3722 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3723 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3724 if (!md->params[i].inmemory) {
3725 s1 = md->params[i].regoff;
3727 if (IS_2_WORD_TYPE(md->params[i].type))
3728 M_LST(s1, REG_SP, j * 8);
3730 M_IST(s1, REG_SP, j * 8);
3738 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3739 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3740 s1 = md->params[i].regoff;
3742 if (IS_2_WORD_TYPE(md->params[i].type))
3743 M_DST(s1, REG_SP, j * 8);
3745 M_FST(s1, REG_SP, j * 8);
3751 /* prepare data structures for native function call */
3753 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3754 M_MOV(REG_PV, REG_A1);
3755 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3756 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
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 /* restore integer and float argument registers */
3764 #if SIZEOF_VOID_P == 8
3765 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3766 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3767 s1 = md->params[i].regoff;
3768 M_LLD(s1, REG_SP, j * 8);
3773 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3774 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3775 if (!md->params[i].inmemory) {
3776 s1 = md->params[i].regoff;
3778 if (IS_2_WORD_TYPE(md->params[i].type))
3779 M_LLD(s1, REG_SP, j * 8);
3781 M_ILD(s1, REG_SP, j * 8);
3789 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3790 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3791 s1 = md->params[i].regoff;
3793 if (IS_2_WORD_TYPE(md->params[i].type))
3794 M_DLD(s1, REG_SP, j * 8);
3796 M_FLD(s1, REG_SP, j * 8);
3802 /* copy or spill arguments to new locations */
3804 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3805 t = md->params[i].type;
3807 if (IS_INT_LNG_TYPE(t)) {
3808 if (!md->params[i].inmemory) {
3809 s1 = md->params[i].regoff;
3810 s2 = nmd->params[j].regoff;
3812 if (!nmd->params[j].inmemory) {
3813 #if SIZEOF_VOID_P == 8
3816 if (IS_2_WORD_TYPE(t))
3823 #if SIZEOF_VOID_P == 8
3824 M_LST(s1, REG_SP, s2);
3826 if (IS_2_WORD_TYPE(t))
3827 M_LST(s1, REG_SP, s2);
3829 M_IST(s1, REG_SP, s2);
3834 s1 = md->params[i].regoff + cd->stackframesize * 8;
3835 s2 = nmd->params[j].regoff;
3837 #if SIZEOF_VOID_P == 8
3838 M_LLD(REG_ITMP1, REG_SP, s1);
3839 M_LST(REG_ITMP1, REG_SP, s2);
3841 if (IS_2_WORD_TYPE(t)) {
3842 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3843 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3846 M_ILD(REG_ITMP1, REG_SP, s1);
3847 M_IST(REG_ITMP1, REG_SP, s2);
3853 if (!md->params[i].inmemory) {
3854 s1 = md->params[i].regoff;
3855 s2 = nmd->params[j].regoff;
3857 if (!nmd->params[j].inmemory) {
3858 #if SIZEOF_VOID_P == 8
3859 if (IS_2_WORD_TYPE(t))
3864 /* On MIPS32 float arguments for native functions
3865 can never be in float argument registers, since
3866 the first argument is _always_ an integer
3867 argument (JNIEnv) */
3869 if (IS_2_WORD_TYPE(t)) {
3870 /* double high/low order is endian
3871 independent: even numbered holds low
3872 32-bits, odd numbered high 32-bits */
3874 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3875 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3882 #if SIZEOF_VOID_P == 8
3883 if (IS_2_WORD_TYPE(t))
3884 M_DST(s1, REG_SP, s2);
3886 M_FST(s1, REG_SP, s2);
3888 /* s1 may have been originally in 2 int registers,
3889 but was moved out by the native function
3890 argument(s), just get low register */
3892 if (IS_2_WORD_TYPE(t))
3893 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3895 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3900 s1 = md->params[i].regoff + cd->stackframesize * 8;
3901 s2 = nmd->params[j].regoff;
3903 #if SIZEOF_VOID_P == 8
3904 if (IS_2_WORD_TYPE(t)) {
3905 M_DLD(REG_FTMP1, REG_SP, s1);
3906 M_DST(REG_FTMP1, REG_SP, s2);
3909 M_FLD(REG_FTMP1, REG_SP, s1);
3910 M_FST(REG_FTMP1, REG_SP, s2);
3913 if (IS_2_WORD_TYPE(t)) {
3914 M_DLD(REG_FTMP1, REG_SP, s1);
3915 M_DST(REG_FTMP1, REG_SP, s2);
3918 M_FLD(REG_FTMP1, REG_SP, s1);
3919 M_FST(REG_FTMP1, REG_SP, s2);
3926 /* put class into second argument register */
3928 if (m->flags & ACC_STATIC) {
3929 disp = dseg_add_address(cd, m->class);
3930 M_ALD(REG_A1, REG_PV, disp);
3933 /* put env into first argument register */
3935 disp = dseg_add_address(cd, _Jv_env);
3936 M_ALD(REG_A0, REG_PV, disp);
3938 /* do the native function call */
3940 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3941 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3942 M_NOP; /* delay slot */
3944 /* save return value */
3946 switch (md->returntype.type) {
3947 #if SIZEOF_VOID_P == 8
3951 M_LST(REG_RESULT, REG_SP, 0 * 8);
3955 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3960 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
3963 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
3967 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
3974 #if !defined(NDEBUG)
3975 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3976 emit_verbosecall_exit(jd);
3979 /* remove native stackframe info */
3981 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3982 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3983 M_ALD(REG_ITMP3, REG_PV, disp);
3984 M_JSR(REG_RA, REG_ITMP3);
3985 M_NOP; /* XXX fill me! */
3986 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3988 /* restore return value */
3990 switch (md->returntype.type) {
3991 #if SIZEOF_VOID_P == 8
3995 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3999 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4004 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4007 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4011 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4018 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4020 /* check for exception */
4022 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4023 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4025 M_RET(REG_RA); /* return to caller */
4026 M_NOP; /* DELAY SLOT */
4028 /* handle exception */
4030 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4031 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4032 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4033 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4035 /* Generate patcher traps. */
4037 emit_patcher_traps(jd);
4042 * These are local overrides for various environment variables in Emacs.
4043 * Please do not remove this and leave it at the end of the file, where
4044 * Emacs will automagically detect them.
4045 * ---------------------------------------------------------------------
4048 * indent-tabs-mode: t
4052 * vim:noexpandtab:sw=4:ts=4: