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 8318 2007-08-16 10:05:34Z michi $
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
42 #include "mm/memory.h"
44 #include "native/localref.h"
45 #include "native/native.h"
47 #include "threads/lock-common.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
53 #include "vm/jit/abi.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen-common.h"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/emit-common.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/md.h"
60 #include "vm/jit/patcher-common.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
64 #if defined(ENABLE_LSRA)
65 # include "vm/jit/allocator/lsra.h"
68 #include "vmcore/class.h"
69 #include "vmcore/options.h"
72 /* codegen_emit ****************************************************************
74 Generates machine code.
76 *******************************************************************************/
78 bool codegen_emit(jitdata *jd)
84 s4 len, s1, s2, s3, d, disp;
90 constant_classref *cr;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 unresolved_method *um;
94 builtintable_entry *bte;
101 /* get required compiler data */
108 /* prevent compiler warnings */
123 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
125 /* space to save used callee saved registers */
127 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
130 cd->stackframesize = rd->memuse + savedregs_num;
132 #if defined(ENABLE_THREADS)
133 /* space to save argument of monitor_enter */
135 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
136 # if SIZEOF_VOID_P == 8
137 cd->stackframesize++;
140 cd->stackframesize += 2;
145 /* keep stack 16-byte aligned */
147 if (cd->stackframesize & 1)
148 cd->stackframesize++;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 #if defined(ENABLE_THREADS)
156 /* IsSync contains the offset relative to the stack pointer for the
157 argument of monitor_exit used in the exception handler. Since the
158 offset could be zero and give a wrong meaning of the flag it is
162 if (checksync && (m->flags & ACC_SYNCHRONIZED))
163 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
166 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
168 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
169 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
170 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
171 dseg_addlinenumbertablesize(cd);
172 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_add_target(cd, ex->start);
178 dseg_add_target(cd, ex->end);
179 dseg_add_target(cd, ex->handler);
180 (void) dseg_add_unique_address(cd, ex->catchtype.any);
183 /* create stack frame (if necessary) */
185 if (cd->stackframesize)
186 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
188 /* save return address and used callee saved registers */
190 p = cd->stackframesize;
191 if (!jd->isleafmethod) {
192 p--; M_AST(REG_RA, REG_SP, p * 8);
194 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
195 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
197 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
198 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
201 /* take arguments out of register or stack frame */
205 for (p = 0, l = 0; p < md->paramcount; p++) {
206 t = md->paramtypes[p].type;
208 varindex = jd->local_map[l * 5 + t];
211 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
214 if (varindex == UNUSED)
218 s1 = md->params[p].regoff;
220 if (IS_INT_LNG_TYPE(t)) { /* integer args */
221 if (!md->params[p].inmemory) { /* register arguments */
222 #if SIZEOF_VOID_P == 8
223 if (!(var->flags & INMEMORY))
224 M_INTMOVE(s1, var->vv.regoff);
226 M_LST(s1, REG_SP, var->vv.regoff);
228 if (!(var->flags & INMEMORY)) {
229 if (IS_2_WORD_TYPE(t))
230 M_LNGMOVE(s1, var->vv.regoff);
232 M_INTMOVE(s1, var->vv.regoff);
235 if (IS_2_WORD_TYPE(t))
236 M_LST(s1, REG_SP, var->vv.regoff);
238 M_IST(s1, REG_SP, var->vv.regoff);
242 else { /* stack arguments */
243 if (!(var->flags & INMEMORY)) {
244 #if SIZEOF_VOID_P == 8
245 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
247 if (IS_2_WORD_TYPE(t))
248 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
250 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
254 var->vv.regoff = cd->stackframesize * 8 + s1;
257 else { /* floating args */
258 if (!md->params[p].inmemory) {
259 if (!(var->flags & INMEMORY)) {
260 if (IS_2_WORD_TYPE(t))
261 M_DBLMOVE(s1, var->vv.regoff);
263 M_FLTMOVE(s1, var->vv.regoff);
266 if (IS_2_WORD_TYPE(t))
267 M_DST(s1, REG_SP, var->vv.regoff);
269 M_FST(s1, REG_SP, var->vv.regoff);
273 if (!(var->flags & INMEMORY)) {
274 if (IS_2_WORD_TYPE(t))
275 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
277 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
280 var->vv.regoff = cd->stackframesize * 8 + s1;
285 /* call monitorenter function */
287 #if defined(ENABLE_THREADS)
288 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
289 /* stack offset for monitor argument */
293 # if !defined(NDEBUG)
294 if (opt_verbosecall) {
295 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
297 for (p = 0; p < INT_ARG_CNT; p++)
298 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
300 for (p = 0; p < FLT_ARG_CNT; p++)
301 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
303 s1 += INT_ARG_CNT + FLT_ARG_CNT;
307 /* get correct lock object */
309 if (m->flags & ACC_STATIC) {
310 disp = dseg_add_address(cd, &m->class->object.header);
311 M_ALD(REG_A0, REG_PV, disp);
312 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
313 M_ALD(REG_ITMP3, REG_PV, disp);
316 /* emit_nullpointer_check(cd, iptr, REG_A0); */
318 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
319 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
320 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
323 M_JSR(REG_RA, REG_ITMP3);
324 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
326 # if !defined(NDEBUG)
327 if (opt_verbosecall) {
328 for (p = 0; p < INT_ARG_CNT; p++)
329 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
331 for (p = 0; p < FLT_ARG_CNT; p++)
332 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
335 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
343 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
344 emit_verbosecall_enter(jd);
347 /* end of header generation */
349 /* create replacement points */
351 REPLACEMENT_POINTS_INIT(cd, jd);
353 /* walk through all basic blocks */
355 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
357 /* handle replacement points */
359 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
361 /* store relative start of block */
363 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
365 if (bptr->flags >= BBREACHED) {
366 /* branch resolving */
368 codegen_resolve_branchrefs(cd, bptr);
370 /* copy interface registers to their destination */
374 #if defined(ENABLE_LSRA)
378 src = bptr->invars[len];
379 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
380 /* d = reg_of_var(m, src, REG_ITMP1); */
381 if (!(src->flags & INMEMORY))
385 M_INTMOVE(REG_ITMP1, d);
386 emit_store(jd, NULL, src, d);
393 var = VAR(bptr->invars[len]);
394 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
395 d = codegen_reg_of_var(0, var, REG_ITMP1);
396 M_INTMOVE(REG_ITMP1, d);
397 emit_store(jd, NULL, var, d);
400 assert((var->flags & INOUT));
403 #if defined(ENABLE_LSRA)
406 /* walk through all instructions */
409 /* currentline = 0; */
411 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
412 if (iptr->line != currentline) {
413 dseg_addlinenumber(cd, iptr->line);
414 currentline = iptr->line;
417 MCODECHECK(64); /* an instruction usually needs < 64 words */
421 case ICMD_NOP: /* ... ==> ... */
422 case ICMD_POP: /* ..., value ==> ... */
423 case ICMD_POP2: /* ..., value, value ==> ... */
426 case ICMD_INLINE_START:
428 REPLACEMENT_POINT_INLINE_START(cd, iptr);
431 case ICMD_INLINE_BODY:
433 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
434 dseg_addlinenumber_inline_start(cd, iptr);
435 dseg_addlinenumber(cd, iptr->line);
438 case ICMD_INLINE_END:
440 dseg_addlinenumber_inline_end(cd, iptr);
441 dseg_addlinenumber(cd, iptr->line);
444 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
447 emit_nullpointer_check(cd, iptr, s1);
450 /* constant operations ************************************************/
452 case ICMD_ICONST: /* ... ==> ..., constant */
454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
455 ICONST(d, iptr->sx.val.i);
456 emit_store_dst(jd, iptr, d);
459 case ICMD_LCONST: /* ... ==> ..., constant */
461 #if SIZEOF_VOID_P == 8
462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
466 LCONST(d, iptr->sx.val.l);
467 emit_store_dst(jd, iptr, d);
470 case ICMD_FCONST: /* ... ==> ..., constant */
472 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
473 disp = dseg_add_float(cd, iptr->sx.val.f);
474 M_FLD(d, REG_PV, disp);
475 emit_store_dst(jd, iptr, d);
478 case ICMD_DCONST: /* ... ==> ..., constant */
480 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
481 disp = dseg_add_double(cd, iptr->sx.val.d);
482 M_DLD(d, REG_PV, disp);
483 emit_store_dst(jd, iptr, d);
486 case ICMD_ACONST: /* ... ==> ..., constant */
488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
490 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
491 cr = iptr->sx.val.c.ref;
492 disp = dseg_add_unique_address(cd, cr);
494 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
497 M_ALD(d, REG_PV, disp);
500 if (iptr->sx.val.anyptr == NULL)
501 M_INTMOVE(REG_ZERO, d);
503 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
504 M_ALD(d, REG_PV, disp);
507 emit_store_dst(jd, iptr, d);
511 /* load/store/copy/move operations ************************************/
513 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
518 case ICMD_ISTORE: /* ..., value ==> ... */
529 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
534 /* integer operations *************************************************/
536 case ICMD_INEG: /* ..., value ==> ..., - value */
538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
540 M_ISUB(REG_ZERO, s1, d);
541 emit_store_dst(jd, iptr, d);
544 case ICMD_LNEG: /* ..., value ==> ..., - value */
546 #if SIZEOF_VOID_P == 8
547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
549 M_LSUB(REG_ZERO, s1, d);
551 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
553 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
554 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
555 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
556 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
558 emit_store_dst(jd, iptr, d);
561 case ICMD_I2L: /* ..., value ==> ..., value */
563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
564 #if SIZEOF_VOID_P == 8
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
569 M_INTMOVE(s1, GET_LOW_REG(d));
570 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
572 emit_store_dst(jd, iptr, d);
575 case ICMD_L2I: /* ..., value ==> ..., value */
577 #if SIZEOF_VOID_P == 8
578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580 M_ISLL_IMM(s1, 0, d);
582 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
584 M_INTMOVE(GET_LOW_REG(s1), d);
586 emit_store_dst(jd, iptr, d);
589 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
593 #if SIZEOF_VOID_P == 8
594 M_LSLL_IMM(s1, 56, d);
595 M_LSRA_IMM( d, 56, d);
597 M_ISLL_IMM(s1, 24, d);
598 M_ISRA_IMM( d, 24, d);
600 emit_store_dst(jd, iptr, d);
603 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
607 M_AND_IMM(s1, 0xffff, d);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615 #if SIZEOF_VOID_P == 8
616 M_LSLL_IMM(s1, 48, d);
617 M_LSRA_IMM( d, 48, d);
619 M_ISLL_IMM(s1, 16, d);
620 M_ISRA_IMM( d, 16, d);
622 emit_store_dst(jd, iptr, d);
626 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
629 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
632 emit_store_dst(jd, iptr, d);
636 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
637 /* sx.val.i = constant */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
642 M_IADD_IMM(s1, iptr->sx.val.i, d);
644 ICONST(REG_ITMP2, iptr->sx.val.i);
645 M_IADD(s1, REG_ITMP2, d);
647 emit_store_dst(jd, iptr, d);
650 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
652 #if SIZEOF_VOID_P == 8
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
659 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
661 M_IADD(s1, s2, GET_HIGH_REG(d));
662 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
663 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
664 if (s1 == GET_LOW_REG(d)) {
665 M_MOV(s1, REG_ITMP3);
668 M_IADD(s1, s2, GET_LOW_REG(d));
669 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
670 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
672 emit_store_dst(jd, iptr, d);
675 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
676 /* sx.val.l = constant */
678 #if SIZEOF_VOID_P == 8
679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
681 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
682 M_LADD_IMM(s1, iptr->sx.val.l, d);
684 LCONST(REG_ITMP2, iptr->sx.val.l);
685 M_LADD(s1, REG_ITMP2, d);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
689 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
690 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
691 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
692 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
693 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
695 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
696 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
697 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
698 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
699 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
700 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
701 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
704 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
705 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
706 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
707 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
708 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
709 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
710 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
711 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
714 emit_store_dst(jd, iptr, d);
717 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
723 emit_store_dst(jd, iptr, d);
726 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
727 /* sx.val.i = constant */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
731 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
732 M_IADD_IMM(s1, -iptr->sx.val.i, d);
734 ICONST(REG_ITMP2, iptr->sx.val.i);
735 M_ISUB(s1, REG_ITMP2, d);
737 emit_store_dst(jd, iptr, d);
740 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
742 #if SIZEOF_VOID_P == 8
743 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
744 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
745 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
748 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
749 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
751 M_ISUB(s1, s2, GET_HIGH_REG(d));
752 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
753 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
754 M_CMPULT(s1, s2, REG_ITMP3);
755 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
756 /* if s1 is equal to REG_ITMP3 we have to reload it, since
757 the CMPULT instruction destroyed it */
759 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
760 M_ISUB(s1, s2, GET_LOW_REG(d));
763 emit_store_dst(jd, iptr, d);
766 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
767 /* sx.val.l = constant */
769 #if SIZEOF_VOID_P == 8
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
773 M_LADD_IMM(s1, -iptr->sx.val.l, d);
775 LCONST(REG_ITMP2, iptr->sx.val.l);
776 M_LSUB(s1, REG_ITMP2, d);
779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
780 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
781 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
782 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
783 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
784 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
785 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
786 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
788 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
789 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
790 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
791 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
792 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
795 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
796 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
797 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
798 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
799 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
800 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
801 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
802 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
821 /* sx.val.i = constant */
823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
825 ICONST(REG_ITMP2, iptr->sx.val.i);
826 M_IMUL(s1, REG_ITMP2);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
835 #if SIZEOF_VOID_P == 8
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
838 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
844 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
845 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
851 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
853 M_MFHI(GET_HIGH_REG(d));
854 M_MFLO(GET_LOW_REG(d));
857 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
859 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
860 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
863 /* XXX do we need nops here? */
865 emit_store_dst(jd, iptr, d);
868 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
869 /* sx.val.l = constant */
871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
872 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
873 LCONST(REG_ITMP2, iptr->sx.val.l);
874 M_LMUL(s1, REG_ITMP2);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
886 emit_arithmetic_check(cd, iptr, s2);
891 emit_store_dst(jd, iptr, d);
894 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
898 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
899 emit_arithmetic_check(cd, iptr, s2);
904 emit_store_dst(jd, iptr, d);
907 #if SIZEOF_VOID_P == 8
909 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914 emit_arithmetic_check(cd, iptr, s2);
919 emit_store_dst(jd, iptr, d);
922 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
925 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
927 emit_arithmetic_check(cd, iptr, s2);
932 emit_store_dst(jd, iptr, d);
935 #else /* SIZEOF_VOID_P == 8 */
937 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
938 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
940 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
941 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
943 /* XXX TODO: only do this if arithmetic check is really done! */
944 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
945 emit_arithmetic_check(cd, iptr, REG_ITMP3);
947 M_LNGMOVE(s1, REG_A0_A1_PACKED);
948 M_LNGMOVE(s2, REG_A2_A3_PACKED);
950 bte = iptr->sx.s23.s3.bte;
951 disp = dseg_add_functionptr(cd, bte->fp);
952 M_ALD(REG_ITMP3, REG_PV, disp);
953 M_JSR(REG_RA, REG_ITMP3);
956 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
957 M_LNGMOVE(REG_RESULT_PACKED, d);
958 emit_store_dst(jd, iptr, d);
961 #endif /* SIZEOF_VOID_P == 8 */
963 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
964 /* val.i = constant */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
968 #if SIZEOF_VOID_P == 8
969 M_LSRA_IMM(s1, 63, REG_ITMP2);
970 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
971 M_LADD(s1, REG_ITMP2, REG_ITMP2);
972 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
974 M_ISRA_IMM(s1, 31, REG_ITMP2);
975 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
976 M_IADD(s1, REG_ITMP2, REG_ITMP2);
977 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
983 /* val.i = constant */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
988 M_MOV(s1, REG_ITMP1);
991 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
992 M_AND_IMM(s1, iptr->sx.val.i, d);
995 M_ISUB(REG_ZERO, s1, d);
996 M_AND_IMM(d, iptr->sx.val.i, d);
999 ICONST(REG_ITMP2, iptr->sx.val.i);
1000 M_AND(s1, REG_ITMP2, d);
1003 M_ISUB(REG_ZERO, s1, d);
1004 M_AND(d, REG_ITMP2, d);
1006 M_ISUB(REG_ZERO, d, d);
1007 emit_store_dst(jd, iptr, d);
1010 #if SIZEOF_VOID_P == 8
1012 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1013 /* val.i = constant */
1015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1016 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1017 M_LSRA_IMM(s1, 63, REG_ITMP2);
1018 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1019 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1020 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1021 emit_store_dst(jd, iptr, d);
1024 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1025 /* val.l = constant */
1027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1028 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1030 M_MOV(s1, REG_ITMP1);
1033 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1034 M_AND_IMM(s1, iptr->sx.val.l, d);
1037 M_LSUB(REG_ZERO, s1, d);
1038 M_AND_IMM(d, iptr->sx.val.l, d);
1041 LCONST(REG_ITMP2, iptr->sx.val.l);
1042 M_AND(s1, REG_ITMP2, d);
1045 M_LSUB(REG_ZERO, s1, d);
1046 M_AND(d, REG_ITMP2, d);
1048 M_LSUB(REG_ZERO, d, d);
1049 emit_store_dst(jd, iptr, d);
1052 #endif /* SIZEOF_VOID_P == 8 */
1054 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1057 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1058 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1064 /* sx.val.i = constant */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1068 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1082 /* sx.val.i = constant */
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1085 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1086 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1093 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1094 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1100 /* sx.val.i = constant */
1102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1104 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1110 #if SIZEOF_VOID_P == 8
1111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1113 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1116 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1117 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1118 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1120 M_ISLL(s2, 26, REG_ITMP1);
1121 M_BGEZ(REG_ITMP1, 3);
1124 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1126 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1129 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1131 M_BEQZ(REG_ITMP1, 4);
1132 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1134 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1135 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1136 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1139 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1142 emit_store_dst(jd, iptr, d);
1145 #if SIZEOF_VOID_P == 8
1147 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1148 /* sx.val.i = constant */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1152 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1159 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1162 emit_store_dst(jd, iptr, d);
1165 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1166 /* sx.val.i = constant */
1168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1169 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1170 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1171 emit_store_dst(jd, iptr, d);
1174 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1176 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1177 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1180 emit_store_dst(jd, iptr, d);
1183 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1184 /* sx.val.i = constant */
1186 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1188 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1189 emit_store_dst(jd, iptr, d);
1192 #endif /* SIZEOF_VOID_P == 8 */
1194 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1196 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1197 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1198 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1204 /* sx.val.i = constant */
1206 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1207 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1208 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1209 M_AND_IMM(s1, iptr->sx.val.i, d);
1211 ICONST(REG_ITMP2, iptr->sx.val.i);
1212 M_AND(s1, REG_ITMP2, d);
1214 emit_store_dst(jd, iptr, d);
1217 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1219 #if SIZEOF_VOID_P == 8
1220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1221 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1222 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1225 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1226 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1227 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1228 M_AND(s1, s2, GET_LOW_REG(d));
1229 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1230 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1231 M_AND(s1, s2, GET_HIGH_REG(d));
1233 emit_store_dst(jd, iptr, d);
1236 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1237 /* sx.val.l = constant */
1239 #if SIZEOF_VOID_P == 8
1240 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1241 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1242 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1243 M_AND_IMM(s1, iptr->sx.val.l, d);
1245 LCONST(REG_ITMP2, iptr->sx.val.l);
1246 M_AND(s1, REG_ITMP2, d);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1250 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1251 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1252 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1253 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1256 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1257 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1258 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1259 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1260 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1269 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1270 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1276 /* sx.val.i = constant */
1278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1279 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1280 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1281 M_OR_IMM(s1, iptr->sx.val.i, d);
1283 ICONST(REG_ITMP2, iptr->sx.val.i);
1284 M_OR(s1, REG_ITMP2, d);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1291 #if SIZEOF_VOID_P == 8
1292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1294 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1297 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1298 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1299 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1300 M_OR(s1, s2, GET_LOW_REG(d));
1301 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1302 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1303 M_OR(s1, s2, GET_HIGH_REG(d));
1305 emit_store_dst(jd, iptr, d);
1308 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1309 /* sx.val.l = constant */
1311 #if SIZEOF_VOID_P == 8
1312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1313 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1314 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1315 M_OR_IMM(s1, iptr->sx.val.l, d);
1317 LCONST(REG_ITMP2, iptr->sx.val.l);
1318 M_OR(s1, REG_ITMP2, d);
1321 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1322 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1324 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1325 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1328 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1329 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1330 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1331 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1332 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1335 emit_store_dst(jd, iptr, d);
1338 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1342 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1348 /* sx.val.i = constant */
1350 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1351 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1352 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1353 M_XOR_IMM(s1, iptr->sx.val.i, d);
1355 ICONST(REG_ITMP2, iptr->sx.val.i);
1356 M_XOR(s1, REG_ITMP2, d);
1358 emit_store_dst(jd, iptr, d);
1361 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1363 #if SIZEOF_VOID_P == 8
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1369 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1370 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1371 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1372 M_XOR(s1, s2, GET_LOW_REG(d));
1373 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1374 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1375 M_XOR(s1, s2, GET_HIGH_REG(d));
1377 emit_store_dst(jd, iptr, d);
1380 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1381 /* sx.val.l = constant */
1383 #if SIZEOF_VOID_P == 8
1384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1386 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1387 M_XOR_IMM(s1, iptr->sx.val.l, d);
1389 LCONST(REG_ITMP2, iptr->sx.val.l);
1390 M_XOR(s1, REG_ITMP2, d);
1393 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1394 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1395 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1396 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1397 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1400 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1401 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1402 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1403 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1404 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1407 emit_store_dst(jd, iptr, d);
1411 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1413 #if SIZEOF_VOID_P == 8
1414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1415 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1417 M_CMPLT(s1, s2, REG_ITMP3);
1418 M_CMPLT(s2, s1, REG_ITMP1);
1419 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1421 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1422 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1423 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1424 M_CMPLT(s1, s2, REG_ITMP3);
1425 M_CMPLT(s2, s1, REG_ITMP1);
1426 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1429 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1430 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1431 M_CMPULT(s1, s2, REG_ITMP3);
1432 M_CMPULT(s2, s1, REG_ITMP1);
1433 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1435 emit_store_dst(jd, iptr, d);
1439 /* floating operations ************************************************/
1441 case ICMD_FNEG: /* ..., value ==> ..., - value */
1443 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1444 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1446 emit_store_dst(jd, iptr, d);
1449 case ICMD_DNEG: /* ..., value ==> ..., - value */
1451 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1452 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1454 emit_store_dst(jd, iptr, d);
1457 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1459 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1460 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1461 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1463 emit_store_dst(jd, iptr, d);
1466 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1468 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1469 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1472 emit_store_dst(jd, iptr, d);
1475 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1477 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1478 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1481 emit_store_dst(jd, iptr, d);
1484 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1486 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1488 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1490 emit_store_dst(jd, iptr, d);
1493 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1495 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1496 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1497 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1499 emit_store_dst(jd, iptr, d);
1502 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1504 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1505 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1506 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1508 emit_store_dst(jd, iptr, d);
1511 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1513 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1514 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1515 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1517 emit_store_dst(jd, iptr, d);
1520 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1522 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1523 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1524 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1526 emit_store_dst(jd, iptr, d);
1530 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1532 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1533 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1534 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1535 M_FDIV(s1,s2, REG_FTMP3);
1536 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1537 M_CVTLF(REG_FTMP3, REG_FTMP3);
1538 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1539 M_FSUB(s1, REG_FTMP3, d);
1540 emit_store_dst(jd, iptr, d);
1543 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1545 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1546 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1547 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1548 M_DDIV(s1,s2, REG_FTMP3);
1549 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1550 M_CVTLD(REG_FTMP3, REG_FTMP3);
1551 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1552 M_DSUB(s1, REG_FTMP3, d);
1553 emit_store_dst(jd, iptr, d);
1557 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1563 emit_store_dst(jd, iptr, d);
1566 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1572 emit_store_dst(jd, iptr, d);
1576 /* XXX these do not work correctly */
1578 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1580 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1582 M_TRUNCFI(s1, REG_FTMP1);
1583 M_MOVDI(REG_FTMP1, d);
1585 emit_store_dst(jd, iptr, d);
1588 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1590 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1592 M_TRUNCDI(s1, REG_FTMP1);
1593 M_MOVDI(REG_FTMP1, d);
1595 emit_store_dst(jd, iptr, d);
1598 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1600 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1602 M_TRUNCFL(s1, REG_FTMP1);
1603 M_MOVDL(REG_FTMP1, d);
1605 emit_store_dst(jd, iptr, d);
1608 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1610 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1612 M_TRUNCDL(s1, REG_FTMP1);
1613 M_MOVDL(REG_FTMP1, d);
1615 emit_store_dst(jd, iptr, d);
1619 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1621 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1622 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1624 emit_store_dst(jd, iptr, d);
1627 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1629 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1630 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1632 emit_store_dst(jd, iptr, d);
1635 #if SUPPORT_FLOAT_CMP
1636 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1638 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1639 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1643 M_AADD_IMM(REG_ZERO, 1, d);
1647 M_ASUB_IMM(REG_ZERO, 1, d);
1648 M_CMOVT(REG_ZERO, d);
1649 emit_store_dst(jd, iptr, d);
1652 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1654 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1655 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1659 M_ASUB_IMM(REG_ZERO, 1, d);
1663 M_AADD_IMM(REG_ZERO, 1, d);
1664 M_CMOVT(REG_ZERO, d);
1665 emit_store_dst(jd, iptr, d);
1669 #if SUPPORT_DOUBLE_CMP
1670 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1672 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1673 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1677 M_AADD_IMM(REG_ZERO, 1, d);
1681 M_ASUB_IMM(REG_ZERO, 1, d);
1682 M_CMOVT(REG_ZERO, d);
1683 emit_store_dst(jd, iptr, d);
1686 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1688 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1689 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1693 M_ASUB_IMM(REG_ZERO, 1, d);
1697 M_AADD_IMM(REG_ZERO, 1, d);
1698 M_CMOVT(REG_ZERO, d);
1699 emit_store_dst(jd, iptr, d);
1704 /* memory operations **************************************************/
1706 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1710 /* implicit null-pointer check */
1711 M_ILD(d, s1, OFFSET(java_array_t, size));
1712 emit_store_dst(jd, iptr, d);
1715 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1719 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1720 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1721 M_AADD(s2, s1, REG_ITMP3);
1722 /* implicit null-pointer check */
1723 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1724 emit_store_dst(jd, iptr, d);
1727 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1732 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1733 M_AADD(s2, s1, REG_ITMP3);
1734 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1735 /* implicit null-pointer check */
1736 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1737 emit_store_dst(jd, iptr, d);
1740 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1745 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1746 M_AADD(s2, s1, REG_ITMP3);
1747 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1748 /* implicit null-pointer check */
1749 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1750 emit_store_dst(jd, iptr, d);
1753 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1756 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1757 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1758 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1759 M_ASLL_IMM(s2, 2, REG_ITMP3);
1760 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1761 /* implicit null-pointer check */
1762 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1763 emit_store_dst(jd, iptr, d);
1766 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1770 #if SIZEOF_VOID_P == 8
1771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1775 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1776 M_ASLL_IMM(s2, 3, REG_ITMP3);
1777 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1778 /* implicit null-pointer check */
1779 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1780 emit_store_dst(jd, iptr, d);
1783 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1786 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1787 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1788 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1789 M_ASLL_IMM(s2, 2, REG_ITMP3);
1790 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1791 /* implicit null-pointer check */
1792 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1793 emit_store_dst(jd, iptr, d);
1796 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1799 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1800 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1801 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1802 M_ASLL_IMM(s2, 3, REG_ITMP3);
1803 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1804 /* implicit null-pointer check */
1805 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1806 emit_store_dst(jd, iptr, d);
1809 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1812 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1814 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1815 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1816 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1817 /* implicit null-pointer check */
1818 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1819 emit_store_dst(jd, iptr, d);
1823 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1826 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1827 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1828 M_AADD(s2, s1, REG_ITMP1);
1829 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1830 /* implicit null-pointer check */
1831 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1834 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1835 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1838 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1839 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1840 M_AADD(s2, s1, REG_ITMP1);
1841 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1842 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1843 /* implicit null-pointer check */
1844 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1847 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1850 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1851 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1852 M_ASLL_IMM(s2, 2, REG_ITMP2);
1853 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1854 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1855 /* implicit null-pointer check */
1856 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1859 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1862 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1863 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1864 M_ASLL_IMM(s2, 3, REG_ITMP2);
1865 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1866 #if SIZEOF_VOID_P == 8
1867 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1869 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1871 /* implicit null-pointer check */
1872 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1875 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1878 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1879 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1880 M_ASLL_IMM(s2, 2, REG_ITMP2);
1881 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1882 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1883 /* implicit null-pointer check */
1884 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1887 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1890 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1891 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1892 M_ASLL_IMM(s2, 3, REG_ITMP2);
1893 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1894 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1895 /* implicit null-pointer check */
1896 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1900 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1902 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1903 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1904 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1905 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1907 M_INTMOVE(s1, REG_A0);
1908 M_INTMOVE(s3, REG_A1);
1909 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1910 M_ALD(REG_ITMP3, REG_PV, disp);
1911 M_JSR(REG_RA, REG_ITMP3);
1913 emit_exception_check(cd, iptr);
1915 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1916 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1917 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1918 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1919 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1920 /* implicit null-pointer check */
1921 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1925 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1928 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1929 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1930 M_AADD(s2, s1, REG_ITMP1);
1931 /* implicit null-pointer check */
1932 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1935 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1936 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1939 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1940 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1941 M_AADD(s2, s1, REG_ITMP1);
1942 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1943 /* implicit null-pointer check */
1944 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1947 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1950 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1951 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1952 M_ASLL_IMM(s2, 2, REG_ITMP2);
1953 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1954 /* implicit null-pointer check */
1955 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1958 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1960 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1961 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1962 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1963 M_ASLL_IMM(s2, 3, REG_ITMP2);
1964 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1965 /* implicit null-pointer check */
1966 #if SIZEOF_VOID_P == 8
1967 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1969 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1973 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1976 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1977 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1978 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1979 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1980 /* implicit null-pointer check */
1981 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1985 case ICMD_GETSTATIC: /* ... ==> ..., value */
1987 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1988 uf = iptr->sx.s23.s3.uf;
1989 fieldtype = uf->fieldref->parseddesc.fd->type;
1990 disp = dseg_add_unique_address(cd, uf);
1992 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1995 fi = iptr->sx.s23.s3.fmiref->p.field;
1996 fieldtype = fi->type;
1997 disp = dseg_add_address(cd, fi->value);
1999 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2000 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2004 M_ALD(REG_ITMP1, REG_PV, disp);
2006 switch (fieldtype) {
2008 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2009 M_ILD_INTERN(d, REG_ITMP1, 0);
2012 #if SIZEOF_VOID_P == 8
2013 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2017 M_LLD_INTERN(d, REG_ITMP1, 0);
2020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2021 M_ALD_INTERN(d, REG_ITMP1, 0);
2024 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2025 M_FLD_INTERN(d, REG_ITMP1, 0);
2028 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2029 M_DLD_INTERN(d, REG_ITMP1, 0);
2032 emit_store_dst(jd, iptr, d);
2035 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2037 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2038 uf = iptr->sx.s23.s3.uf;
2039 fieldtype = uf->fieldref->parseddesc.fd->type;
2040 disp = dseg_add_unique_address(cd, uf);
2042 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2045 fi = iptr->sx.s23.s3.fmiref->p.field;
2046 fieldtype = fi->type;
2047 disp = dseg_add_address(cd, fi->value);
2049 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2050 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2054 M_ALD(REG_ITMP1, REG_PV, disp);
2056 switch (fieldtype) {
2058 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2059 M_IST_INTERN(s1, REG_ITMP1, 0);
2062 #if SIZEOF_VOID_P == 8
2063 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2065 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2067 M_LST_INTERN(s1, REG_ITMP1, 0);
2070 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2071 M_AST_INTERN(s1, REG_ITMP1, 0);
2074 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2075 M_FST_INTERN(s1, REG_ITMP1, 0);
2078 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2079 M_DST_INTERN(s1, REG_ITMP1, 0);
2084 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2086 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2087 uf = iptr->sx.s23.s3.uf;
2088 fieldtype = uf->fieldref->parseddesc.fd->type;
2089 disp = dseg_add_unique_address(cd, uf);
2091 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2094 fi = iptr->sx.s23.s3.fmiref->p.field;
2095 fieldtype = fi->type;
2096 disp = dseg_add_address(cd, fi->value);
2098 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2099 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2103 M_ALD(REG_ITMP1, REG_PV, disp);
2105 switch (fieldtype) {
2107 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2110 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2113 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2116 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2119 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2125 case ICMD_GETFIELD: /* ... ==> ..., value */
2127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2128 emit_nullpointer_check(cd, iptr, s1);
2130 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2131 uf = iptr->sx.s23.s3.uf;
2132 fieldtype = uf->fieldref->parseddesc.fd->type;
2135 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2138 fi = iptr->sx.s23.s3.fmiref->p.field;
2139 fieldtype = fi->type;
2143 switch (fieldtype) {
2145 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2149 #if SIZEOF_VOID_P == 8
2150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2154 M_LLD_GETFIELD(d, s1, disp);
2158 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2162 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2166 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2170 emit_store_dst(jd, iptr, d);
2173 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2176 emit_nullpointer_check(cd, iptr, s1);
2178 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2179 uf = iptr->sx.s23.s3.uf;
2180 fieldtype = uf->fieldref->parseddesc.fd->type;
2184 fi = iptr->sx.s23.s3.fmiref->p.field;
2185 fieldtype = fi->type;
2189 #if SIZEOF_VOID_P == 8
2190 if (IS_INT_LNG_TYPE(fieldtype))
2191 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2193 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2195 if (IS_INT_LNG_TYPE(fieldtype)) {
2196 if (IS_2_WORD_TYPE(fieldtype))
2197 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2199 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2202 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2205 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2206 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2208 switch (fieldtype) {
2210 M_IST(s2, s1, disp);
2213 M_LST(s2, s1, disp);
2216 M_AST(s2, s1, disp);
2219 M_FST(s2, s1, disp);
2222 M_DST(s2, s1, disp);
2227 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2230 emit_nullpointer_check(cd, iptr, s1);
2232 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2233 uf = iptr->sx.s23.s3.uf;
2234 fieldtype = uf->fieldref->parseddesc.fd->type;
2237 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2240 fi = iptr->sx.s23.s3.fmiref->p.field;
2241 fieldtype = fi->type;
2245 switch (fieldtype) {
2247 M_IST(REG_ZERO, s1, disp);
2250 M_LST(REG_ZERO, s1, disp);
2253 M_AST(REG_ZERO, s1, disp);
2256 M_FST(REG_ZERO, s1, disp);
2259 M_DST(REG_ZERO, s1, disp);
2265 /* branch operations **************************************************/
2267 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2269 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2270 M_INTMOVE(s1, REG_ITMP1_XPTR);
2272 #ifdef ENABLE_VERIFIER
2273 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2274 uc = iptr->sx.s23.s2.uc;
2276 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2278 #endif /* ENABLE_VERIFIER */
2280 disp = dseg_add_functionptr(cd, asm_handle_exception);
2281 M_ALD(REG_ITMP2, REG_PV, disp);
2282 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2284 M_NOP; /* nop ensures that XPC is less than the end */
2285 /* of basic block */
2289 case ICMD_GOTO: /* ... ==> ... */
2290 case ICMD_RET: /* ... ==> ... */
2292 emit_br(cd, iptr->dst.block);
2296 case ICMD_JSR: /* ... ==> ... */
2298 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2302 case ICMD_IFNULL: /* ..., value ==> ... */
2303 case ICMD_IFNONNULL:
2305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2306 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2309 case ICMD_IFEQ: /* ..., value ==> ... */
2311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2312 if (iptr->sx.val.i == 0)
2313 emit_beqz(cd, iptr->dst.block, s1);
2315 ICONST(REG_ITMP2, iptr->sx.val.i);
2316 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2320 case ICMD_IFLT: /* ..., value ==> ... */
2322 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2323 if (iptr->sx.val.i == 0)
2324 emit_bltz(cd, iptr->dst.block, s1);
2326 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2327 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2329 ICONST(REG_ITMP2, iptr->sx.val.i);
2330 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2332 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2336 case ICMD_IFLE: /* ..., value ==> ... */
2338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2339 if (iptr->sx.val.i == 0)
2340 emit_blez(cd, iptr->dst.block, s1);
2342 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2343 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2344 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2347 ICONST(REG_ITMP2, iptr->sx.val.i);
2348 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2349 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2354 case ICMD_IFNE: /* ..., value ==> ... */
2356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2357 if (iptr->sx.val.i == 0)
2358 emit_bnez(cd, iptr->dst.block, s1);
2360 ICONST(REG_ITMP2, iptr->sx.val.i);
2361 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2365 case ICMD_IFGT: /* ..., value ==> ... */
2367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2368 if (iptr->sx.val.i == 0)
2369 emit_bgtz(cd, iptr->dst.block, s1);
2371 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2372 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2373 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2376 ICONST(REG_ITMP2, iptr->sx.val.i);
2377 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2378 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2383 case ICMD_IFGE: /* ..., value ==> ... */
2385 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2386 if (iptr->sx.val.i == 0)
2387 emit_bgez(cd, iptr->dst.block, s1);
2389 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2390 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2392 ICONST(REG_ITMP2, iptr->sx.val.i);
2393 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2395 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2399 case ICMD_IF_LEQ: /* ..., value ==> ... */
2401 #if SIZEOF_VOID_P == 8
2402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2403 if (iptr->sx.val.l == 0)
2404 emit_beqz(cd, iptr->dst.block, s1);
2406 LCONST(REG_ITMP2, iptr->sx.val.l);
2407 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2410 if (iptr->sx.val.l == 0) {
2411 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2412 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2413 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2416 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2417 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2418 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2419 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2420 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2421 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2422 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2423 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2428 case ICMD_IF_LLT: /* ..., value ==> ... */
2430 #if SIZEOF_VOID_P == 8
2431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2432 if (iptr->sx.val.l == 0)
2433 emit_bltz(cd, iptr->dst.block, s1);
2435 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2436 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2438 LCONST(REG_ITMP2, iptr->sx.val.l);
2439 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2441 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2444 if (iptr->sx.val.l == 0) {
2445 /* if high word is less than zero, the whole long is too */
2446 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2447 emit_bltz(cd, iptr->dst.block, s1);
2450 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2451 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2452 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2453 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2454 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2455 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2457 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2458 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2459 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2464 case ICMD_IF_LLE: /* ..., value ==> ... */
2466 #if SIZEOF_VOID_P == 8
2467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2468 if (iptr->sx.val.l == 0)
2469 emit_blez(cd, iptr->dst.block, s1);
2471 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2472 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2473 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2476 LCONST(REG_ITMP2, iptr->sx.val.l);
2477 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2478 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2482 if (iptr->sx.val.l == 0) {
2483 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2484 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2486 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2487 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2490 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2491 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2492 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2493 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2494 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2495 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2497 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2498 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2499 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2504 case ICMD_IF_LNE: /* ..., value ==> ... */
2506 #if SIZEOF_VOID_P == 8
2507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2508 if (iptr->sx.val.l == 0)
2509 emit_bnez(cd, iptr->dst.block, s1);
2511 LCONST(REG_ITMP2, iptr->sx.val.l);
2512 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2515 if (iptr->sx.val.l == 0) {
2516 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2517 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2518 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2521 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2522 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2523 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2524 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2525 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2526 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2527 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2528 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2533 case ICMD_IF_LGT: /* ..., value ==> ... */
2535 #if SIZEOF_VOID_P == 8
2536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2537 if (iptr->sx.val.l == 0)
2538 emit_bgtz(cd, iptr->dst.block, s1);
2540 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2541 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2542 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2545 LCONST(REG_ITMP2, iptr->sx.val.l);
2546 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2547 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2551 if (iptr->sx.val.l == 0) {
2552 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2553 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2554 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2556 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2559 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2560 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2561 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2562 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2563 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2564 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2566 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2567 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2568 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2573 case ICMD_IF_LGE: /* ..., value ==> ... */
2575 #if SIZEOF_VOID_P == 8
2576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2577 if (iptr->sx.val.l == 0)
2578 emit_bgez(cd, iptr->dst.block, s1);
2580 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2581 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2584 LCONST(REG_ITMP2, iptr->sx.val.l);
2585 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2587 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2590 if (iptr->sx.val.l == 0) {
2591 /* if high word is greater equal zero, the whole long is too */
2592 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2593 emit_bgez(cd, iptr->dst.block, s1);
2596 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2597 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2598 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2599 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2600 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2601 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2603 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2604 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2605 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2610 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2611 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2612 #if SIZEOF_VOID_P == 8
2613 case ICMD_IF_LCMPEQ:
2616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2617 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2618 emit_beq(cd, iptr->dst.block, s1, s2);
2621 #if SIZEOF_VOID_P == 4
2622 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2623 /* op1 = target JavaVM pc */
2625 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2626 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2627 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2629 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2630 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2631 emit_beq(cd, iptr->dst.block, s1, s2);
2635 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2636 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2637 #if SIZEOF_VOID_P == 8
2638 case ICMD_IF_LCMPNE:
2641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2642 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2643 emit_bne(cd, iptr->dst.block, s1, s2);
2646 #if SIZEOF_VOID_P == 4
2647 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2649 /* TODO: could be optimized (XOR or SUB) */
2650 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2651 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2652 emit_bne(cd, iptr->dst.block, s1, s2);
2653 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2654 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2655 emit_bne(cd, iptr->dst.block, s1, s2);
2659 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2660 #if SIZEOF_VOID_P == 8
2661 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2666 M_CMPLT(s1, s2, REG_ITMP3);
2667 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2670 #if SIZEOF_VOID_P == 4
2671 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2673 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2674 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2675 M_CMPLT(s1, s2, REG_ITMP3);
2676 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2677 M_CMPGT(s1, s2, REG_ITMP3);
2678 /* load low-bits before the branch, so we know the distance */
2679 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2680 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2681 M_BNEZ(REG_ITMP3, 4); /* XXX */
2683 M_CMPULT(s1, s2, REG_ITMP3);
2684 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2688 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2689 #if SIZEOF_VOID_P == 8
2690 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2695 M_CMPGT(s1, s2, REG_ITMP3);
2696 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2699 #if SIZEOF_VOID_P == 4
2700 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2702 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2703 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2704 M_CMPGT(s1, s2, REG_ITMP3);
2705 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2706 M_CMPLT(s1, s2, REG_ITMP3);
2707 /* load low-bits before the branch, so we know the distance */
2708 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2709 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2710 M_BNEZ(REG_ITMP3, 4); /* XXX */
2712 M_CMPUGT(s1, s2, REG_ITMP3);
2713 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2717 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2718 #if SIZEOF_VOID_P == 8
2719 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2724 M_CMPGT(s1, s2, REG_ITMP3);
2725 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2728 #if SIZEOF_VOID_P == 4
2729 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2731 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2732 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2733 M_CMPLT(s1, s2, REG_ITMP3);
2734 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2735 M_CMPGT(s1, s2, REG_ITMP3);
2736 /* load low-bits before the branch, so we know the distance */
2737 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2738 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2739 M_BNEZ(REG_ITMP3, 4); /* XXX */
2741 M_CMPUGT(s1, s2, REG_ITMP3);
2742 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2746 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2747 #if SIZEOF_VOID_P == 8
2748 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2753 M_CMPLT(s1, s2, REG_ITMP3);
2754 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2757 #if SIZEOF_VOID_P == 4
2758 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2760 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2761 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2762 M_CMPGT(s1, s2, REG_ITMP3);
2763 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2764 M_CMPLT(s1, s2, REG_ITMP3);
2765 /* load low-bits before the branch, so we know the distance */
2766 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2767 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2768 M_BNEZ(REG_ITMP3, 4); /* XXX */
2770 M_CMPULT(s1, s2, REG_ITMP3);
2771 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2775 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2776 #if SIZEOF_VOID_P == 8
2780 REPLACEMENT_POINT_RETURN(cd, iptr);
2781 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2782 M_INTMOVE(s1, REG_RESULT);
2783 goto nowperformreturn;
2785 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2787 REPLACEMENT_POINT_RETURN(cd, iptr);
2788 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2789 M_INTMOVE(s1, REG_RESULT);
2791 #ifdef ENABLE_VERIFIER
2792 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2793 uc = iptr->sx.s23.s2.uc;
2795 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2797 #endif /* ENABLE_VERIFIER */
2798 goto nowperformreturn;
2800 #if SIZEOF_VOID_P == 4
2801 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2803 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2804 M_LNGMOVE(s1, REG_RESULT_PACKED);
2805 goto nowperformreturn;
2808 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2809 REPLACEMENT_POINT_RETURN(cd, iptr);
2810 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2811 M_FLTMOVE(s1, REG_FRESULT);
2812 goto nowperformreturn;
2814 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2816 REPLACEMENT_POINT_RETURN(cd, iptr);
2817 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2818 M_DBLMOVE(s1, REG_FRESULT);
2819 goto nowperformreturn;
2821 case ICMD_RETURN: /* ... ==> ... */
2823 REPLACEMENT_POINT_RETURN(cd, iptr);
2829 p = cd->stackframesize;
2831 #if !defined(NDEBUG)
2832 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2833 emit_verbosecall_exit(jd);
2836 #if defined(ENABLE_THREADS)
2837 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2838 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2839 M_ALD(REG_ITMP3, REG_PV, disp);
2841 /* we need to save the proper return value */
2843 switch (iptr->opc) {
2846 #if SIZEOF_VOID_P == 8
2849 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2850 M_JSR(REG_RA, REG_ITMP3);
2851 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2853 #if SIZEOF_VOID_P == 4
2855 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2856 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2857 M_JSR(REG_RA, REG_ITMP3);
2863 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2864 M_JSR(REG_RA, REG_ITMP3);
2865 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2868 M_JSR(REG_RA, REG_ITMP3);
2869 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2873 /* and now restore the proper return value */
2875 switch (iptr->opc) {
2878 #if SIZEOF_VOID_P == 8
2881 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2883 #if SIZEOF_VOID_P == 4
2885 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2890 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2896 /* restore return address */
2898 if (!jd->isleafmethod) {
2899 p--; M_ALD(REG_RA, REG_SP, p * 8);
2902 /* restore saved registers */
2904 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2905 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2907 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2908 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2911 /* deallocate stack and return */
2913 if (cd->stackframesize) {
2916 disp = cd->stackframesize * 8;
2917 lo = (short) (disp);
2918 hi = (short) (((disp) - lo) >> 16);
2922 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2924 M_LUI(REG_ITMP3,hi);
2925 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2927 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2940 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2943 branch_target_t *table;
2945 table = iptr->dst.table;
2947 l = iptr->sx.s23.s2.tablelow;
2948 i = iptr->sx.s23.s3.tablehigh;
2950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2952 {M_INTMOVE(s1, REG_ITMP1);}
2953 else if (l <= 32768) {
2954 M_IADD_IMM(s1, -l, REG_ITMP1);
2957 ICONST(REG_ITMP2, l);
2958 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2961 /* number of targets */
2966 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2967 emit_beqz(cd, table[0].block, REG_ITMP2);
2969 /* build jump table top down and use address of lowest entry */
2974 dseg_add_target(cd, table->block);
2979 /* length of dataseg after last dseg_add_target is used by load */
2981 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2982 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2983 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2990 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2993 lookup_target_t *lookup;
2995 lookup = iptr->dst.lookup;
2997 i = iptr->sx.s23.s2.lookupcount;
2999 MCODECHECK((i<<2)+8);
3000 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3003 ICONST(REG_ITMP2, lookup->value);
3004 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3008 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3014 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3016 bte = iptr->sx.s23.s3.bte;
3020 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3022 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3023 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3024 case ICMD_INVOKEINTERFACE:
3026 REPLACEMENT_POINT_INVOKE(cd, iptr);
3028 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3030 um = iptr->sx.s23.s3.um;
3031 md = um->methodref->parseddesc.md;
3034 lm = iptr->sx.s23.s3.fmiref->p.method;
3036 md = lm->parseddesc;
3040 s3 = md->paramcount;
3042 MCODECHECK((s3 << 1) + 64);
3044 /* copy arguments to registers or stack location */
3046 for (s3 = s3 - 1; s3 >= 0; s3--) {
3047 var = VAR(iptr->sx.s23.s2.args[s3]);
3048 d = md->params[s3].regoff;
3050 if (var->flags & PREALLOC)
3053 if (IS_INT_LNG_TYPE(var->type)) {
3054 #if SIZEOF_VOID_P == 8
3055 if (!md->params[s3].inmemory) {
3056 s1 = emit_load(jd, iptr, var, d);
3060 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3061 M_LST(s1, REG_SP, d);
3064 if (!md->params[s3].inmemory) {
3065 s1 = emit_load(jd, iptr, var, d);
3067 if (IS_2_WORD_TYPE(var->type))
3073 if (IS_2_WORD_TYPE(var->type)) {
3074 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3075 M_LST(s1, REG_SP, d);
3078 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3079 M_IST(s1, REG_SP, d);
3085 if (!md->params[s3].inmemory) {
3086 s1 = emit_load(jd, iptr, var, d);
3087 if (IS_2_WORD_TYPE(var->type))
3093 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3094 if (IS_2_WORD_TYPE(var->type))
3095 M_DST(s1, REG_SP, d);
3097 M_FST(s1, REG_SP, d);
3102 switch (iptr->opc) {
3104 disp = dseg_add_functionptr(cd, bte->fp);
3106 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3108 /* generate the actual call */
3110 /* TWISTI: i actually don't know the reason for using
3111 REG_ITMP3 here instead of REG_PV. */
3113 M_JSR(REG_RA, REG_ITMP3);
3115 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3116 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3117 M_LDA(REG_PV, REG_RA, -disp);
3119 emit_exception_check(cd, iptr);
3122 case ICMD_INVOKESPECIAL:
3123 emit_nullpointer_check(cd, iptr, REG_A0);
3126 case ICMD_INVOKESTATIC:
3128 disp = dseg_add_unique_address(cd, um);
3130 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3134 disp = dseg_add_address(cd, lm->stubroutine);
3136 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3138 /* generate the actual call */
3140 M_JSR(REG_RA, REG_PV);
3142 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3143 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3144 M_LDA(REG_PV, REG_RA, -disp);
3147 case ICMD_INVOKEVIRTUAL:
3148 emit_nullpointer_check(cd, iptr, REG_A0);
3151 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3156 s1 = OFFSET(vftbl_t, table[0]) +
3157 sizeof(methodptr) * lm->vftblindex;
3159 /* implicit null-pointer check */
3160 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3161 M_ALD(REG_PV, REG_METHODPTR, s1);
3163 /* generate the actual call */
3165 M_JSR(REG_RA, REG_PV);
3167 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3168 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3169 M_LDA(REG_PV, REG_RA, -disp);
3172 case ICMD_INVOKEINTERFACE:
3173 emit_nullpointer_check(cd, iptr, REG_A0);
3176 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3182 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3183 sizeof(methodptr*) * lm->class->index;
3185 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3188 /* implicit null-pointer check */
3189 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3190 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3191 M_ALD(REG_PV, REG_METHODPTR, s2);
3193 /* generate the actual call */
3195 M_JSR(REG_RA, REG_PV);
3197 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3198 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3199 M_LDA(REG_PV, REG_RA, -disp);
3203 /* store return value */
3205 d = md->returntype.type;
3207 if (d != TYPE_VOID) {
3208 if (IS_INT_LNG_TYPE(d)) {
3209 #if SIZEOF_VOID_P == 8
3210 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3211 M_INTMOVE(REG_RESULT, s1);
3213 if (IS_2_WORD_TYPE(d)) {
3214 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3215 M_LNGMOVE(REG_RESULT_PACKED, s1);
3218 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3219 M_INTMOVE(REG_RESULT, s1);
3224 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3225 if (IS_2_WORD_TYPE(d))
3226 M_DMOV(REG_FRESULT, s1);
3228 M_FMOV(REG_FRESULT, s1);
3230 emit_store_dst(jd, iptr, s1);
3235 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3237 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3241 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3246 super = iptr->sx.s23.s3.c.cls;
3247 superindex = super->index;
3250 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3251 CODEGEN_CRITICAL_SECTION_NEW;
3253 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3255 /* if class is not resolved, check which code to call */
3257 if (super == NULL) {
3258 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3260 cr = iptr->sx.s23.s3.c.ref;
3261 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3263 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3266 M_ILD(REG_ITMP2, REG_PV, disp);
3267 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3268 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3271 /* interface checkcast code */
3273 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3274 if (super == NULL) {
3275 cr = iptr->sx.s23.s3.c.ref;
3277 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3281 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3284 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3285 M_ILD(REG_ITMP3, REG_ITMP2,
3286 OFFSET(vftbl_t, interfacetablelength));
3287 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3288 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3290 M_ALD(REG_ITMP3, REG_ITMP2,
3291 OFFSET(vftbl_t, interfacetable[0]) -
3292 superindex * sizeof(methodptr*));
3293 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3296 emit_label_br(cd, BRANCH_LABEL_4);
3298 emit_label(cd, BRANCH_LABEL_3);
3301 /* class checkcast code */
3303 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3304 if (super == NULL) {
3305 emit_label(cd, BRANCH_LABEL_2);
3307 cr = iptr->sx.s23.s3.c.ref;
3308 disp = dseg_add_unique_address(cd, NULL);
3310 patcher_add_patch_ref(jd,
3311 PATCHER_resolve_classref_to_vftbl,
3315 disp = dseg_add_address(cd, super->vftbl);
3317 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3320 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3321 M_ALD(REG_ITMP3, REG_PV, disp);
3323 CODEGEN_CRITICAL_SECTION_START;
3325 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3326 /* if (s1 != REG_ITMP1) { */
3327 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3328 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3329 /* #if defined(ENABLE_THREADS) */
3330 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3332 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3334 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3335 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3336 M_ALD(REG_ITMP3, REG_PV, disp);
3337 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3339 CODEGEN_CRITICAL_SECTION_END;
3342 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3343 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3346 emit_label(cd, BRANCH_LABEL_5);
3349 if (super == NULL) {
3350 emit_label(cd, BRANCH_LABEL_1);
3351 emit_label(cd, BRANCH_LABEL_4);
3354 d = codegen_reg_of_dst(jd, iptr, s1);
3357 s1 = emit_load_s1(jd, iptr, REG_A0);
3358 M_INTMOVE(s1, REG_A0);
3360 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3361 cr = iptr->sx.s23.s3.c.ref;
3362 disp = dseg_add_unique_address(cd, NULL);
3364 patcher_add_patch_ref(jd,
3365 PATCHER_resolve_classref_to_classinfo,
3369 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3372 M_ALD(REG_A1, REG_PV, disp);
3373 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3374 M_ALD(REG_ITMP3, REG_PV, disp);
3375 M_JSR(REG_RA, REG_ITMP3);
3378 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3379 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3381 d = codegen_reg_of_dst(jd, iptr, s1);
3385 emit_store_dst(jd, iptr, d);
3388 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3394 super = iptr->sx.s23.s3.c.cls;
3396 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3401 super = iptr->sx.s23.s3.c.cls;
3402 superindex = super->index;
3405 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3406 CODEGEN_CRITICAL_SECTION_NEW;
3408 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3412 M_MOV(s1, REG_ITMP1);
3418 /* if class is not resolved, check which code to call */
3420 if (super == NULL) {
3421 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3423 cr = iptr->sx.s23.s3.c.ref;
3424 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3426 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3429 M_ILD(REG_ITMP3, REG_PV, disp);
3430 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3431 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3434 /* interface instanceof code */
3436 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3437 if (super == NULL) {
3438 cr = iptr->sx.s23.s3.c.ref;
3440 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3444 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3447 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3448 M_ILD(REG_ITMP3, REG_ITMP1,
3449 OFFSET(vftbl_t, interfacetablelength));
3450 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3451 M_BLEZ(REG_ITMP3, 3);
3453 M_ALD(REG_ITMP1, REG_ITMP1,
3454 OFFSET(vftbl_t, interfacetable[0]) -
3455 superindex * sizeof(methodptr*));
3456 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3459 emit_label_br(cd, BRANCH_LABEL_4);
3461 emit_label(cd, BRANCH_LABEL_3);
3464 /* class instanceof code */
3466 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3467 if (super == NULL) {
3468 emit_label(cd, BRANCH_LABEL_2);
3470 cr = iptr->sx.s23.s3.c.ref;
3471 disp = dseg_add_unique_address(cd, NULL);
3473 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3477 disp = dseg_add_address(cd, super->vftbl);
3479 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3482 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3483 M_ALD(REG_ITMP2, REG_PV, disp);
3485 CODEGEN_CRITICAL_SECTION_START;
3487 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3488 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3489 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3491 CODEGEN_CRITICAL_SECTION_END;
3493 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3494 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3498 emit_label(cd, BRANCH_LABEL_5);
3501 if (super == NULL) {
3502 emit_label(cd, BRANCH_LABEL_1);
3503 emit_label(cd, BRANCH_LABEL_4);
3506 emit_store_dst(jd, iptr, d);
3510 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3512 /* check for negative sizes and copy sizes to stack if necessary */
3514 MCODECHECK((iptr->s1.argcount << 1) + 64);
3516 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3518 var = VAR(iptr->sx.s23.s2.args[s1]);
3520 /* copy SAVEDVAR sizes to stack */
3522 if (!(var->flags & PREALLOC)) {
3523 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3524 #if SIZEOF_VOID_P == 8
3525 M_LST(s2, REG_SP, s1 * 8);
3527 M_IST(s2, REG_SP, (s1 + 2) * 8);
3532 /* a0 = dimension count */
3534 ICONST(REG_A0, iptr->s1.argcount);
3536 /* is patcher function set? */
3538 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3539 cr = iptr->sx.s23.s3.c.ref;
3540 disp = dseg_add_unique_address(cd, NULL);
3542 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3546 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3549 /* a1 = arraydescriptor */
3551 M_ALD(REG_A1, REG_PV, disp);
3553 /* a2 = pointer to dimensions = stack pointer */
3555 #if SIZEOF_VOID_P == 8
3556 M_MOV(REG_SP, REG_A2);
3558 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3561 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3562 M_ALD(REG_ITMP3, REG_PV, disp);
3563 M_JSR(REG_RA, REG_ITMP3);
3566 /* check for exception before result assignment */
3568 emit_exception_check(cd, iptr);
3570 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3571 M_INTMOVE(REG_RESULT, d);
3572 emit_store_dst(jd, iptr, d);
3576 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3581 } /* for instruction */
3583 MCODECHECK(64); /* XXX require smaller number? */
3585 /* At the end of a basic block we may have to append some nops,
3586 because the patcher stub calling code might be longer than the
3587 actual instruction. So codepatching does not change the
3588 following block unintentionally. */
3590 if (cd->mcodeptr < cd->lastmcodeptr) {
3591 while (cd->mcodeptr < cd->lastmcodeptr)
3595 } /* if (bptr -> flags >= BBREACHED) */
3596 } /* for basic block */
3598 dseg_createlinenumbertable(cd);
3600 /* generate traps */
3602 emit_patcher_traps(jd);
3604 /* everything's ok */
3610 /* codegen_emit_stub_compiler **************************************************
3612 Emits a stub routine which calls the compiler.
3614 *******************************************************************************/
3616 void codegen_emit_stub_compiler(jitdata *jd)
3621 /* get required compiler data */
3626 /* code for the stub */
3628 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3629 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3635 /* codegen_emit_stub_native ****************************************************
3637 Emits a stub routine which calls a native method.
3639 *******************************************************************************/
3641 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3651 s4 funcdisp; /* displacement of the function */
3653 /* get required compiler data */
3659 /* initialize variables */
3662 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3664 /* calculate stack frame size */
3666 cd->stackframesize =
3667 1 + /* return address */
3668 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3669 sizeof(localref_table) / SIZEOF_VOID_P +
3670 md->paramcount + /* for saving arguments over calls */
3671 #if SIZEOF_VOID_P == 4
3672 5 + /* additional save space (MIPS32) */
3674 1 + /* for saving return address */
3677 /* adjust stackframe size for 16-byte alignment */
3679 if (cd->stackframesize & 1)
3680 cd->stackframesize++;
3682 /* create method header */
3684 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3685 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3686 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3687 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3688 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3689 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3690 (void) dseg_addlinenumbertablesize(cd);
3691 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3693 /* generate stub code */
3695 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3696 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3698 #if !defined(NDEBUG)
3699 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3700 emit_verbosecall_enter(jd);
3703 /* get function address (this must happen before the stackframeinfo) */
3705 funcdisp = dseg_add_functionptr(cd, f);
3707 #if !defined(WITH_STATIC_CLASSPATH)
3709 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3712 /* save integer and float argument registers */
3714 #if SIZEOF_VOID_P == 8
3715 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3716 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3717 s1 = md->params[i].regoff;
3718 M_AST(s1, REG_SP, j * 8);
3723 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3724 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3725 if (!md->params[i].inmemory) {
3726 s1 = md->params[i].regoff;
3728 if (IS_2_WORD_TYPE(md->params[i].type))
3729 M_LST(s1, REG_SP, j * 8);
3731 M_IST(s1, REG_SP, j * 8);
3739 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3740 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3741 s1 = md->params[i].regoff;
3743 if (IS_2_WORD_TYPE(md->params[i].type))
3744 M_DST(s1, REG_SP, j * 8);
3746 M_FST(s1, REG_SP, j * 8);
3752 /* prepare data structures for native function call */
3754 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3755 M_MOV(REG_PV, REG_A1);
3756 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3757 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3758 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3759 M_ALD(REG_ITMP3, REG_PV, disp);
3760 M_JSR(REG_RA, REG_ITMP3);
3761 M_NOP; /* XXX fill me! */
3763 /* restore integer and float argument registers */
3765 #if SIZEOF_VOID_P == 8
3766 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3767 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3768 s1 = md->params[i].regoff;
3769 M_LLD(s1, REG_SP, j * 8);
3774 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3775 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3776 if (!md->params[i].inmemory) {
3777 s1 = md->params[i].regoff;
3779 if (IS_2_WORD_TYPE(md->params[i].type))
3780 M_LLD(s1, REG_SP, j * 8);
3782 M_ILD(s1, REG_SP, j * 8);
3790 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3791 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3792 s1 = md->params[i].regoff;
3794 if (IS_2_WORD_TYPE(md->params[i].type))
3795 M_DLD(s1, REG_SP, j * 8);
3797 M_FLD(s1, REG_SP, j * 8);
3803 /* copy or spill arguments to new locations */
3805 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3806 t = md->params[i].type;
3808 if (IS_INT_LNG_TYPE(t)) {
3809 if (!md->params[i].inmemory) {
3810 s1 = md->params[i].regoff;
3811 s2 = nmd->params[j].regoff;
3813 if (!nmd->params[j].inmemory) {
3814 #if SIZEOF_VOID_P == 8
3817 if (IS_2_WORD_TYPE(t))
3824 #if SIZEOF_VOID_P == 8
3825 M_LST(s1, REG_SP, s2);
3827 if (IS_2_WORD_TYPE(t))
3828 M_LST(s1, REG_SP, s2);
3830 M_IST(s1, REG_SP, s2);
3835 s1 = md->params[i].regoff + cd->stackframesize * 8;
3836 s2 = nmd->params[j].regoff;
3838 #if SIZEOF_VOID_P == 8
3839 M_LLD(REG_ITMP1, REG_SP, s1);
3840 M_LST(REG_ITMP1, REG_SP, s2);
3842 if (IS_2_WORD_TYPE(t)) {
3843 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3844 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3847 M_ILD(REG_ITMP1, REG_SP, s1);
3848 M_IST(REG_ITMP1, REG_SP, s2);
3854 if (!md->params[i].inmemory) {
3855 s1 = md->params[i].regoff;
3856 s2 = nmd->params[j].regoff;
3858 if (!nmd->params[j].inmemory) {
3859 #if SIZEOF_VOID_P == 8
3860 if (IS_2_WORD_TYPE(t))
3865 /* On MIPS32 float arguments for native functions
3866 can never be in float argument registers, since
3867 the first argument is _always_ an integer
3868 argument (JNIEnv) */
3870 if (IS_2_WORD_TYPE(t)) {
3871 /* double high/low order is endian
3872 independent: even numbered holds low
3873 32-bits, odd numbered high 32-bits */
3875 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3876 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3883 #if SIZEOF_VOID_P == 8
3884 if (IS_2_WORD_TYPE(t))
3885 M_DST(s1, REG_SP, s2);
3887 M_FST(s1, REG_SP, s2);
3889 /* s1 may have been originally in 2 int registers,
3890 but was moved out by the native function
3891 argument(s), just get low register */
3893 if (IS_2_WORD_TYPE(t))
3894 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3896 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3901 s1 = md->params[i].regoff + cd->stackframesize * 8;
3902 s2 = nmd->params[j].regoff;
3904 #if SIZEOF_VOID_P == 8
3905 if (IS_2_WORD_TYPE(t)) {
3906 M_DLD(REG_FTMP1, REG_SP, s1);
3907 M_DST(REG_FTMP1, REG_SP, s2);
3910 M_FLD(REG_FTMP1, REG_SP, s1);
3911 M_FST(REG_FTMP1, REG_SP, s2);
3914 if (IS_2_WORD_TYPE(t)) {
3915 M_DLD(REG_FTMP1, REG_SP, s1);
3916 M_DST(REG_FTMP1, REG_SP, s2);
3919 M_FLD(REG_FTMP1, REG_SP, s1);
3920 M_FST(REG_FTMP1, REG_SP, s2);
3927 /* put class into second argument register */
3929 if (m->flags & ACC_STATIC) {
3930 disp = dseg_add_address(cd, m->class);
3931 M_ALD(REG_A1, REG_PV, disp);
3934 /* put env into first argument register */
3936 disp = dseg_add_address(cd, _Jv_env);
3937 M_ALD(REG_A0, REG_PV, disp);
3939 /* do the native function call */
3941 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3942 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3943 M_NOP; /* delay slot */
3945 /* save return value */
3947 switch (md->returntype.type) {
3948 #if SIZEOF_VOID_P == 8
3952 M_LST(REG_RESULT, REG_SP, 0 * 8);
3956 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3961 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
3964 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
3968 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
3975 #if !defined(NDEBUG)
3976 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3977 emit_verbosecall_exit(jd);
3980 /* remove native stackframe info */
3982 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3983 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3984 M_ALD(REG_ITMP3, REG_PV, disp);
3985 M_JSR(REG_RA, REG_ITMP3);
3986 M_NOP; /* XXX fill me! */
3987 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3989 /* restore return value */
3991 switch (md->returntype.type) {
3992 #if SIZEOF_VOID_P == 8
3996 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4000 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4005 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4008 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4012 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4019 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4021 /* check for exception */
4023 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4024 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4026 M_RET(REG_RA); /* return to caller */
4027 M_NOP; /* DELAY SLOT */
4029 /* handle exception */
4031 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4032 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4033 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4034 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4036 /* Generate patcher traps. */
4038 emit_patcher_traps(jd);
4043 * These are local overrides for various environment variables in Emacs.
4044 * Please do not remove this and leave it at the end of the file, where
4045 * Emacs will automagically detect them.
4046 * ---------------------------------------------------------------------
4049 * indent-tabs-mode: t
4053 * vim:noexpandtab:sw=4:ts=4: