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 8264 2007-08-06 16:02:28Z 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: /* ... ==> ... */
2084 /* val = value (in current instruction) */
2085 /* following NOP) */
2087 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2088 uf = iptr->sx.s23.s3.uf;
2089 fieldtype = uf->fieldref->parseddesc.fd->type;
2090 disp = dseg_add_unique_address(cd, uf);
2092 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2095 fi = iptr->sx.s23.s3.fmiref->p.field;
2096 fieldtype = fi->type;
2097 disp = dseg_add_address(cd, &(fi->value));
2099 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2100 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2104 M_ALD(REG_ITMP1, REG_PV, disp);
2106 switch (fieldtype) {
2108 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2111 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2114 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2117 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2120 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2126 case ICMD_GETFIELD: /* ... ==> ..., value */
2128 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2129 emit_nullpointer_check(cd, iptr, s1);
2131 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2132 uf = iptr->sx.s23.s3.uf;
2133 fieldtype = uf->fieldref->parseddesc.fd->type;
2136 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2139 fi = iptr->sx.s23.s3.fmiref->p.field;
2140 fieldtype = fi->type;
2144 switch (fieldtype) {
2146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2150 #if SIZEOF_VOID_P == 8
2151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2155 M_LLD_GETFIELD(d, s1, disp);
2159 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2163 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2167 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2171 emit_store_dst(jd, iptr, d);
2174 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2176 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2177 emit_nullpointer_check(cd, iptr, s1);
2179 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2180 uf = iptr->sx.s23.s3.uf;
2181 fieldtype = uf->fieldref->parseddesc.fd->type;
2185 fi = iptr->sx.s23.s3.fmiref->p.field;
2186 fieldtype = fi->type;
2190 #if SIZEOF_VOID_P == 8
2191 if (IS_INT_LNG_TYPE(fieldtype))
2192 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2194 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2196 if (IS_INT_LNG_TYPE(fieldtype)) {
2197 if (IS_2_WORD_TYPE(fieldtype))
2198 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2200 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2203 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2206 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2207 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2209 switch (fieldtype) {
2211 M_IST(s2, s1, disp);
2214 M_LST(s2, s1, disp);
2217 M_AST(s2, s1, disp);
2220 M_FST(s2, s1, disp);
2223 M_DST(s2, s1, disp);
2228 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2231 emit_nullpointer_check(cd, iptr, s1);
2233 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2234 unresolved_field *uf = iptr->sx.s23.s3.uf;
2236 fieldtype = uf->fieldref->parseddesc.fd->type;
2239 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2242 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2243 fieldtype = fi->type;
2247 switch (fieldtype) {
2249 M_IST(REG_ZERO, s1, disp);
2252 M_LST(REG_ZERO, s1, disp);
2255 M_AST(REG_ZERO, s1, disp);
2258 M_FST(REG_ZERO, s1, disp);
2261 M_DST(REG_ZERO, s1, disp);
2267 /* branch operations **************************************************/
2269 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2272 M_INTMOVE(s1, REG_ITMP1_XPTR);
2274 #ifdef ENABLE_VERIFIER
2275 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2276 uc = iptr->sx.s23.s2.uc;
2278 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2280 #endif /* ENABLE_VERIFIER */
2282 disp = dseg_add_functionptr(cd, asm_handle_exception);
2283 M_ALD(REG_ITMP2, REG_PV, disp);
2284 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2286 M_NOP; /* nop ensures that XPC is less than the end */
2287 /* of basic block */
2291 case ICMD_GOTO: /* ... ==> ... */
2292 case ICMD_RET: /* ... ==> ... */
2294 emit_br(cd, iptr->dst.block);
2298 case ICMD_JSR: /* ... ==> ... */
2300 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2304 case ICMD_IFNULL: /* ..., value ==> ... */
2305 case ICMD_IFNONNULL:
2307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2308 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2311 case ICMD_IFEQ: /* ..., value ==> ... */
2313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2314 if (iptr->sx.val.i == 0)
2315 emit_beqz(cd, iptr->dst.block, s1);
2317 ICONST(REG_ITMP2, iptr->sx.val.i);
2318 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2322 case ICMD_IFLT: /* ..., value ==> ... */
2324 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2325 if (iptr->sx.val.i == 0)
2326 emit_bltz(cd, iptr->dst.block, s1);
2328 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2329 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2331 ICONST(REG_ITMP2, iptr->sx.val.i);
2332 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2334 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2338 case ICMD_IFLE: /* ..., value ==> ... */
2340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2341 if (iptr->sx.val.i == 0)
2342 emit_blez(cd, iptr->dst.block, s1);
2344 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2345 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2346 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2349 ICONST(REG_ITMP2, iptr->sx.val.i);
2350 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2351 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2356 case ICMD_IFNE: /* ..., value ==> ... */
2358 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2359 if (iptr->sx.val.i == 0)
2360 emit_bnez(cd, iptr->dst.block, s1);
2362 ICONST(REG_ITMP2, iptr->sx.val.i);
2363 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2367 case ICMD_IFGT: /* ..., value ==> ... */
2369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2370 if (iptr->sx.val.i == 0)
2371 emit_bgtz(cd, iptr->dst.block, s1);
2373 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2374 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2375 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2378 ICONST(REG_ITMP2, iptr->sx.val.i);
2379 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2380 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2385 case ICMD_IFGE: /* ..., value ==> ... */
2387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2388 if (iptr->sx.val.i == 0)
2389 emit_bgez(cd, iptr->dst.block, s1);
2391 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2392 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2394 ICONST(REG_ITMP2, iptr->sx.val.i);
2395 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2397 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2401 case ICMD_IF_LEQ: /* ..., value ==> ... */
2403 #if SIZEOF_VOID_P == 8
2404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2405 if (iptr->sx.val.l == 0)
2406 emit_beqz(cd, iptr->dst.block, s1);
2408 LCONST(REG_ITMP2, iptr->sx.val.l);
2409 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2412 if (iptr->sx.val.l == 0) {
2413 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2414 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2415 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2418 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2419 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2420 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2421 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2422 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2423 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2424 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2425 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2430 case ICMD_IF_LLT: /* ..., value ==> ... */
2432 #if SIZEOF_VOID_P == 8
2433 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2434 if (iptr->sx.val.l == 0)
2435 emit_bltz(cd, iptr->dst.block, s1);
2437 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2438 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2440 LCONST(REG_ITMP2, iptr->sx.val.l);
2441 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2443 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2446 if (iptr->sx.val.l == 0) {
2447 /* if high word is less than zero, the whole long is too */
2448 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2449 emit_bltz(cd, iptr->dst.block, s1);
2452 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2453 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2454 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2455 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2456 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2457 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2459 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2460 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2461 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2466 case ICMD_IF_LLE: /* ..., value ==> ... */
2468 #if SIZEOF_VOID_P == 8
2469 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2470 if (iptr->sx.val.l == 0)
2471 emit_blez(cd, iptr->dst.block, s1);
2473 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2474 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2475 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2478 LCONST(REG_ITMP2, iptr->sx.val.l);
2479 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2480 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2484 if (iptr->sx.val.l == 0) {
2485 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2486 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2488 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2489 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2492 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2493 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2494 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2495 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2496 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2497 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2499 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2500 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2501 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2506 case ICMD_IF_LNE: /* ..., value ==> ... */
2508 #if SIZEOF_VOID_P == 8
2509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2510 if (iptr->sx.val.l == 0)
2511 emit_bnez(cd, iptr->dst.block, s1);
2513 LCONST(REG_ITMP2, iptr->sx.val.l);
2514 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2517 if (iptr->sx.val.l == 0) {
2518 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2519 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2520 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2523 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2524 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2525 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2526 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2527 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2528 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2529 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2530 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2535 case ICMD_IF_LGT: /* ..., value ==> ... */
2537 #if SIZEOF_VOID_P == 8
2538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2539 if (iptr->sx.val.l == 0)
2540 emit_bgtz(cd, iptr->dst.block, s1);
2542 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2543 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2544 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2547 LCONST(REG_ITMP2, iptr->sx.val.l);
2548 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2549 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2553 if (iptr->sx.val.l == 0) {
2554 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2555 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2556 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2558 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2561 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2562 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2563 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2564 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2565 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2566 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2568 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2569 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2570 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2575 case ICMD_IF_LGE: /* ..., value ==> ... */
2577 #if SIZEOF_VOID_P == 8
2578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2579 if (iptr->sx.val.l == 0)
2580 emit_bgez(cd, iptr->dst.block, s1);
2582 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2583 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2586 LCONST(REG_ITMP2, iptr->sx.val.l);
2587 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2589 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2592 if (iptr->sx.val.l == 0) {
2593 /* if high word is greater equal zero, the whole long is too */
2594 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2595 emit_bgez(cd, iptr->dst.block, s1);
2598 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2599 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2600 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2601 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2602 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2603 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2605 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2606 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2607 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2612 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2613 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2614 #if SIZEOF_VOID_P == 8
2615 case ICMD_IF_LCMPEQ:
2618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2620 emit_beq(cd, iptr->dst.block, s1, s2);
2623 #if SIZEOF_VOID_P == 4
2624 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2625 /* op1 = target JavaVM pc */
2627 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2628 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2629 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2631 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2632 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2633 emit_beq(cd, iptr->dst.block, s1, s2);
2637 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2638 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2639 #if SIZEOF_VOID_P == 8
2640 case ICMD_IF_LCMPNE:
2643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2644 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2645 emit_bne(cd, iptr->dst.block, s1, s2);
2648 #if SIZEOF_VOID_P == 4
2649 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2651 /* TODO: could be optimized (XOR or SUB) */
2652 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2653 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2654 emit_bne(cd, iptr->dst.block, s1, s2);
2655 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2656 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2657 emit_bne(cd, iptr->dst.block, s1, s2);
2661 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2662 #if SIZEOF_VOID_P == 8
2663 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2667 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2668 M_CMPLT(s1, s2, REG_ITMP3);
2669 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2672 #if SIZEOF_VOID_P == 4
2673 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2675 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2676 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2677 M_CMPLT(s1, s2, REG_ITMP3);
2678 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2679 M_CMPGT(s1, s2, REG_ITMP3);
2680 /* load low-bits before the branch, so we know the distance */
2681 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2682 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2683 M_BNEZ(REG_ITMP3, 4); /* XXX */
2685 M_CMPULT(s1, s2, REG_ITMP3);
2686 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2690 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2691 #if SIZEOF_VOID_P == 8
2692 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2697 M_CMPGT(s1, s2, REG_ITMP3);
2698 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2701 #if SIZEOF_VOID_P == 4
2702 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2704 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2705 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2706 M_CMPGT(s1, s2, REG_ITMP3);
2707 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2708 M_CMPLT(s1, s2, REG_ITMP3);
2709 /* load low-bits before the branch, so we know the distance */
2710 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2711 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2712 M_BNEZ(REG_ITMP3, 4); /* XXX */
2714 M_CMPUGT(s1, s2, REG_ITMP3);
2715 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2719 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2720 #if SIZEOF_VOID_P == 8
2721 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2726 M_CMPGT(s1, s2, REG_ITMP3);
2727 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2730 #if SIZEOF_VOID_P == 4
2731 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2733 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2734 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2735 M_CMPLT(s1, s2, REG_ITMP3);
2736 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2737 M_CMPGT(s1, s2, REG_ITMP3);
2738 /* load low-bits before the branch, so we know the distance */
2739 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2740 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2741 M_BNEZ(REG_ITMP3, 4); /* XXX */
2743 M_CMPUGT(s1, s2, REG_ITMP3);
2744 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2748 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2749 #if SIZEOF_VOID_P == 8
2750 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2755 M_CMPLT(s1, s2, REG_ITMP3);
2756 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2759 #if SIZEOF_VOID_P == 4
2760 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2762 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2763 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2764 M_CMPGT(s1, s2, REG_ITMP3);
2765 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2766 M_CMPLT(s1, s2, REG_ITMP3);
2767 /* load low-bits before the branch, so we know the distance */
2768 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2769 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2770 M_BNEZ(REG_ITMP3, 4); /* XXX */
2772 M_CMPULT(s1, s2, REG_ITMP3);
2773 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2777 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2778 #if SIZEOF_VOID_P == 8
2782 REPLACEMENT_POINT_RETURN(cd, iptr);
2783 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2784 M_INTMOVE(s1, REG_RESULT);
2785 goto nowperformreturn;
2787 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2789 REPLACEMENT_POINT_RETURN(cd, iptr);
2790 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2791 M_INTMOVE(s1, REG_RESULT);
2793 #ifdef ENABLE_VERIFIER
2794 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2795 uc = iptr->sx.s23.s2.uc;
2797 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2799 #endif /* ENABLE_VERIFIER */
2800 goto nowperformreturn;
2802 #if SIZEOF_VOID_P == 4
2803 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2805 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2806 M_LNGMOVE(s1, REG_RESULT_PACKED);
2807 goto nowperformreturn;
2810 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2811 REPLACEMENT_POINT_RETURN(cd, iptr);
2812 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2813 M_FLTMOVE(s1, REG_FRESULT);
2814 goto nowperformreturn;
2816 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2818 REPLACEMENT_POINT_RETURN(cd, iptr);
2819 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2820 M_DBLMOVE(s1, REG_FRESULT);
2821 goto nowperformreturn;
2823 case ICMD_RETURN: /* ... ==> ... */
2825 REPLACEMENT_POINT_RETURN(cd, iptr);
2831 p = cd->stackframesize;
2833 #if !defined(NDEBUG)
2834 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2835 emit_verbosecall_exit(jd);
2838 #if defined(ENABLE_THREADS)
2839 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2840 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2841 M_ALD(REG_ITMP3, REG_PV, disp);
2843 /* we need to save the proper return value */
2845 switch (iptr->opc) {
2848 #if SIZEOF_VOID_P == 8
2851 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2852 M_JSR(REG_RA, REG_ITMP3);
2853 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2855 #if SIZEOF_VOID_P == 4
2857 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2858 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2859 M_JSR(REG_RA, REG_ITMP3);
2865 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2866 M_JSR(REG_RA, REG_ITMP3);
2867 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2870 M_JSR(REG_RA, REG_ITMP3);
2871 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2875 /* and now restore the proper return value */
2877 switch (iptr->opc) {
2880 #if SIZEOF_VOID_P == 8
2883 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2885 #if SIZEOF_VOID_P == 4
2887 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2892 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2898 /* restore return address */
2900 if (!jd->isleafmethod) {
2901 p--; M_ALD(REG_RA, REG_SP, p * 8);
2904 /* restore saved registers */
2906 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2907 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2909 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2910 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2913 /* deallocate stack and return */
2915 if (cd->stackframesize) {
2918 disp = cd->stackframesize * 8;
2919 lo = (short) (disp);
2920 hi = (short) (((disp) - lo) >> 16);
2924 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2926 M_LUI(REG_ITMP3,hi);
2927 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2929 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2942 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2945 branch_target_t *table;
2947 table = iptr->dst.table;
2949 l = iptr->sx.s23.s2.tablelow;
2950 i = iptr->sx.s23.s3.tablehigh;
2952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2954 {M_INTMOVE(s1, REG_ITMP1);}
2955 else if (l <= 32768) {
2956 M_IADD_IMM(s1, -l, REG_ITMP1);
2959 ICONST(REG_ITMP2, l);
2960 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2963 /* number of targets */
2968 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2969 emit_beqz(cd, table[0].block, REG_ITMP2);
2971 /* build jump table top down and use address of lowest entry */
2976 dseg_add_target(cd, table->block);
2981 /* length of dataseg after last dseg_add_target is used by load */
2983 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2984 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2985 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2992 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2995 lookup_target_t *lookup;
2997 lookup = iptr->dst.lookup;
2999 i = iptr->sx.s23.s2.lookupcount;
3001 MCODECHECK((i<<2)+8);
3002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3005 ICONST(REG_ITMP2, lookup->value);
3006 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3010 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3016 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3018 bte = iptr->sx.s23.s3.bte;
3022 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3024 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3025 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3026 case ICMD_INVOKEINTERFACE:
3028 REPLACEMENT_POINT_INVOKE(cd, iptr);
3030 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3032 um = iptr->sx.s23.s3.um;
3033 md = um->methodref->parseddesc.md;
3036 lm = iptr->sx.s23.s3.fmiref->p.method;
3038 md = lm->parseddesc;
3042 s3 = md->paramcount;
3044 MCODECHECK((s3 << 1) + 64);
3046 /* copy arguments to registers or stack location */
3048 for (s3 = s3 - 1; s3 >= 0; s3--) {
3049 var = VAR(iptr->sx.s23.s2.args[s3]);
3050 d = md->params[s3].regoff;
3052 if (var->flags & PREALLOC)
3055 if (IS_INT_LNG_TYPE(var->type)) {
3056 #if SIZEOF_VOID_P == 8
3057 if (!md->params[s3].inmemory) {
3058 s1 = emit_load(jd, iptr, var, d);
3062 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3063 M_LST(s1, REG_SP, d);
3066 if (!md->params[s3].inmemory) {
3067 s1 = emit_load(jd, iptr, var, d);
3069 if (IS_2_WORD_TYPE(var->type))
3075 if (IS_2_WORD_TYPE(var->type)) {
3076 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3077 M_LST(s1, REG_SP, d);
3080 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3081 M_IST(s1, REG_SP, d);
3087 if (!md->params[s3].inmemory) {
3088 s1 = emit_load(jd, iptr, var, d);
3089 if (IS_2_WORD_TYPE(var->type))
3095 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3096 if (IS_2_WORD_TYPE(var->type))
3097 M_DST(s1, REG_SP, d);
3099 M_FST(s1, REG_SP, d);
3104 switch (iptr->opc) {
3106 disp = dseg_add_functionptr(cd, bte->fp);
3108 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3110 /* generate the actual call */
3112 /* TWISTI: i actually don't know the reason for using
3113 REG_ITMP3 here instead of REG_PV. */
3115 M_JSR(REG_RA, REG_ITMP3);
3117 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3118 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3119 M_LDA(REG_PV, REG_RA, -disp);
3121 emit_exception_check(cd, iptr);
3124 case ICMD_INVOKESPECIAL:
3125 emit_nullpointer_check(cd, iptr, REG_A0);
3128 case ICMD_INVOKESTATIC:
3130 disp = dseg_add_unique_address(cd, um);
3132 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3136 disp = dseg_add_address(cd, lm->stubroutine);
3138 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3140 /* generate the actual call */
3142 M_JSR(REG_RA, REG_PV);
3144 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3145 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3146 M_LDA(REG_PV, REG_RA, -disp);
3149 case ICMD_INVOKEVIRTUAL:
3150 emit_nullpointer_check(cd, iptr, REG_A0);
3153 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3158 s1 = OFFSET(vftbl_t, table[0]) +
3159 sizeof(methodptr) * lm->vftblindex;
3161 /* implicit null-pointer check */
3162 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3163 M_ALD(REG_PV, REG_METHODPTR, s1);
3165 /* generate the actual call */
3167 M_JSR(REG_RA, REG_PV);
3169 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3170 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3171 M_LDA(REG_PV, REG_RA, -disp);
3174 case ICMD_INVOKEINTERFACE:
3175 emit_nullpointer_check(cd, iptr, REG_A0);
3178 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3184 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3185 sizeof(methodptr*) * lm->class->index;
3187 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3190 /* implicit null-pointer check */
3191 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3192 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3193 M_ALD(REG_PV, REG_METHODPTR, s2);
3195 /* generate the actual call */
3197 M_JSR(REG_RA, REG_PV);
3199 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3200 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3201 M_LDA(REG_PV, REG_RA, -disp);
3205 /* store return value */
3207 d = md->returntype.type;
3209 if (d != TYPE_VOID) {
3210 if (IS_INT_LNG_TYPE(d)) {
3211 #if SIZEOF_VOID_P == 8
3212 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3213 M_INTMOVE(REG_RESULT, s1);
3215 if (IS_2_WORD_TYPE(d)) {
3216 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3217 M_LNGMOVE(REG_RESULT_PACKED, s1);
3220 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3221 M_INTMOVE(REG_RESULT, s1);
3226 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3227 if (IS_2_WORD_TYPE(d))
3228 M_DMOV(REG_FRESULT, s1);
3230 M_FMOV(REG_FRESULT, s1);
3232 emit_store_dst(jd, iptr, s1);
3237 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3239 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3243 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3248 super = iptr->sx.s23.s3.c.cls;
3249 superindex = super->index;
3252 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3253 CODEGEN_CRITICAL_SECTION_NEW;
3255 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3257 /* if class is not resolved, check which code to call */
3259 if (super == NULL) {
3260 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3262 cr = iptr->sx.s23.s3.c.ref;
3263 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3265 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3268 M_ILD(REG_ITMP2, REG_PV, disp);
3269 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3270 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3273 /* interface checkcast code */
3275 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3276 if (super == NULL) {
3277 cr = iptr->sx.s23.s3.c.ref;
3279 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3283 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3286 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3287 M_ILD(REG_ITMP3, REG_ITMP2,
3288 OFFSET(vftbl_t, interfacetablelength));
3289 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3290 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3292 M_ALD(REG_ITMP3, REG_ITMP2,
3293 OFFSET(vftbl_t, interfacetable[0]) -
3294 superindex * sizeof(methodptr*));
3295 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3298 emit_label_br(cd, BRANCH_LABEL_4);
3300 emit_label(cd, BRANCH_LABEL_3);
3303 /* class checkcast code */
3305 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3306 if (super == NULL) {
3307 emit_label(cd, BRANCH_LABEL_2);
3309 cr = iptr->sx.s23.s3.c.ref;
3310 disp = dseg_add_unique_address(cd, NULL);
3312 patcher_add_patch_ref(jd,
3313 PATCHER_resolve_classref_to_vftbl,
3317 disp = dseg_add_address(cd, super->vftbl);
3319 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3322 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3323 M_ALD(REG_ITMP3, REG_PV, disp);
3325 CODEGEN_CRITICAL_SECTION_START;
3327 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3328 /* if (s1 != REG_ITMP1) { */
3329 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3330 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3331 /* #if defined(ENABLE_THREADS) */
3332 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3334 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3336 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3337 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3338 M_ALD(REG_ITMP3, REG_PV, disp);
3339 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3341 CODEGEN_CRITICAL_SECTION_END;
3344 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3345 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3348 emit_label(cd, BRANCH_LABEL_5);
3351 if (super == NULL) {
3352 emit_label(cd, BRANCH_LABEL_1);
3353 emit_label(cd, BRANCH_LABEL_4);
3356 d = codegen_reg_of_dst(jd, iptr, s1);
3359 s1 = emit_load_s1(jd, iptr, REG_A0);
3360 M_INTMOVE(s1, REG_A0);
3362 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3363 cr = iptr->sx.s23.s3.c.ref;
3364 disp = dseg_add_unique_address(cd, NULL);
3366 patcher_add_patch_ref(jd,
3367 PATCHER_resolve_classref_to_classinfo,
3371 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3374 M_ALD(REG_A1, REG_PV, disp);
3375 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3376 M_ALD(REG_ITMP3, REG_PV, disp);
3377 M_JSR(REG_RA, REG_ITMP3);
3380 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3381 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3383 d = codegen_reg_of_dst(jd, iptr, s1);
3387 emit_store_dst(jd, iptr, d);
3390 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3396 super = iptr->sx.s23.s3.c.cls;
3398 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3403 super = iptr->sx.s23.s3.c.cls;
3404 superindex = super->index;
3407 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3408 CODEGEN_CRITICAL_SECTION_NEW;
3410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3411 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3414 M_MOV(s1, REG_ITMP1);
3420 /* if class is not resolved, check which code to call */
3422 if (super == NULL) {
3423 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3425 cr = iptr->sx.s23.s3.c.ref;
3426 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3428 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3431 M_ILD(REG_ITMP3, REG_PV, disp);
3432 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3433 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3436 /* interface instanceof code */
3438 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3439 if (super == NULL) {
3440 cr = iptr->sx.s23.s3.c.ref;
3442 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3446 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3449 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3450 M_ILD(REG_ITMP3, REG_ITMP1,
3451 OFFSET(vftbl_t, interfacetablelength));
3452 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3453 M_BLEZ(REG_ITMP3, 3);
3455 M_ALD(REG_ITMP1, REG_ITMP1,
3456 OFFSET(vftbl_t, interfacetable[0]) -
3457 superindex * sizeof(methodptr*));
3458 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3461 emit_label_br(cd, BRANCH_LABEL_4);
3463 emit_label(cd, BRANCH_LABEL_3);
3466 /* class instanceof code */
3468 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3469 if (super == NULL) {
3470 emit_label(cd, BRANCH_LABEL_2);
3472 cr = iptr->sx.s23.s3.c.ref;
3473 disp = dseg_add_unique_address(cd, NULL);
3475 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3479 disp = dseg_add_address(cd, super->vftbl);
3481 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3484 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3485 M_ALD(REG_ITMP2, REG_PV, disp);
3487 CODEGEN_CRITICAL_SECTION_START;
3489 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3490 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3491 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3493 CODEGEN_CRITICAL_SECTION_END;
3495 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3496 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3500 emit_label(cd, BRANCH_LABEL_5);
3503 if (super == NULL) {
3504 emit_label(cd, BRANCH_LABEL_1);
3505 emit_label(cd, BRANCH_LABEL_4);
3508 emit_store_dst(jd, iptr, d);
3512 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3514 /* check for negative sizes and copy sizes to stack if necessary */
3516 MCODECHECK((iptr->s1.argcount << 1) + 64);
3518 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3520 var = VAR(iptr->sx.s23.s2.args[s1]);
3522 /* copy SAVEDVAR sizes to stack */
3524 if (!(var->flags & PREALLOC)) {
3525 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3526 #if SIZEOF_VOID_P == 8
3527 M_LST(s2, REG_SP, s1 * 8);
3529 M_IST(s2, REG_SP, (s1 + 2) * 8);
3534 /* a0 = dimension count */
3536 ICONST(REG_A0, iptr->s1.argcount);
3538 /* is patcher function set? */
3540 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3541 cr = iptr->sx.s23.s3.c.ref;
3542 disp = dseg_add_unique_address(cd, NULL);
3544 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3548 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3551 /* a1 = arraydescriptor */
3553 M_ALD(REG_A1, REG_PV, disp);
3555 /* a2 = pointer to dimensions = stack pointer */
3557 #if SIZEOF_VOID_P == 8
3558 M_MOV(REG_SP, REG_A2);
3560 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3563 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3564 M_ALD(REG_ITMP3, REG_PV, disp);
3565 M_JSR(REG_RA, REG_ITMP3);
3568 /* check for exception before result assignment */
3570 emit_exception_check(cd, iptr);
3572 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3573 M_INTMOVE(REG_RESULT, d);
3574 emit_store_dst(jd, iptr, d);
3578 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3583 } /* for instruction */
3585 MCODECHECK(64); /* XXX require smaller number? */
3587 /* At the end of a basic block we may have to append some nops,
3588 because the patcher stub calling code might be longer than the
3589 actual instruction. So codepatching does not change the
3590 following block unintentionally. */
3592 if (cd->mcodeptr < cd->lastmcodeptr) {
3593 while (cd->mcodeptr < cd->lastmcodeptr)
3597 } /* if (bptr -> flags >= BBREACHED) */
3598 } /* for basic block */
3600 dseg_createlinenumbertable(cd);
3602 /* generate traps */
3604 emit_patcher_traps(jd);
3606 /* everything's ok */
3612 /* codegen_emit_stub_compiler **************************************************
3614 Emits a stub routine which calls the compiler.
3616 *******************************************************************************/
3618 void codegen_emit_stub_compiler(jitdata *jd)
3623 /* get required compiler data */
3628 /* code for the stub */
3630 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3631 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3637 /* codegen_emit_stub_native ****************************************************
3639 Emits a stub routine which calls a native method.
3641 *******************************************************************************/
3643 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3653 s4 funcdisp; /* displacement of the function */
3655 /* get required compiler data */
3661 /* initialize variables */
3664 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3666 /* calculate stack frame size */
3668 cd->stackframesize =
3669 1 + /* return address */
3670 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3671 sizeof(localref_table) / SIZEOF_VOID_P +
3672 md->paramcount + /* for saving arguments over calls */
3673 #if SIZEOF_VOID_P == 4
3674 5 + /* additional save space (MIPS32) */
3676 1 + /* for saving return address */
3679 /* adjust stackframe size for 16-byte alignment */
3681 if (cd->stackframesize & 1)
3682 cd->stackframesize++;
3684 /* create method header */
3686 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3687 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3688 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3689 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3690 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3691 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3692 (void) dseg_addlinenumbertablesize(cd);
3693 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3695 /* generate stub code */
3697 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3698 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3700 #if !defined(NDEBUG)
3701 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3702 emit_verbosecall_enter(jd);
3705 /* get function address (this must happen before the stackframeinfo) */
3707 funcdisp = dseg_add_functionptr(cd, f);
3709 #if !defined(WITH_STATIC_CLASSPATH)
3711 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3714 /* save integer and float argument registers */
3716 #if SIZEOF_VOID_P == 8
3717 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3718 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3719 s1 = md->params[i].regoff;
3720 M_AST(s1, REG_SP, j * 8);
3725 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3726 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3727 if (!md->params[i].inmemory) {
3728 s1 = md->params[i].regoff;
3730 if (IS_2_WORD_TYPE(md->params[i].type))
3731 M_LST(s1, REG_SP, j * 8);
3733 M_IST(s1, REG_SP, j * 8);
3741 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3742 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3743 s1 = md->params[i].regoff;
3745 if (IS_2_WORD_TYPE(md->params[i].type))
3746 M_DST(s1, REG_SP, j * 8);
3748 M_FST(s1, REG_SP, j * 8);
3754 /* prepare data structures for native function call */
3756 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3757 M_MOV(REG_PV, REG_A1);
3758 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3759 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3760 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3761 M_ALD(REG_ITMP3, REG_PV, disp);
3762 M_JSR(REG_RA, REG_ITMP3);
3763 M_NOP; /* XXX fill me! */
3765 /* restore integer and float argument registers */
3767 #if SIZEOF_VOID_P == 8
3768 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3769 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3770 s1 = md->params[i].regoff;
3771 M_LLD(s1, REG_SP, j * 8);
3776 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3777 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3778 if (!md->params[i].inmemory) {
3779 s1 = md->params[i].regoff;
3781 if (IS_2_WORD_TYPE(md->params[i].type))
3782 M_LLD(s1, REG_SP, j * 8);
3784 M_ILD(s1, REG_SP, j * 8);
3792 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3793 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3794 s1 = md->params[i].regoff;
3796 if (IS_2_WORD_TYPE(md->params[i].type))
3797 M_DLD(s1, REG_SP, j * 8);
3799 M_FLD(s1, REG_SP, j * 8);
3805 /* copy or spill arguments to new locations */
3807 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3808 t = md->params[i].type;
3810 if (IS_INT_LNG_TYPE(t)) {
3811 if (!md->params[i].inmemory) {
3812 s1 = md->params[i].regoff;
3813 s2 = nmd->params[j].regoff;
3815 if (!nmd->params[j].inmemory) {
3816 #if SIZEOF_VOID_P == 8
3819 if (IS_2_WORD_TYPE(t))
3826 #if SIZEOF_VOID_P == 8
3827 M_LST(s1, REG_SP, s2);
3829 if (IS_2_WORD_TYPE(t))
3830 M_LST(s1, REG_SP, s2);
3832 M_IST(s1, REG_SP, s2);
3837 s1 = md->params[i].regoff + cd->stackframesize * 8;
3838 s2 = nmd->params[j].regoff;
3840 #if SIZEOF_VOID_P == 8
3841 M_LLD(REG_ITMP1, REG_SP, s1);
3842 M_LST(REG_ITMP1, REG_SP, s2);
3844 if (IS_2_WORD_TYPE(t)) {
3845 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3846 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3849 M_ILD(REG_ITMP1, REG_SP, s1);
3850 M_IST(REG_ITMP1, REG_SP, s2);
3856 if (!md->params[i].inmemory) {
3857 s1 = md->params[i].regoff;
3858 s2 = nmd->params[j].regoff;
3860 if (!nmd->params[j].inmemory) {
3861 #if SIZEOF_VOID_P == 8
3862 if (IS_2_WORD_TYPE(t))
3867 /* On MIPS32 float arguments for native functions
3868 can never be in float argument registers, since
3869 the first argument is _always_ an integer
3870 argument (JNIEnv) */
3872 if (IS_2_WORD_TYPE(t)) {
3873 /* double high/low order is endian
3874 independent: even numbered holds low
3875 32-bits, odd numbered high 32-bits */
3877 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3878 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3885 #if SIZEOF_VOID_P == 8
3886 if (IS_2_WORD_TYPE(t))
3887 M_DST(s1, REG_SP, s2);
3889 M_FST(s1, REG_SP, s2);
3891 /* s1 may have been originally in 2 int registers,
3892 but was moved out by the native function
3893 argument(s), just get low register */
3895 if (IS_2_WORD_TYPE(t))
3896 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3898 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3903 s1 = md->params[i].regoff + cd->stackframesize * 8;
3904 s2 = nmd->params[j].regoff;
3906 #if SIZEOF_VOID_P == 8
3907 if (IS_2_WORD_TYPE(t)) {
3908 M_DLD(REG_FTMP1, REG_SP, s1);
3909 M_DST(REG_FTMP1, REG_SP, s2);
3912 M_FLD(REG_FTMP1, REG_SP, s1);
3913 M_FST(REG_FTMP1, REG_SP, s2);
3916 if (IS_2_WORD_TYPE(t)) {
3917 M_DLD(REG_FTMP1, REG_SP, s1);
3918 M_DST(REG_FTMP1, REG_SP, s2);
3921 M_FLD(REG_FTMP1, REG_SP, s1);
3922 M_FST(REG_FTMP1, REG_SP, s2);
3929 /* put class into second argument register */
3931 if (m->flags & ACC_STATIC) {
3932 disp = dseg_add_address(cd, m->class);
3933 M_ALD(REG_A1, REG_PV, disp);
3936 /* put env into first argument register */
3938 disp = dseg_add_address(cd, _Jv_env);
3939 M_ALD(REG_A0, REG_PV, disp);
3941 /* do the native function call */
3943 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3944 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3945 M_NOP; /* delay slot */
3947 /* save return value */
3949 switch (md->returntype.type) {
3950 #if SIZEOF_VOID_P == 8
3954 M_LST(REG_RESULT, REG_SP, 0 * 8);
3958 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3963 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
3966 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
3970 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
3977 #if !defined(NDEBUG)
3978 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3979 emit_verbosecall_exit(jd);
3982 /* remove native stackframe info */
3984 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3985 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3986 M_ALD(REG_ITMP3, REG_PV, disp);
3987 M_JSR(REG_RA, REG_ITMP3);
3988 M_NOP; /* XXX fill me! */
3989 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3991 /* restore return value */
3993 switch (md->returntype.type) {
3994 #if SIZEOF_VOID_P == 8
3998 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4002 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4007 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4010 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4014 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4021 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4023 /* check for exception */
4025 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4026 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4028 M_RET(REG_RA); /* return to caller */
4029 M_NOP; /* DELAY SLOT */
4031 /* handle exception */
4033 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4034 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4035 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4036 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4038 /* Generate patcher traps. */
4040 emit_patcher_traps(jd);
4045 * These are local overrides for various environment variables in Emacs.
4046 * Please do not remove this and leave it at the end of the file, where
4047 * Emacs will automagically detect them.
4048 * ---------------------------------------------------------------------
4051 * indent-tabs-mode: t
4055 * vim:noexpandtab:sw=4:ts=4: