1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "vm/jit/mips/arch.h"
38 #include "vm/jit/mips/codegen.h"
40 #include "mm/memory.h"
42 #include "native/localref.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
51 #include "vm/jit/abi.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.h"
54 #include "vm/jit/dseg.h"
55 #include "vm/jit/emit-common.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/md.h"
58 #include "vm/jit/patcher-common.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
62 #if defined(ENABLE_LSRA)
63 # include "vm/jit/allocator/lsra.h"
66 #include "vmcore/class.h"
67 #include "vmcore/options.h"
70 /* codegen_emit ****************************************************************
72 Generates machine code.
74 *******************************************************************************/
76 bool codegen_emit(jitdata *jd)
82 s4 len, s1, s2, s3, d, disp;
88 constant_classref *cr;
90 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
91 unresolved_method *um;
92 builtintable_entry *bte;
99 /* get required compiler data */
106 /* prevent compiler warnings */
121 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
123 /* space to save used callee saved registers */
125 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128 cd->stackframesize = rd->memuse + savedregs_num;
130 #if defined(ENABLE_THREADS)
131 /* space to save argument of monitor_enter */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
134 # if SIZEOF_VOID_P == 8
135 cd->stackframesize++;
138 cd->stackframesize += 2;
143 /* keep stack 16-byte aligned */
145 if (cd->stackframesize & 1)
146 cd->stackframesize++;
148 /* create method header */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
166 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
167 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
168 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
169 dseg_addlinenumbertablesize(cd);
170 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
172 /* create exception table */
174 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
175 dseg_add_target(cd, ex->start);
176 dseg_add_target(cd, ex->end);
177 dseg_add_target(cd, ex->handler);
178 (void) dseg_add_unique_address(cd, ex->catchtype.any);
181 /* create stack frame (if necessary) */
183 if (cd->stackframesize)
184 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
186 /* save return address and used callee saved registers */
188 p = cd->stackframesize;
189 if (!jd->isleafmethod) {
190 p--; M_AST(REG_RA, REG_SP, p * 8);
192 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
193 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
195 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
196 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
199 /* take arguments out of register or stack frame */
203 for (p = 0, l = 0; p < md->paramcount; p++) {
204 t = md->paramtypes[p].type;
206 varindex = jd->local_map[l * 5 + t];
209 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
212 if (varindex == UNUSED)
216 s1 = md->params[p].regoff;
218 if (IS_INT_LNG_TYPE(t)) { /* integer args */
219 if (!md->params[p].inmemory) { /* register arguments */
220 #if SIZEOF_VOID_P == 8
221 if (!(var->flags & INMEMORY))
222 M_INTMOVE(s1, var->vv.regoff);
224 M_LST(s1, REG_SP, var->vv.regoff);
226 if (!(var->flags & INMEMORY)) {
227 if (IS_2_WORD_TYPE(t))
228 M_LNGMOVE(s1, var->vv.regoff);
230 M_INTMOVE(s1, var->vv.regoff);
233 if (IS_2_WORD_TYPE(t))
234 M_LST(s1, REG_SP, var->vv.regoff);
236 M_IST(s1, REG_SP, var->vv.regoff);
240 else { /* stack arguments */
241 if (!(var->flags & INMEMORY)) {
242 #if SIZEOF_VOID_P == 8
243 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
245 if (IS_2_WORD_TYPE(t))
246 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
248 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
252 var->vv.regoff = cd->stackframesize * 8 + s1;
255 else { /* floating args */
256 if (!md->params[p].inmemory) {
257 if (!(var->flags & INMEMORY)) {
258 if (IS_2_WORD_TYPE(t))
259 M_DBLMOVE(s1, var->vv.regoff);
261 M_FLTMOVE(s1, var->vv.regoff);
264 if (IS_2_WORD_TYPE(t))
265 M_DST(s1, REG_SP, var->vv.regoff);
267 M_FST(s1, REG_SP, var->vv.regoff);
271 if (!(var->flags & INMEMORY)) {
272 if (IS_2_WORD_TYPE(t))
273 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
275 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
278 var->vv.regoff = cd->stackframesize * 8 + s1;
283 /* call monitorenter function */
285 #if defined(ENABLE_THREADS)
286 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
287 /* stack offset for monitor argument */
291 # if !defined(NDEBUG)
292 if (opt_verbosecall) {
293 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
295 for (p = 0; p < INT_ARG_CNT; p++)
296 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
298 for (p = 0; p < FLT_ARG_CNT; p++)
299 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
301 s1 += INT_ARG_CNT + FLT_ARG_CNT;
305 /* get correct lock object */
307 if (m->flags & ACC_STATIC) {
308 disp = dseg_add_address(cd, &m->class->object.header);
309 M_ALD(REG_A0, REG_PV, disp);
310 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
311 M_ALD(REG_ITMP3, REG_PV, disp);
314 /* emit_nullpointer_check(cd, iptr, REG_A0); */
316 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
317 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
318 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
321 M_JSR(REG_RA, REG_ITMP3);
322 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
324 # if !defined(NDEBUG)
325 if (opt_verbosecall) {
326 for (p = 0; p < INT_ARG_CNT; p++)
327 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
329 for (p = 0; p < FLT_ARG_CNT; p++)
330 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
333 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
341 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
342 emit_verbosecall_enter(jd);
345 /* end of header generation */
347 /* create replacement points */
349 REPLACEMENT_POINTS_INIT(cd, jd);
351 /* walk through all basic blocks */
353 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
355 /* handle replacement points */
357 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
359 /* store relative start of block */
361 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
363 if (bptr->flags >= BBREACHED) {
364 /* branch resolving */
366 codegen_resolve_branchrefs(cd, bptr);
368 /* copy interface registers to their destination */
372 #if defined(ENABLE_LSRA)
376 src = bptr->invars[len];
377 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
378 /* d = reg_of_var(m, src, REG_ITMP1); */
379 if (!(src->flags & INMEMORY))
383 M_INTMOVE(REG_ITMP1, d);
384 emit_store(jd, NULL, src, d);
391 var = VAR(bptr->invars[len]);
392 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
393 d = codegen_reg_of_var(0, var, REG_ITMP1);
394 M_INTMOVE(REG_ITMP1, d);
395 emit_store(jd, NULL, var, d);
398 assert((var->flags & INOUT));
401 #if defined(ENABLE_LSRA)
404 /* walk through all instructions */
407 /* currentline = 0; */
409 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
410 if (iptr->line != currentline) {
411 dseg_addlinenumber(cd, iptr->line);
412 currentline = iptr->line;
415 MCODECHECK(64); /* an instruction usually needs < 64 words */
419 case ICMD_NOP: /* ... ==> ... */
420 case ICMD_POP: /* ..., value ==> ... */
421 case ICMD_POP2: /* ..., value, value ==> ... */
424 case ICMD_INLINE_START:
426 REPLACEMENT_POINT_INLINE_START(cd, iptr);
429 case ICMD_INLINE_BODY:
431 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
432 dseg_addlinenumber_inline_start(cd, iptr);
433 dseg_addlinenumber(cd, iptr->line);
436 case ICMD_INLINE_END:
438 dseg_addlinenumber_inline_end(cd, iptr);
439 dseg_addlinenumber(cd, iptr->line);
442 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
444 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
445 emit_nullpointer_check(cd, iptr, s1);
448 /* constant operations ************************************************/
450 case ICMD_ICONST: /* ... ==> ..., constant */
452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
453 ICONST(d, iptr->sx.val.i);
454 emit_store_dst(jd, iptr, d);
457 case ICMD_LCONST: /* ... ==> ..., constant */
459 #if SIZEOF_VOID_P == 8
460 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
464 LCONST(d, iptr->sx.val.l);
465 emit_store_dst(jd, iptr, d);
468 case ICMD_FCONST: /* ... ==> ..., constant */
470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
471 disp = dseg_add_float(cd, iptr->sx.val.f);
472 M_FLD(d, REG_PV, disp);
473 emit_store_dst(jd, iptr, d);
476 case ICMD_DCONST: /* ... ==> ..., constant */
478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
479 disp = dseg_add_double(cd, iptr->sx.val.d);
480 M_DLD(d, REG_PV, disp);
481 emit_store_dst(jd, iptr, d);
484 case ICMD_ACONST: /* ... ==> ..., constant */
486 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
488 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
489 cr = iptr->sx.val.c.ref;
490 disp = dseg_add_unique_address(cd, cr);
492 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
495 M_ALD(d, REG_PV, disp);
498 if (iptr->sx.val.anyptr == NULL)
499 M_INTMOVE(REG_ZERO, d);
501 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
502 M_ALD(d, REG_PV, disp);
505 emit_store_dst(jd, iptr, d);
509 /* load/store/copy/move operations ************************************/
511 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
516 case ICMD_ISTORE: /* ..., value ==> ... */
527 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
532 /* integer operations *************************************************/
534 case ICMD_INEG: /* ..., value ==> ..., - value */
536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
538 M_ISUB(REG_ZERO, s1, d);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_LNEG: /* ..., value ==> ..., - value */
544 #if SIZEOF_VOID_P == 8
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
547 M_LSUB(REG_ZERO, s1, d);
549 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
551 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
552 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
553 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
554 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
556 emit_store_dst(jd, iptr, d);
559 case ICMD_I2L: /* ..., value ==> ..., value */
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 #if SIZEOF_VOID_P == 8
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
567 M_INTMOVE(s1, GET_LOW_REG(d));
568 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
570 emit_store_dst(jd, iptr, d);
573 case ICMD_L2I: /* ..., value ==> ..., value */
575 #if SIZEOF_VOID_P == 8
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 M_ISLL_IMM(s1, 0, d);
580 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
582 M_INTMOVE(GET_LOW_REG(s1), d);
584 emit_store_dst(jd, iptr, d);
587 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
591 #if SIZEOF_VOID_P == 8
592 M_LSLL_IMM(s1, 56, d);
593 M_LSRA_IMM( d, 56, d);
595 M_ISLL_IMM(s1, 24, d);
596 M_ISRA_IMM( d, 24, d);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 M_AND_IMM(s1, 0xffff, d);
606 emit_store_dst(jd, iptr, d);
609 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
613 #if SIZEOF_VOID_P == 8
614 M_LSLL_IMM(s1, 48, d);
615 M_LSRA_IMM( d, 48, d);
617 M_ISLL_IMM(s1, 16, d);
618 M_ISRA_IMM( d, 16, d);
620 emit_store_dst(jd, iptr, d);
624 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630 emit_store_dst(jd, iptr, d);
634 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
635 /* sx.val.i = constant */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
639 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
640 M_IADD_IMM(s1, iptr->sx.val.i, d);
642 ICONST(REG_ITMP2, iptr->sx.val.i);
643 M_IADD(s1, REG_ITMP2, d);
645 emit_store_dst(jd, iptr, d);
648 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
650 #if SIZEOF_VOID_P == 8
651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
657 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
659 M_IADD(s1, s2, GET_HIGH_REG(d));
660 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
661 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
662 if (s1 == GET_LOW_REG(d)) {
663 M_MOV(s1, REG_ITMP3);
666 M_IADD(s1, s2, GET_LOW_REG(d));
667 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
668 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
670 emit_store_dst(jd, iptr, d);
673 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
674 /* sx.val.l = constant */
676 #if SIZEOF_VOID_P == 8
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
680 M_LADD_IMM(s1, iptr->sx.val.l, d);
682 LCONST(REG_ITMP2, iptr->sx.val.l);
683 M_LADD(s1, REG_ITMP2, d);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
687 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
688 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
689 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
690 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
691 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
693 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
694 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
695 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
696 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
697 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
698 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
699 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
702 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
703 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
704 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
705 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
706 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
707 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
708 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
709 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
712 emit_store_dst(jd, iptr, d);
715 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
719 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
721 emit_store_dst(jd, iptr, d);
724 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
725 /* sx.val.i = constant */
727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
728 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
729 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
730 M_IADD_IMM(s1, -iptr->sx.val.i, d);
732 ICONST(REG_ITMP2, iptr->sx.val.i);
733 M_ISUB(s1, REG_ITMP2, d);
735 emit_store_dst(jd, iptr, d);
738 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
740 #if SIZEOF_VOID_P == 8
741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
746 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
747 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
748 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
749 M_ISUB(s1, s2, GET_HIGH_REG(d));
750 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
751 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
752 M_CMPULT(s1, s2, REG_ITMP3);
753 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
754 /* if s1 is equal to REG_ITMP3 we have to reload it, since
755 the CMPULT instruction destroyed it */
757 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
758 M_ISUB(s1, s2, GET_LOW_REG(d));
761 emit_store_dst(jd, iptr, d);
764 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
765 /* sx.val.l = constant */
767 #if SIZEOF_VOID_P == 8
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
770 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
771 M_LADD_IMM(s1, -iptr->sx.val.l, d);
773 LCONST(REG_ITMP2, iptr->sx.val.l);
774 M_LSUB(s1, REG_ITMP2, d);
777 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
778 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
779 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
780 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
781 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
782 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
783 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
784 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
786 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
787 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
788 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
789 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
790 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
793 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
794 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
795 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
796 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
797 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
798 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
799 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
800 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
803 emit_store_dst(jd, iptr, d);
806 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
819 /* sx.val.i = constant */
821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 ICONST(REG_ITMP2, iptr->sx.val.i);
824 M_IMUL(s1, REG_ITMP2);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
833 #if SIZEOF_VOID_P == 8
834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
836 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
843 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
844 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
849 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
851 M_MFHI(GET_HIGH_REG(d));
852 M_MFLO(GET_LOW_REG(d));
855 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
857 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
858 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
861 /* XXX do we need nops here? */
863 emit_store_dst(jd, iptr, d);
866 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
867 /* sx.val.l = constant */
869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 LCONST(REG_ITMP2, iptr->sx.val.l);
872 M_LMUL(s1, REG_ITMP2);
876 emit_store_dst(jd, iptr, d);
879 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
883 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
884 emit_arithmetic_check(cd, iptr, s2);
889 emit_store_dst(jd, iptr, d);
892 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
897 emit_arithmetic_check(cd, iptr, s2);
902 emit_store_dst(jd, iptr, d);
905 #if SIZEOF_VOID_P == 8
907 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
910 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
911 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
912 emit_arithmetic_check(cd, iptr, s2);
917 emit_store_dst(jd, iptr, d);
920 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
923 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
924 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
925 emit_arithmetic_check(cd, iptr, s2);
930 emit_store_dst(jd, iptr, d);
933 #else /* SIZEOF_VOID_P == 8 */
935 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
936 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
938 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
939 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
941 /* XXX TODO: only do this if arithmetic check is really done! */
942 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
943 emit_arithmetic_check(cd, iptr, REG_ITMP3);
945 M_LNGMOVE(s1, REG_A0_A1_PACKED);
946 M_LNGMOVE(s2, REG_A2_A3_PACKED);
948 bte = iptr->sx.s23.s3.bte;
949 disp = dseg_add_functionptr(cd, bte->fp);
950 M_ALD(REG_ITMP3, REG_PV, disp);
951 M_JSR(REG_RA, REG_ITMP3);
954 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
955 M_LNGMOVE(REG_RESULT_PACKED, d);
956 emit_store_dst(jd, iptr, d);
959 #endif /* SIZEOF_VOID_P == 8 */
961 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
962 /* val.i = constant */
964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
965 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
966 #if SIZEOF_VOID_P == 8
967 M_LSRA_IMM(s1, 63, REG_ITMP2);
968 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
969 M_LADD(s1, REG_ITMP2, REG_ITMP2);
970 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
972 M_ISRA_IMM(s1, 31, REG_ITMP2);
973 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
974 M_IADD(s1, REG_ITMP2, REG_ITMP2);
975 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
977 emit_store_dst(jd, iptr, d);
980 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
981 /* val.i = constant */
983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
984 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
986 M_MOV(s1, REG_ITMP1);
989 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
990 M_AND_IMM(s1, iptr->sx.val.i, d);
993 M_ISUB(REG_ZERO, s1, d);
994 M_AND_IMM(d, iptr->sx.val.i, d);
997 ICONST(REG_ITMP2, iptr->sx.val.i);
998 M_AND(s1, REG_ITMP2, d);
1001 M_ISUB(REG_ZERO, s1, d);
1002 M_AND(d, REG_ITMP2, d);
1004 M_ISUB(REG_ZERO, d, d);
1005 emit_store_dst(jd, iptr, d);
1008 #if SIZEOF_VOID_P == 8
1010 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1011 /* val.i = constant */
1013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1014 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1015 M_LSRA_IMM(s1, 63, REG_ITMP2);
1016 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1017 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1018 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1019 emit_store_dst(jd, iptr, d);
1022 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1023 /* val.l = constant */
1025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1028 M_MOV(s1, REG_ITMP1);
1031 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1032 M_AND_IMM(s1, iptr->sx.val.l, d);
1035 M_LSUB(REG_ZERO, s1, d);
1036 M_AND_IMM(d, iptr->sx.val.l, d);
1039 LCONST(REG_ITMP2, iptr->sx.val.l);
1040 M_AND(s1, REG_ITMP2, d);
1043 M_LSUB(REG_ZERO, s1, d);
1044 M_AND(d, REG_ITMP2, d);
1046 M_LSUB(REG_ZERO, d, d);
1047 emit_store_dst(jd, iptr, d);
1050 #endif /* SIZEOF_VOID_P == 8 */
1052 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1056 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1058 emit_store_dst(jd, iptr, d);
1061 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1062 /* sx.val.i = constant */
1064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1065 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1067 emit_store_dst(jd, iptr, d);
1070 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1073 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1076 emit_store_dst(jd, iptr, d);
1079 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1080 /* sx.val.i = constant */
1082 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1083 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1084 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1094 emit_store_dst(jd, iptr, d);
1097 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1098 /* sx.val.i = constant */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1102 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1103 emit_store_dst(jd, iptr, d);
1106 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1108 #if SIZEOF_VOID_P == 8
1109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1110 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1111 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1114 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1115 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1116 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1118 M_ISLL(s2, 26, REG_ITMP1);
1119 M_BGEZ(REG_ITMP1, 3);
1122 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1124 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1127 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1129 M_BEQZ(REG_ITMP1, 4);
1130 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1132 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1133 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1134 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1137 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1140 emit_store_dst(jd, iptr, d);
1143 #if SIZEOF_VOID_P == 8
1145 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1146 /* sx.val.i = constant */
1148 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1149 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1150 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1151 emit_store_dst(jd, iptr, d);
1154 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1156 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1157 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1158 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1164 /* sx.val.i = constant */
1166 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1167 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1168 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1169 emit_store_dst(jd, iptr, d);
1172 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1175 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1176 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1178 emit_store_dst(jd, iptr, d);
1181 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1182 /* sx.val.i = constant */
1184 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1185 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1186 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1187 emit_store_dst(jd, iptr, d);
1190 #endif /* SIZEOF_VOID_P == 8 */
1192 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1195 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1196 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1198 emit_store_dst(jd, iptr, d);
1201 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1202 /* sx.val.i = constant */
1204 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1205 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1206 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1207 M_AND_IMM(s1, iptr->sx.val.i, d);
1209 ICONST(REG_ITMP2, iptr->sx.val.i);
1210 M_AND(s1, REG_ITMP2, d);
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1217 #if SIZEOF_VOID_P == 8
1218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1223 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1224 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1225 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1226 M_AND(s1, s2, GET_LOW_REG(d));
1227 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1228 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1229 M_AND(s1, s2, GET_HIGH_REG(d));
1231 emit_store_dst(jd, iptr, d);
1234 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1235 /* sx.val.l = constant */
1237 #if SIZEOF_VOID_P == 8
1238 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1239 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1240 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1241 M_AND_IMM(s1, iptr->sx.val.l, d);
1243 LCONST(REG_ITMP2, iptr->sx.val.l);
1244 M_AND(s1, REG_ITMP2, d);
1247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1248 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1249 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1250 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1251 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1254 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1255 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1256 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1257 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1258 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1261 emit_store_dst(jd, iptr, d);
1264 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1266 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1267 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1268 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1274 /* sx.val.i = constant */
1276 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1277 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1278 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1279 M_OR_IMM(s1, iptr->sx.val.i, d);
1281 ICONST(REG_ITMP2, iptr->sx.val.i);
1282 M_OR(s1, REG_ITMP2, d);
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1289 #if SIZEOF_VOID_P == 8
1290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1291 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1295 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1296 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1297 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1298 M_OR(s1, s2, GET_LOW_REG(d));
1299 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1300 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1301 M_OR(s1, s2, GET_HIGH_REG(d));
1303 emit_store_dst(jd, iptr, d);
1306 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1307 /* sx.val.l = constant */
1309 #if SIZEOF_VOID_P == 8
1310 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1311 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1312 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1313 M_OR_IMM(s1, iptr->sx.val.l, d);
1315 LCONST(REG_ITMP2, iptr->sx.val.l);
1316 M_OR(s1, REG_ITMP2, d);
1319 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1320 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1321 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1322 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1323 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1326 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1327 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1328 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1329 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1330 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1346 /* sx.val.i = constant */
1348 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1349 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1350 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1351 M_XOR_IMM(s1, iptr->sx.val.i, d);
1353 ICONST(REG_ITMP2, iptr->sx.val.i);
1354 M_XOR(s1, REG_ITMP2, d);
1356 emit_store_dst(jd, iptr, d);
1359 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1361 #if SIZEOF_VOID_P == 8
1362 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1363 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1367 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1368 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1370 M_XOR(s1, s2, GET_LOW_REG(d));
1371 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1372 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1373 M_XOR(s1, s2, GET_HIGH_REG(d));
1375 emit_store_dst(jd, iptr, d);
1378 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1379 /* sx.val.l = constant */
1381 #if SIZEOF_VOID_P == 8
1382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1383 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1384 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1385 M_XOR_IMM(s1, iptr->sx.val.l, d);
1387 LCONST(REG_ITMP2, iptr->sx.val.l);
1388 M_XOR(s1, REG_ITMP2, d);
1391 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1392 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1393 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1394 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1395 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1398 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1399 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1400 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1401 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1402 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1405 emit_store_dst(jd, iptr, d);
1409 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1411 #if SIZEOF_VOID_P == 8
1412 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1413 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1414 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1415 M_CMPLT(s1, s2, REG_ITMP3);
1416 M_CMPLT(s2, s1, REG_ITMP1);
1417 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1419 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1420 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1422 M_CMPLT(s1, s2, REG_ITMP3);
1423 M_CMPLT(s2, s1, REG_ITMP1);
1424 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1427 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1428 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1429 M_CMPULT(s1, s2, REG_ITMP3);
1430 M_CMPULT(s2, s1, REG_ITMP1);
1431 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1433 emit_store_dst(jd, iptr, d);
1437 /* floating operations ************************************************/
1439 case ICMD_FNEG: /* ..., value ==> ..., - value */
1441 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1442 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1444 emit_store_dst(jd, iptr, d);
1447 case ICMD_DNEG: /* ..., value ==> ..., - value */
1449 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1450 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1452 emit_store_dst(jd, iptr, d);
1455 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1457 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1458 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1459 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1461 emit_store_dst(jd, iptr, d);
1464 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1466 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1467 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1468 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1470 emit_store_dst(jd, iptr, d);
1473 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1475 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1476 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1477 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1479 emit_store_dst(jd, iptr, d);
1482 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1484 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1485 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1486 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1488 emit_store_dst(jd, iptr, d);
1491 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1493 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1494 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1495 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1497 emit_store_dst(jd, iptr, d);
1500 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1502 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1503 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1504 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1506 emit_store_dst(jd, iptr, d);
1509 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1511 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1512 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1513 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1515 emit_store_dst(jd, iptr, d);
1518 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1520 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1521 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1522 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1524 emit_store_dst(jd, iptr, d);
1528 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1530 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1533 M_FDIV(s1,s2, REG_FTMP3);
1534 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1535 M_CVTLF(REG_FTMP3, REG_FTMP3);
1536 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1537 M_FSUB(s1, REG_FTMP3, d);
1538 emit_store_dst(jd, iptr, d);
1541 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1543 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1545 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1546 M_DDIV(s1,s2, REG_FTMP3);
1547 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1548 M_CVTLD(REG_FTMP3, REG_FTMP3);
1549 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1550 M_DSUB(s1, REG_FTMP3, d);
1551 emit_store_dst(jd, iptr, d);
1555 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1558 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1561 emit_store_dst(jd, iptr, d);
1564 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1570 emit_store_dst(jd, iptr, d);
1574 /* XXX these do not work correctly */
1576 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1578 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1580 M_TRUNCFI(s1, REG_FTMP1);
1581 M_MOVDI(REG_FTMP1, d);
1583 emit_store_dst(jd, iptr, d);
1586 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1588 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1590 M_TRUNCDI(s1, REG_FTMP1);
1591 M_MOVDI(REG_FTMP1, d);
1593 emit_store_dst(jd, iptr, d);
1596 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1598 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1600 M_TRUNCFL(s1, REG_FTMP1);
1601 M_MOVDL(REG_FTMP1, d);
1603 emit_store_dst(jd, iptr, d);
1606 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1608 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1610 M_TRUNCDL(s1, REG_FTMP1);
1611 M_MOVDL(REG_FTMP1, d);
1613 emit_store_dst(jd, iptr, d);
1617 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1619 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1620 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1622 emit_store_dst(jd, iptr, d);
1625 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1627 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1628 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1630 emit_store_dst(jd, iptr, d);
1633 #if SUPPORT_FLOAT_CMP
1634 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1636 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1637 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1641 M_AADD_IMM(REG_ZERO, 1, d);
1645 M_ASUB_IMM(REG_ZERO, 1, d);
1646 M_CMOVT(REG_ZERO, d);
1647 emit_store_dst(jd, iptr, d);
1650 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1652 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1653 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1657 M_ASUB_IMM(REG_ZERO, 1, d);
1661 M_AADD_IMM(REG_ZERO, 1, d);
1662 M_CMOVT(REG_ZERO, d);
1663 emit_store_dst(jd, iptr, d);
1667 #if SUPPORT_DOUBLE_CMP
1668 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1670 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1671 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1675 M_AADD_IMM(REG_ZERO, 1, d);
1679 M_ASUB_IMM(REG_ZERO, 1, d);
1680 M_CMOVT(REG_ZERO, d);
1681 emit_store_dst(jd, iptr, d);
1684 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1686 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1687 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1691 M_ASUB_IMM(REG_ZERO, 1, d);
1695 M_AADD_IMM(REG_ZERO, 1, d);
1696 M_CMOVT(REG_ZERO, d);
1697 emit_store_dst(jd, iptr, d);
1702 /* memory operations **************************************************/
1704 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1708 /* implicit null-pointer check */
1709 M_ILD(d, s1, OFFSET(java_array_t, size));
1710 emit_store_dst(jd, iptr, d);
1713 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1716 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1717 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1718 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1719 M_AADD(s2, s1, REG_ITMP3);
1720 /* implicit null-pointer check */
1721 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1722 emit_store_dst(jd, iptr, d);
1725 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1729 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1730 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1731 M_AADD(s2, s1, REG_ITMP3);
1732 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1733 /* implicit null-pointer check */
1734 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1735 emit_store_dst(jd, iptr, d);
1738 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1741 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1743 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1744 M_AADD(s2, s1, REG_ITMP3);
1745 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1746 /* implicit null-pointer check */
1747 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1748 emit_store_dst(jd, iptr, d);
1751 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1756 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1757 M_ASLL_IMM(s2, 2, REG_ITMP3);
1758 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1759 /* implicit null-pointer check */
1760 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1761 emit_store_dst(jd, iptr, d);
1764 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1768 #if SIZEOF_VOID_P == 8
1769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1773 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1774 M_ASLL_IMM(s2, 3, REG_ITMP3);
1775 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1776 /* implicit null-pointer check */
1777 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1778 emit_store_dst(jd, iptr, d);
1781 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1785 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1786 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1787 M_ASLL_IMM(s2, 2, REG_ITMP3);
1788 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1789 /* implicit null-pointer check */
1790 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1791 emit_store_dst(jd, iptr, d);
1794 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1797 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1798 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1799 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1800 M_ASLL_IMM(s2, 3, REG_ITMP3);
1801 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1802 /* implicit null-pointer check */
1803 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1804 emit_store_dst(jd, iptr, d);
1807 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1810 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1812 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1813 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1814 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1815 /* implicit null-pointer check */
1816 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1817 emit_store_dst(jd, iptr, d);
1821 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1824 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1825 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1826 M_AADD(s2, s1, REG_ITMP1);
1827 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1828 /* implicit null-pointer check */
1829 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1832 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1833 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1836 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1837 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1838 M_AADD(s2, s1, REG_ITMP1);
1839 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1840 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1841 /* implicit null-pointer check */
1842 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1845 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1849 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1850 M_ASLL_IMM(s2, 2, REG_ITMP2);
1851 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1852 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1853 /* implicit null-pointer check */
1854 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1857 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1861 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1862 M_ASLL_IMM(s2, 3, REG_ITMP2);
1863 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1864 #if SIZEOF_VOID_P == 8
1865 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1867 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1869 /* implicit null-pointer check */
1870 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1873 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1876 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1877 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1878 M_ASLL_IMM(s2, 2, REG_ITMP2);
1879 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1880 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1881 /* implicit null-pointer check */
1882 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1885 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1888 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1889 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1890 M_ASLL_IMM(s2, 3, REG_ITMP2);
1891 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1892 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1893 /* implicit null-pointer check */
1894 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1898 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1902 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1903 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1905 M_INTMOVE(s1, REG_A0);
1906 M_INTMOVE(s3, REG_A1);
1907 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1908 M_ALD(REG_ITMP3, REG_PV, disp);
1909 M_JSR(REG_RA, REG_ITMP3);
1911 emit_exception_check(cd, iptr);
1913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1914 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1915 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1916 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1917 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1918 /* implicit null-pointer check */
1919 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1923 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1926 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1927 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1928 M_AADD(s2, s1, REG_ITMP1);
1929 /* implicit null-pointer check */
1930 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1933 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1934 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1936 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1937 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1938 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1939 M_AADD(s2, s1, REG_ITMP1);
1940 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1941 /* implicit null-pointer check */
1942 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1945 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1948 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1949 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1950 M_ASLL_IMM(s2, 2, REG_ITMP2);
1951 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1952 /* implicit null-pointer check */
1953 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1956 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1960 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1961 M_ASLL_IMM(s2, 3, REG_ITMP2);
1962 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1963 /* implicit null-pointer check */
1964 #if SIZEOF_VOID_P == 8
1965 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1967 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1971 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1974 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1975 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1976 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1977 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1978 /* implicit null-pointer check */
1979 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1983 case ICMD_GETSTATIC: /* ... ==> ..., value */
1985 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1986 uf = iptr->sx.s23.s3.uf;
1987 fieldtype = uf->fieldref->parseddesc.fd->type;
1988 disp = dseg_add_unique_address(cd, uf);
1990 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1993 fi = iptr->sx.s23.s3.fmiref->p.field;
1994 fieldtype = fi->type;
1995 disp = dseg_add_address(cd, fi->value);
1997 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1998 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2002 M_ALD(REG_ITMP1, REG_PV, disp);
2004 switch (fieldtype) {
2006 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2007 M_ILD_INTERN(d, REG_ITMP1, 0);
2010 #if SIZEOF_VOID_P == 8
2011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2013 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2015 M_LLD_INTERN(d, REG_ITMP1, 0);
2018 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2019 M_ALD_INTERN(d, REG_ITMP1, 0);
2022 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2023 M_FLD_INTERN(d, REG_ITMP1, 0);
2026 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2027 M_DLD_INTERN(d, REG_ITMP1, 0);
2030 emit_store_dst(jd, iptr, d);
2033 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2035 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2036 uf = iptr->sx.s23.s3.uf;
2037 fieldtype = uf->fieldref->parseddesc.fd->type;
2038 disp = dseg_add_unique_address(cd, uf);
2040 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2043 fi = iptr->sx.s23.s3.fmiref->p.field;
2044 fieldtype = fi->type;
2045 disp = dseg_add_address(cd, fi->value);
2047 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2048 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2052 M_ALD(REG_ITMP1, REG_PV, disp);
2054 switch (fieldtype) {
2056 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2057 M_IST_INTERN(s1, REG_ITMP1, 0);
2060 #if SIZEOF_VOID_P == 8
2061 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2063 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2065 M_LST_INTERN(s1, REG_ITMP1, 0);
2068 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2069 M_AST_INTERN(s1, REG_ITMP1, 0);
2072 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2073 M_FST_INTERN(s1, REG_ITMP1, 0);
2076 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2077 M_DST_INTERN(s1, REG_ITMP1, 0);
2082 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2084 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2085 uf = iptr->sx.s23.s3.uf;
2086 fieldtype = uf->fieldref->parseddesc.fd->type;
2087 disp = dseg_add_unique_address(cd, uf);
2089 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2092 fi = iptr->sx.s23.s3.fmiref->p.field;
2093 fieldtype = fi->type;
2094 disp = dseg_add_address(cd, fi->value);
2096 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2097 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2101 M_ALD(REG_ITMP1, REG_PV, disp);
2103 switch (fieldtype) {
2105 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2108 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2111 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2114 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2117 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2123 case ICMD_GETFIELD: /* ... ==> ..., value */
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 emit_nullpointer_check(cd, iptr, s1);
2128 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2129 uf = iptr->sx.s23.s3.uf;
2130 fieldtype = uf->fieldref->parseddesc.fd->type;
2133 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2136 fi = iptr->sx.s23.s3.fmiref->p.field;
2137 fieldtype = fi->type;
2141 switch (fieldtype) {
2143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2147 #if SIZEOF_VOID_P == 8
2148 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2152 M_LLD_GETFIELD(d, s1, disp);
2156 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2160 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2164 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2168 emit_store_dst(jd, iptr, d);
2171 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2174 emit_nullpointer_check(cd, iptr, s1);
2176 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2177 uf = iptr->sx.s23.s3.uf;
2178 fieldtype = uf->fieldref->parseddesc.fd->type;
2182 fi = iptr->sx.s23.s3.fmiref->p.field;
2183 fieldtype = fi->type;
2187 #if SIZEOF_VOID_P == 8
2188 if (IS_INT_LNG_TYPE(fieldtype))
2189 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2191 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2193 if (IS_INT_LNG_TYPE(fieldtype)) {
2194 if (IS_2_WORD_TYPE(fieldtype))
2195 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2197 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2200 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2203 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2204 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2206 switch (fieldtype) {
2208 M_IST(s2, s1, disp);
2211 M_LST(s2, s1, disp);
2214 M_AST(s2, s1, disp);
2217 M_FST(s2, s1, disp);
2220 M_DST(s2, s1, disp);
2225 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2227 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2228 emit_nullpointer_check(cd, iptr, s1);
2230 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2231 uf = iptr->sx.s23.s3.uf;
2232 fieldtype = uf->fieldref->parseddesc.fd->type;
2235 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2238 fi = iptr->sx.s23.s3.fmiref->p.field;
2239 fieldtype = fi->type;
2243 switch (fieldtype) {
2245 M_IST(REG_ZERO, s1, disp);
2248 M_LST(REG_ZERO, s1, disp);
2251 M_AST(REG_ZERO, s1, disp);
2254 M_FST(REG_ZERO, s1, disp);
2257 M_DST(REG_ZERO, s1, disp);
2263 /* branch operations **************************************************/
2265 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2268 M_INTMOVE(s1, REG_ITMP1_XPTR);
2270 #ifdef ENABLE_VERIFIER
2271 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2272 uc = iptr->sx.s23.s2.uc;
2274 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2276 #endif /* ENABLE_VERIFIER */
2278 disp = dseg_add_functionptr(cd, asm_handle_exception);
2279 M_ALD(REG_ITMP2, REG_PV, disp);
2280 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2282 M_NOP; /* nop ensures that XPC is less than the end */
2283 /* of basic block */
2287 case ICMD_GOTO: /* ... ==> ... */
2288 case ICMD_RET: /* ... ==> ... */
2290 emit_br(cd, iptr->dst.block);
2294 case ICMD_JSR: /* ... ==> ... */
2296 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2300 case ICMD_IFNULL: /* ..., value ==> ... */
2301 case ICMD_IFNONNULL:
2303 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2304 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2307 case ICMD_IFEQ: /* ..., value ==> ... */
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 if (iptr->sx.val.i == 0)
2311 emit_beqz(cd, iptr->dst.block, s1);
2313 ICONST(REG_ITMP2, iptr->sx.val.i);
2314 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2318 case ICMD_IFLT: /* ..., value ==> ... */
2320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2321 if (iptr->sx.val.i == 0)
2322 emit_bltz(cd, iptr->dst.block, s1);
2324 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2325 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2327 ICONST(REG_ITMP2, iptr->sx.val.i);
2328 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2330 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2334 case ICMD_IFLE: /* ..., value ==> ... */
2336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 if (iptr->sx.val.i == 0)
2338 emit_blez(cd, iptr->dst.block, s1);
2340 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2341 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2342 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2345 ICONST(REG_ITMP2, iptr->sx.val.i);
2346 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2347 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2352 case ICMD_IFNE: /* ..., value ==> ... */
2354 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2355 if (iptr->sx.val.i == 0)
2356 emit_bnez(cd, iptr->dst.block, s1);
2358 ICONST(REG_ITMP2, iptr->sx.val.i);
2359 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2363 case ICMD_IFGT: /* ..., value ==> ... */
2365 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2366 if (iptr->sx.val.i == 0)
2367 emit_bgtz(cd, iptr->dst.block, s1);
2369 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2370 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2371 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2374 ICONST(REG_ITMP2, iptr->sx.val.i);
2375 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2376 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2381 case ICMD_IFGE: /* ..., value ==> ... */
2383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2384 if (iptr->sx.val.i == 0)
2385 emit_bgez(cd, iptr->dst.block, s1);
2387 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2388 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2390 ICONST(REG_ITMP2, iptr->sx.val.i);
2391 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2393 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2397 case ICMD_IF_LEQ: /* ..., value ==> ... */
2399 #if SIZEOF_VOID_P == 8
2400 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2401 if (iptr->sx.val.l == 0)
2402 emit_beqz(cd, iptr->dst.block, s1);
2404 LCONST(REG_ITMP2, iptr->sx.val.l);
2405 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2408 if (iptr->sx.val.l == 0) {
2409 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2410 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2411 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2414 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2415 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2416 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2417 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2418 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2419 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2420 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2421 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2426 case ICMD_IF_LLT: /* ..., value ==> ... */
2428 #if SIZEOF_VOID_P == 8
2429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2430 if (iptr->sx.val.l == 0)
2431 emit_bltz(cd, iptr->dst.block, s1);
2433 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2434 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2436 LCONST(REG_ITMP2, iptr->sx.val.l);
2437 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2439 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2442 if (iptr->sx.val.l == 0) {
2443 /* if high word is less than zero, the whole long is too */
2444 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2445 emit_bltz(cd, iptr->dst.block, s1);
2448 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2449 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2450 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2451 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2452 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2453 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2455 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2456 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2457 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2462 case ICMD_IF_LLE: /* ..., value ==> ... */
2464 #if SIZEOF_VOID_P == 8
2465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2466 if (iptr->sx.val.l == 0)
2467 emit_blez(cd, iptr->dst.block, s1);
2469 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2470 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2471 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2474 LCONST(REG_ITMP2, iptr->sx.val.l);
2475 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2476 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2480 if (iptr->sx.val.l == 0) {
2481 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2482 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2484 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2485 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2488 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2489 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2490 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2491 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2492 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2493 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2495 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2496 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2497 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2502 case ICMD_IF_LNE: /* ..., value ==> ... */
2504 #if SIZEOF_VOID_P == 8
2505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506 if (iptr->sx.val.l == 0)
2507 emit_bnez(cd, iptr->dst.block, s1);
2509 LCONST(REG_ITMP2, iptr->sx.val.l);
2510 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2513 if (iptr->sx.val.l == 0) {
2514 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2515 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2516 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2519 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2520 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2521 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2522 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2523 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2524 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2525 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2526 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2531 case ICMD_IF_LGT: /* ..., value ==> ... */
2533 #if SIZEOF_VOID_P == 8
2534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2535 if (iptr->sx.val.l == 0)
2536 emit_bgtz(cd, iptr->dst.block, s1);
2538 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2539 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2540 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2543 LCONST(REG_ITMP2, iptr->sx.val.l);
2544 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2545 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2549 if (iptr->sx.val.l == 0) {
2550 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2551 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2552 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2554 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2557 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2558 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2559 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2560 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2561 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2562 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2564 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2565 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2566 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2571 case ICMD_IF_LGE: /* ..., value ==> ... */
2573 #if SIZEOF_VOID_P == 8
2574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2575 if (iptr->sx.val.l == 0)
2576 emit_bgez(cd, iptr->dst.block, s1);
2578 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2579 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2582 LCONST(REG_ITMP2, iptr->sx.val.l);
2583 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2585 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2588 if (iptr->sx.val.l == 0) {
2589 /* if high word is greater equal zero, the whole long is too */
2590 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2591 emit_bgez(cd, iptr->dst.block, s1);
2594 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2595 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2596 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2597 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2598 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2599 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2601 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2602 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2603 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2608 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2609 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2610 #if SIZEOF_VOID_P == 8
2611 case ICMD_IF_LCMPEQ:
2614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2615 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2616 emit_beq(cd, iptr->dst.block, s1, s2);
2619 #if SIZEOF_VOID_P == 4
2620 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2621 /* op1 = target JavaVM pc */
2623 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2624 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2625 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2627 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2628 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2629 emit_beq(cd, iptr->dst.block, s1, s2);
2633 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2634 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2635 #if SIZEOF_VOID_P == 8
2636 case ICMD_IF_LCMPNE:
2639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2641 emit_bne(cd, iptr->dst.block, s1, s2);
2644 #if SIZEOF_VOID_P == 4
2645 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2647 /* TODO: could be optimized (XOR or SUB) */
2648 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2649 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2650 emit_bne(cd, iptr->dst.block, s1, s2);
2651 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2652 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2653 emit_bne(cd, iptr->dst.block, s1, s2);
2657 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2658 #if SIZEOF_VOID_P == 8
2659 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2663 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2664 M_CMPLT(s1, s2, REG_ITMP3);
2665 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2668 #if SIZEOF_VOID_P == 4
2669 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2671 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2672 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2673 M_CMPLT(s1, s2, REG_ITMP3);
2674 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2675 M_CMPGT(s1, s2, REG_ITMP3);
2676 /* load low-bits before the branch, so we know the distance */
2677 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2678 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2679 M_BNEZ(REG_ITMP3, 4); /* XXX */
2681 M_CMPULT(s1, s2, REG_ITMP3);
2682 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2686 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2687 #if SIZEOF_VOID_P == 8
2688 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2692 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2693 M_CMPGT(s1, s2, REG_ITMP3);
2694 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2697 #if SIZEOF_VOID_P == 4
2698 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2700 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2701 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2702 M_CMPGT(s1, s2, REG_ITMP3);
2703 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2704 M_CMPLT(s1, s2, REG_ITMP3);
2705 /* load low-bits before the branch, so we know the distance */
2706 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2707 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2708 M_BNEZ(REG_ITMP3, 4); /* XXX */
2710 M_CMPUGT(s1, s2, REG_ITMP3);
2711 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2715 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2716 #if SIZEOF_VOID_P == 8
2717 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2722 M_CMPGT(s1, s2, REG_ITMP3);
2723 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2726 #if SIZEOF_VOID_P == 4
2727 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2729 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2730 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2731 M_CMPLT(s1, s2, REG_ITMP3);
2732 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2733 M_CMPGT(s1, s2, REG_ITMP3);
2734 /* load low-bits before the branch, so we know the distance */
2735 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2736 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2737 M_BNEZ(REG_ITMP3, 4); /* XXX */
2739 M_CMPUGT(s1, s2, REG_ITMP3);
2740 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2744 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2745 #if SIZEOF_VOID_P == 8
2746 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2750 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2751 M_CMPLT(s1, s2, REG_ITMP3);
2752 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2755 #if SIZEOF_VOID_P == 4
2756 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2758 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2759 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2760 M_CMPGT(s1, s2, REG_ITMP3);
2761 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2762 M_CMPLT(s1, s2, REG_ITMP3);
2763 /* load low-bits before the branch, so we know the distance */
2764 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2765 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2766 M_BNEZ(REG_ITMP3, 4); /* XXX */
2768 M_CMPULT(s1, s2, REG_ITMP3);
2769 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2773 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2774 #if SIZEOF_VOID_P == 8
2778 REPLACEMENT_POINT_RETURN(cd, iptr);
2779 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2780 M_INTMOVE(s1, REG_RESULT);
2781 goto nowperformreturn;
2783 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2785 REPLACEMENT_POINT_RETURN(cd, iptr);
2786 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2787 M_INTMOVE(s1, REG_RESULT);
2789 #ifdef ENABLE_VERIFIER
2790 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2791 uc = iptr->sx.s23.s2.uc;
2793 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2795 #endif /* ENABLE_VERIFIER */
2796 goto nowperformreturn;
2798 #if SIZEOF_VOID_P == 4
2799 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2801 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2802 M_LNGMOVE(s1, REG_RESULT_PACKED);
2803 goto nowperformreturn;
2806 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2807 REPLACEMENT_POINT_RETURN(cd, iptr);
2808 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2809 M_FLTMOVE(s1, REG_FRESULT);
2810 goto nowperformreturn;
2812 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2814 REPLACEMENT_POINT_RETURN(cd, iptr);
2815 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2816 M_DBLMOVE(s1, REG_FRESULT);
2817 goto nowperformreturn;
2819 case ICMD_RETURN: /* ... ==> ... */
2821 REPLACEMENT_POINT_RETURN(cd, iptr);
2827 p = cd->stackframesize;
2829 #if !defined(NDEBUG)
2830 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2831 emit_verbosecall_exit(jd);
2834 #if defined(ENABLE_THREADS)
2835 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2836 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2837 M_ALD(REG_ITMP3, REG_PV, disp);
2839 /* we need to save the proper return value */
2841 switch (iptr->opc) {
2844 #if SIZEOF_VOID_P == 8
2847 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2848 M_JSR(REG_RA, REG_ITMP3);
2849 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2851 #if SIZEOF_VOID_P == 4
2853 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2854 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2855 M_JSR(REG_RA, REG_ITMP3);
2861 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2862 M_JSR(REG_RA, REG_ITMP3);
2863 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2866 M_JSR(REG_RA, REG_ITMP3);
2867 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2871 /* and now restore the proper return value */
2873 switch (iptr->opc) {
2876 #if SIZEOF_VOID_P == 8
2879 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2881 #if SIZEOF_VOID_P == 4
2883 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2888 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2894 /* restore return address */
2896 if (!jd->isleafmethod) {
2897 p--; M_ALD(REG_RA, REG_SP, p * 8);
2900 /* restore saved registers */
2902 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2903 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2905 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2906 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2909 /* deallocate stack and return */
2911 if (cd->stackframesize) {
2914 disp = cd->stackframesize * 8;
2915 lo = (short) (disp);
2916 hi = (short) (((disp) - lo) >> 16);
2920 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2922 M_LUI(REG_ITMP3,hi);
2923 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2925 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2938 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2941 branch_target_t *table;
2943 table = iptr->dst.table;
2945 l = iptr->sx.s23.s2.tablelow;
2946 i = iptr->sx.s23.s3.tablehigh;
2948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2950 {M_INTMOVE(s1, REG_ITMP1);}
2951 else if (l <= 32768) {
2952 M_IADD_IMM(s1, -l, REG_ITMP1);
2955 ICONST(REG_ITMP2, l);
2956 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2959 /* number of targets */
2964 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2965 emit_beqz(cd, table[0].block, REG_ITMP2);
2967 /* build jump table top down and use address of lowest entry */
2972 dseg_add_target(cd, table->block);
2977 /* length of dataseg after last dseg_add_target is used by load */
2979 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2980 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2981 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2988 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2991 lookup_target_t *lookup;
2993 lookup = iptr->dst.lookup;
2995 i = iptr->sx.s23.s2.lookupcount;
2997 MCODECHECK((i<<2)+8);
2998 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3001 ICONST(REG_ITMP2, lookup->value);
3002 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3006 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3012 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3014 bte = iptr->sx.s23.s3.bte;
3018 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3020 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3021 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3022 case ICMD_INVOKEINTERFACE:
3024 REPLACEMENT_POINT_INVOKE(cd, iptr);
3026 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3028 um = iptr->sx.s23.s3.um;
3029 md = um->methodref->parseddesc.md;
3032 lm = iptr->sx.s23.s3.fmiref->p.method;
3034 md = lm->parseddesc;
3038 s3 = md->paramcount;
3040 MCODECHECK((s3 << 1) + 64);
3042 /* copy arguments to registers or stack location */
3044 for (s3 = s3 - 1; s3 >= 0; s3--) {
3045 var = VAR(iptr->sx.s23.s2.args[s3]);
3046 d = md->params[s3].regoff;
3048 if (var->flags & PREALLOC)
3051 if (IS_INT_LNG_TYPE(var->type)) {
3052 #if SIZEOF_VOID_P == 8
3053 if (!md->params[s3].inmemory) {
3054 s1 = emit_load(jd, iptr, var, d);
3058 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3059 M_LST(s1, REG_SP, d);
3062 if (!md->params[s3].inmemory) {
3063 s1 = emit_load(jd, iptr, var, d);
3065 if (IS_2_WORD_TYPE(var->type))
3071 if (IS_2_WORD_TYPE(var->type)) {
3072 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3073 M_LST(s1, REG_SP, d);
3076 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3077 M_IST(s1, REG_SP, d);
3083 if (!md->params[s3].inmemory) {
3084 s1 = emit_load(jd, iptr, var, d);
3085 if (IS_2_WORD_TYPE(var->type))
3091 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3092 if (IS_2_WORD_TYPE(var->type))
3093 M_DST(s1, REG_SP, d);
3095 M_FST(s1, REG_SP, d);
3100 switch (iptr->opc) {
3102 disp = dseg_add_functionptr(cd, bte->fp);
3104 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3106 /* generate the actual call */
3108 /* TWISTI: i actually don't know the reason for using
3109 REG_ITMP3 here instead of REG_PV. */
3111 M_JSR(REG_RA, REG_ITMP3);
3113 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3114 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3115 M_LDA(REG_PV, REG_RA, -disp);
3117 emit_exception_check(cd, iptr);
3120 case ICMD_INVOKESPECIAL:
3121 emit_nullpointer_check(cd, iptr, REG_A0);
3124 case ICMD_INVOKESTATIC:
3126 disp = dseg_add_unique_address(cd, um);
3128 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3132 disp = dseg_add_address(cd, lm->stubroutine);
3134 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3136 /* generate the actual call */
3138 M_JSR(REG_RA, REG_PV);
3140 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3141 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3142 M_LDA(REG_PV, REG_RA, -disp);
3145 case ICMD_INVOKEVIRTUAL:
3146 emit_nullpointer_check(cd, iptr, REG_A0);
3149 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3154 s1 = OFFSET(vftbl_t, table[0]) +
3155 sizeof(methodptr) * lm->vftblindex;
3157 /* implicit null-pointer check */
3158 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3159 M_ALD(REG_PV, REG_METHODPTR, s1);
3161 /* generate the actual call */
3163 M_JSR(REG_RA, REG_PV);
3165 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3166 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3167 M_LDA(REG_PV, REG_RA, -disp);
3170 case ICMD_INVOKEINTERFACE:
3171 emit_nullpointer_check(cd, iptr, REG_A0);
3174 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3180 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3181 sizeof(methodptr*) * lm->class->index;
3183 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3186 /* implicit null-pointer check */
3187 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3188 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3189 M_ALD(REG_PV, REG_METHODPTR, s2);
3191 /* generate the actual call */
3193 M_JSR(REG_RA, REG_PV);
3195 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3196 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3197 M_LDA(REG_PV, REG_RA, -disp);
3201 /* store return value */
3203 d = md->returntype.type;
3205 if (d != TYPE_VOID) {
3206 if (IS_INT_LNG_TYPE(d)) {
3207 #if SIZEOF_VOID_P == 8
3208 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3209 M_INTMOVE(REG_RESULT, s1);
3211 if (IS_2_WORD_TYPE(d)) {
3212 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3213 M_LNGMOVE(REG_RESULT_PACKED, s1);
3216 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3217 M_INTMOVE(REG_RESULT, s1);
3222 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3223 if (IS_2_WORD_TYPE(d))
3224 M_DMOV(REG_FRESULT, s1);
3226 M_FMOV(REG_FRESULT, s1);
3228 emit_store_dst(jd, iptr, s1);
3233 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3235 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3239 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3244 super = iptr->sx.s23.s3.c.cls;
3245 superindex = super->index;
3248 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3249 CODEGEN_CRITICAL_SECTION_NEW;
3251 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3253 /* if class is not resolved, check which code to call */
3255 if (super == NULL) {
3256 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3258 cr = iptr->sx.s23.s3.c.ref;
3259 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3261 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3264 M_ILD(REG_ITMP2, REG_PV, disp);
3265 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3266 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3269 /* interface checkcast code */
3271 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3272 if (super == NULL) {
3273 cr = iptr->sx.s23.s3.c.ref;
3275 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3279 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3282 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3283 M_ILD(REG_ITMP3, REG_ITMP2,
3284 OFFSET(vftbl_t, interfacetablelength));
3285 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3286 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3288 M_ALD(REG_ITMP3, REG_ITMP2,
3289 OFFSET(vftbl_t, interfacetable[0]) -
3290 superindex * sizeof(methodptr*));
3291 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3294 emit_label_br(cd, BRANCH_LABEL_4);
3296 emit_label(cd, BRANCH_LABEL_3);
3299 /* class checkcast code */
3301 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3302 if (super == NULL) {
3303 emit_label(cd, BRANCH_LABEL_2);
3305 cr = iptr->sx.s23.s3.c.ref;
3306 disp = dseg_add_unique_address(cd, NULL);
3308 patcher_add_patch_ref(jd,
3309 PATCHER_resolve_classref_to_vftbl,
3313 disp = dseg_add_address(cd, super->vftbl);
3315 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3318 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3319 M_ALD(REG_ITMP3, REG_PV, disp);
3321 CODEGEN_CRITICAL_SECTION_START;
3323 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3324 /* if (s1 != REG_ITMP1) { */
3325 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3326 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3327 /* #if defined(ENABLE_THREADS) */
3328 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3330 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3332 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3333 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3334 M_ALD(REG_ITMP3, REG_PV, disp);
3335 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3337 CODEGEN_CRITICAL_SECTION_END;
3340 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3341 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3344 emit_label(cd, BRANCH_LABEL_5);
3347 if (super == NULL) {
3348 emit_label(cd, BRANCH_LABEL_1);
3349 emit_label(cd, BRANCH_LABEL_4);
3352 d = codegen_reg_of_dst(jd, iptr, s1);
3355 s1 = emit_load_s1(jd, iptr, REG_A0);
3356 M_INTMOVE(s1, REG_A0);
3358 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3359 cr = iptr->sx.s23.s3.c.ref;
3360 disp = dseg_add_unique_address(cd, NULL);
3362 patcher_add_patch_ref(jd,
3363 PATCHER_resolve_classref_to_classinfo,
3367 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3370 M_ALD(REG_A1, REG_PV, disp);
3371 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3372 M_ALD(REG_ITMP3, REG_PV, disp);
3373 M_JSR(REG_RA, REG_ITMP3);
3376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3377 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3379 d = codegen_reg_of_dst(jd, iptr, s1);
3383 emit_store_dst(jd, iptr, d);
3386 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3392 super = iptr->sx.s23.s3.c.cls;
3394 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3399 super = iptr->sx.s23.s3.c.cls;
3400 superindex = super->index;
3403 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3404 CODEGEN_CRITICAL_SECTION_NEW;
3406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3407 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3410 M_MOV(s1, REG_ITMP1);
3416 /* if class is not resolved, check which code to call */
3418 if (super == NULL) {
3419 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3421 cr = iptr->sx.s23.s3.c.ref;
3422 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3424 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3427 M_ILD(REG_ITMP3, REG_PV, disp);
3428 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3429 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3432 /* interface instanceof code */
3434 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3435 if (super == NULL) {
3436 cr = iptr->sx.s23.s3.c.ref;
3438 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3442 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3445 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3446 M_ILD(REG_ITMP3, REG_ITMP1,
3447 OFFSET(vftbl_t, interfacetablelength));
3448 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3449 M_BLEZ(REG_ITMP3, 3);
3451 M_ALD(REG_ITMP1, REG_ITMP1,
3452 OFFSET(vftbl_t, interfacetable[0]) -
3453 superindex * sizeof(methodptr*));
3454 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3457 emit_label_br(cd, BRANCH_LABEL_4);
3459 emit_label(cd, BRANCH_LABEL_3);
3462 /* class instanceof code */
3464 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3465 if (super == NULL) {
3466 emit_label(cd, BRANCH_LABEL_2);
3468 cr = iptr->sx.s23.s3.c.ref;
3469 disp = dseg_add_unique_address(cd, NULL);
3471 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3475 disp = dseg_add_address(cd, super->vftbl);
3477 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3480 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3481 M_ALD(REG_ITMP2, REG_PV, disp);
3483 CODEGEN_CRITICAL_SECTION_START;
3485 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3486 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3487 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3489 CODEGEN_CRITICAL_SECTION_END;
3491 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3492 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3496 emit_label(cd, BRANCH_LABEL_5);
3499 if (super == NULL) {
3500 emit_label(cd, BRANCH_LABEL_1);
3501 emit_label(cd, BRANCH_LABEL_4);
3504 emit_store_dst(jd, iptr, d);
3508 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3510 /* check for negative sizes and copy sizes to stack if necessary */
3512 MCODECHECK((iptr->s1.argcount << 1) + 64);
3514 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3516 var = VAR(iptr->sx.s23.s2.args[s1]);
3518 /* copy SAVEDVAR sizes to stack */
3520 if (!(var->flags & PREALLOC)) {
3521 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3522 #if SIZEOF_VOID_P == 8
3523 M_LST(s2, REG_SP, s1 * 8);
3525 M_IST(s2, REG_SP, (s1 + 2) * 8);
3530 /* a0 = dimension count */
3532 ICONST(REG_A0, iptr->s1.argcount);
3534 /* is patcher function set? */
3536 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3537 cr = iptr->sx.s23.s3.c.ref;
3538 disp = dseg_add_unique_address(cd, NULL);
3540 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3544 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3547 /* a1 = arraydescriptor */
3549 M_ALD(REG_A1, REG_PV, disp);
3551 /* a2 = pointer to dimensions = stack pointer */
3553 #if SIZEOF_VOID_P == 8
3554 M_MOV(REG_SP, REG_A2);
3556 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3559 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3560 M_ALD(REG_ITMP3, REG_PV, disp);
3561 M_JSR(REG_RA, REG_ITMP3);
3564 /* check for exception before result assignment */
3566 emit_exception_check(cd, iptr);
3568 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3569 M_INTMOVE(REG_RESULT, d);
3570 emit_store_dst(jd, iptr, d);
3574 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3579 } /* for instruction */
3581 MCODECHECK(64); /* XXX require smaller number? */
3583 /* At the end of a basic block we may have to append some nops,
3584 because the patcher stub calling code might be longer than the
3585 actual instruction. So codepatching does not change the
3586 following block unintentionally. */
3588 if (cd->mcodeptr < cd->lastmcodeptr) {
3589 while (cd->mcodeptr < cd->lastmcodeptr)
3593 } /* if (bptr -> flags >= BBREACHED) */
3594 } /* for basic block */
3596 dseg_createlinenumbertable(cd);
3598 /* generate traps */
3600 emit_patcher_traps(jd);
3602 /* everything's ok */
3608 /* codegen_emit_stub_compiler **************************************************
3610 Emits a stub routine which calls the compiler.
3612 *******************************************************************************/
3614 void codegen_emit_stub_compiler(jitdata *jd)
3619 /* get required compiler data */
3624 /* code for the stub */
3626 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3627 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3633 /* codegen_emit_stub_native ****************************************************
3635 Emits a stub routine which calls a native method.
3637 *******************************************************************************/
3639 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3649 s4 funcdisp; /* displacement of the function */
3651 /* get required compiler data */
3657 /* initialize variables */
3660 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3662 /* calculate stack frame size */
3664 cd->stackframesize =
3665 1 + /* return address */
3666 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3667 sizeof(localref_table) / SIZEOF_VOID_P +
3668 md->paramcount + /* for saving arguments over calls */
3669 #if SIZEOF_VOID_P == 4
3670 5 + /* additional save space (MIPS32) */
3672 1 + /* for saving return address */
3675 /* adjust stackframe size for 16-byte alignment */
3677 if (cd->stackframesize & 1)
3678 cd->stackframesize++;
3680 /* create method header */
3682 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3683 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3684 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3685 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3686 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3687 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3688 (void) dseg_addlinenumbertablesize(cd);
3689 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3691 /* generate stub code */
3693 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3694 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3696 #if !defined(NDEBUG)
3697 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3698 emit_verbosecall_enter(jd);
3701 /* get function address (this must happen before the stackframeinfo) */
3703 funcdisp = dseg_add_functionptr(cd, f);
3705 #if !defined(WITH_STATIC_CLASSPATH)
3707 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3710 /* save integer and float argument registers */
3712 #if SIZEOF_VOID_P == 8
3713 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3714 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3715 s1 = md->params[i].regoff;
3716 M_AST(s1, REG_SP, j * 8);
3721 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3722 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3723 if (!md->params[i].inmemory) {
3724 s1 = md->params[i].regoff;
3726 if (IS_2_WORD_TYPE(md->params[i].type))
3727 M_LST(s1, REG_SP, j * 8);
3729 M_IST(s1, REG_SP, j * 8);
3737 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3738 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3739 s1 = md->params[i].regoff;
3741 if (IS_2_WORD_TYPE(md->params[i].type))
3742 M_DST(s1, REG_SP, j * 8);
3744 M_FST(s1, REG_SP, j * 8);
3750 /* prepare data structures for native function call */
3752 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3753 M_MOV(REG_PV, REG_A1);
3754 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3755 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3756 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3757 M_ALD(REG_ITMP3, REG_PV, disp);
3758 M_JSR(REG_RA, REG_ITMP3);
3759 M_NOP; /* XXX fill me! */
3761 /* restore integer and float argument registers */
3763 #if SIZEOF_VOID_P == 8
3764 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3765 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3766 s1 = md->params[i].regoff;
3767 M_LLD(s1, REG_SP, j * 8);
3772 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3773 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3774 if (!md->params[i].inmemory) {
3775 s1 = md->params[i].regoff;
3777 if (IS_2_WORD_TYPE(md->params[i].type))
3778 M_LLD(s1, REG_SP, j * 8);
3780 M_ILD(s1, REG_SP, j * 8);
3788 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3789 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3790 s1 = md->params[i].regoff;
3792 if (IS_2_WORD_TYPE(md->params[i].type))
3793 M_DLD(s1, REG_SP, j * 8);
3795 M_FLD(s1, REG_SP, j * 8);
3801 /* copy or spill arguments to new locations */
3803 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3804 t = md->params[i].type;
3806 if (IS_INT_LNG_TYPE(t)) {
3807 if (!md->params[i].inmemory) {
3808 s1 = md->params[i].regoff;
3809 s2 = nmd->params[j].regoff;
3811 if (!nmd->params[j].inmemory) {
3812 #if SIZEOF_VOID_P == 8
3815 if (IS_2_WORD_TYPE(t))
3822 #if SIZEOF_VOID_P == 8
3823 M_LST(s1, REG_SP, s2);
3825 if (IS_2_WORD_TYPE(t))
3826 M_LST(s1, REG_SP, s2);
3828 M_IST(s1, REG_SP, s2);
3833 s1 = md->params[i].regoff + cd->stackframesize * 8;
3834 s2 = nmd->params[j].regoff;
3836 #if SIZEOF_VOID_P == 8
3837 M_LLD(REG_ITMP1, REG_SP, s1);
3838 M_LST(REG_ITMP1, REG_SP, s2);
3840 if (IS_2_WORD_TYPE(t)) {
3841 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3842 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3845 M_ILD(REG_ITMP1, REG_SP, s1);
3846 M_IST(REG_ITMP1, REG_SP, s2);
3852 if (!md->params[i].inmemory) {
3853 s1 = md->params[i].regoff;
3854 s2 = nmd->params[j].regoff;
3856 if (!nmd->params[j].inmemory) {
3857 #if SIZEOF_VOID_P == 8
3858 if (IS_2_WORD_TYPE(t))
3863 /* On MIPS32 float arguments for native functions
3864 can never be in float argument registers, since
3865 the first argument is _always_ an integer
3866 argument (JNIEnv) */
3868 if (IS_2_WORD_TYPE(t)) {
3869 /* double high/low order is endian
3870 independent: even numbered holds low
3871 32-bits, odd numbered high 32-bits */
3873 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3874 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3881 #if SIZEOF_VOID_P == 8
3882 if (IS_2_WORD_TYPE(t))
3883 M_DST(s1, REG_SP, s2);
3885 M_FST(s1, REG_SP, s2);
3887 /* s1 may have been originally in 2 int registers,
3888 but was moved out by the native function
3889 argument(s), just get low register */
3891 if (IS_2_WORD_TYPE(t))
3892 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3894 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3899 s1 = md->params[i].regoff + cd->stackframesize * 8;
3900 s2 = nmd->params[j].regoff;
3902 #if SIZEOF_VOID_P == 8
3903 if (IS_2_WORD_TYPE(t)) {
3904 M_DLD(REG_FTMP1, REG_SP, s1);
3905 M_DST(REG_FTMP1, REG_SP, s2);
3908 M_FLD(REG_FTMP1, REG_SP, s1);
3909 M_FST(REG_FTMP1, REG_SP, s2);
3912 if (IS_2_WORD_TYPE(t)) {
3913 M_DLD(REG_FTMP1, REG_SP, s1);
3914 M_DST(REG_FTMP1, REG_SP, s2);
3917 M_FLD(REG_FTMP1, REG_SP, s1);
3918 M_FST(REG_FTMP1, REG_SP, s2);
3925 /* put class into second argument register */
3927 if (m->flags & ACC_STATIC) {
3928 disp = dseg_add_address(cd, m->class);
3929 M_ALD(REG_A1, REG_PV, disp);
3932 /* put env into first argument register */
3934 disp = dseg_add_address(cd, _Jv_env);
3935 M_ALD(REG_A0, REG_PV, disp);
3937 /* do the native function call */
3939 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3940 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3941 M_NOP; /* delay slot */
3943 /* save return value */
3945 switch (md->returntype.type) {
3946 #if SIZEOF_VOID_P == 8
3950 M_LST(REG_RESULT, REG_SP, 0 * 8);
3954 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3959 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
3962 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
3966 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
3973 #if !defined(NDEBUG)
3974 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3975 emit_verbosecall_exit(jd);
3978 /* remove native stackframe info */
3980 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3981 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3982 M_ALD(REG_ITMP3, REG_PV, disp);
3983 M_JSR(REG_RA, REG_ITMP3);
3984 M_NOP; /* XXX fill me! */
3985 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3987 /* restore return value */
3989 switch (md->returntype.type) {
3990 #if SIZEOF_VOID_P == 8
3994 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3998 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4003 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4006 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4010 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4017 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4019 /* check for exception */
4021 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4022 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4024 M_RET(REG_RA); /* return to caller */
4025 M_NOP; /* DELAY SLOT */
4027 /* handle exception */
4029 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4030 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4031 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4032 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4034 /* Generate patcher traps. */
4036 emit_patcher_traps(jd);
4041 * These are local overrides for various environment variables in Emacs.
4042 * Please do not remove this and leave it at the end of the file, where
4043 * Emacs will automagically detect them.
4044 * ---------------------------------------------------------------------
4047 * indent-tabs-mode: t
4051 * vim:noexpandtab:sw=4:ts=4: