1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 8011 2007-06-05 10:06:18Z twisti $
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
42 #include "mm/memory.h"
44 #include "native/native.h"
46 #include "threads/lock-common.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/md.h"
59 #include "vm/jit/patcher.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
63 #if defined(ENABLE_LSRA)
64 # include "vm/jit/allocator/lsra.h"
67 #include "vmcore/class.h"
68 #include "vmcore/options.h"
71 /* codegen_emit ****************************************************************
73 Generates machine code.
75 *******************************************************************************/
77 bool codegen_emit(jitdata *jd)
83 s4 len, s1, s2, s3, d, disp;
89 constant_classref *cr;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 unresolved_method *um;
93 builtintable_entry *bte;
100 /* get required compiler data */
107 /* prevent compiler warnings */
122 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
124 /* space to save used callee saved registers */
126 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
127 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
129 cd->stackframesize = rd->memuse + savedregs_num;
131 #if defined(ENABLE_THREADS)
132 /* space to save argument of monitor_enter */
134 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
135 # if SIZEOF_VOID_P == 8
136 cd->stackframesize++;
139 cd->stackframesize += 2;
144 /* keep stack 16-byte aligned */
146 if (cd->stackframesize & 1)
147 cd->stackframesize++;
149 /* create method header */
151 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
152 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
154 #if defined(ENABLE_THREADS)
155 /* IsSync contains the offset relative to the stack pointer for the
156 argument of monitor_exit used in the exception handler. Since the
157 offset could be zero and give a wrong meaning of the flag it is
161 if (checksync && (m->flags & ACC_SYNCHRONIZED))
162 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
165 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
167 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
168 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
169 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 dseg_addlinenumbertablesize(cd);
171 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
173 /* create exception table */
175 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
176 dseg_add_target(cd, ex->start);
177 dseg_add_target(cd, ex->end);
178 dseg_add_target(cd, ex->handler);
179 (void) dseg_add_unique_address(cd, ex->catchtype.any);
182 /* create stack frame (if necessary) */
184 if (cd->stackframesize)
185 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
187 /* save return address and used callee saved registers */
189 p = cd->stackframesize;
190 if (!jd->isleafmethod) {
191 p--; M_AST(REG_RA, REG_SP, p * 8);
193 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
194 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
196 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
197 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
200 /* take arguments out of register or stack frame */
204 for (p = 0, l = 0; p < md->paramcount; p++) {
205 t = md->paramtypes[p].type;
207 varindex = jd->local_map[l * 5 + t];
210 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
213 if (varindex == UNUSED)
217 s1 = md->params[p].regoff;
219 if (IS_INT_LNG_TYPE(t)) { /* integer args */
220 if (!md->params[p].inmemory) { /* register arguments */
221 #if SIZEOF_VOID_P == 8
222 if (!(var->flags & INMEMORY))
223 M_INTMOVE(s1, var->vv.regoff);
225 M_LST(s1, REG_SP, var->vv.regoff * 8);
227 if (!(var->flags & INMEMORY)) {
228 if (IS_2_WORD_TYPE(t))
229 M_LNGMOVE(s1, var->vv.regoff);
231 M_INTMOVE(s1, var->vv.regoff);
234 if (IS_2_WORD_TYPE(t))
235 M_LST(s1, REG_SP, var->vv.regoff * 8);
237 M_IST(s1, REG_SP, var->vv.regoff * 8);
241 else { /* stack arguments */
242 if (!(var->flags & INMEMORY)) {
243 #if SIZEOF_VOID_P == 8
244 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
246 if (IS_2_WORD_TYPE(t))
247 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
249 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
253 var->vv.regoff = cd->stackframesize + s1;
256 else { /* floating args */
257 if (!md->params[p].inmemory) {
258 if (!(var->flags & INMEMORY)) {
259 if (IS_2_WORD_TYPE(t))
260 M_DBLMOVE(s1, var->vv.regoff);
262 M_FLTMOVE(s1, var->vv.regoff);
265 if (IS_2_WORD_TYPE(t))
266 M_DST(s1, REG_SP, var->vv.regoff * 8);
268 M_FST(s1, REG_SP, var->vv.regoff * 8);
272 if (!(var->flags & INMEMORY)) {
273 if (IS_2_WORD_TYPE(t))
274 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
276 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
279 var->vv.regoff = cd->stackframesize + s1;
284 /* call monitorenter function */
286 #if defined(ENABLE_THREADS)
287 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
288 /* stack offset for monitor argument */
292 # if !defined(NDEBUG)
293 if (opt_verbosecall) {
294 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
296 for (p = 0; p < INT_ARG_CNT; p++)
297 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
299 for (p = 0; p < FLT_ARG_CNT; p++)
300 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
302 s1 += INT_ARG_CNT + FLT_ARG_CNT;
306 /* get correct lock object */
308 if (m->flags & ACC_STATIC) {
309 disp = dseg_add_address(cd, &m->class->object.header);
310 M_ALD(REG_A0, REG_PV, disp);
311 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
312 M_ALD(REG_ITMP3, REG_PV, disp);
315 /* emit_nullpointer_check(cd, iptr, REG_A0); */
317 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
318 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
319 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
322 M_JSR(REG_RA, REG_ITMP3);
323 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
325 # if !defined(NDEBUG)
326 if (opt_verbosecall) {
327 for (p = 0; p < INT_ARG_CNT; p++)
328 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
330 for (p = 0; p < FLT_ARG_CNT; p++)
331 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
334 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
342 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
343 emit_verbosecall_enter(jd);
346 /* end of header generation */
348 /* create replacement points */
350 REPLACEMENT_POINTS_INIT(cd, jd);
352 /* walk through all basic blocks */
354 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
356 /* handle replacement points */
358 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
360 /* store relative start of block */
362 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
364 if (bptr->flags >= BBREACHED) {
365 /* branch resolving */
367 codegen_resolve_branchrefs(cd, bptr);
369 /* copy interface registers to their destination */
373 #if defined(ENABLE_LSRA)
377 src = bptr->invars[len];
378 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
379 /* d = reg_of_var(m, src, REG_ITMP1); */
380 if (!(src->flags & INMEMORY))
384 M_INTMOVE(REG_ITMP1, d);
385 emit_store(jd, NULL, src, d);
392 var = VAR(bptr->invars[len]);
393 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
394 d = codegen_reg_of_var(0, var, REG_ITMP1);
395 M_INTMOVE(REG_ITMP1, d);
396 emit_store(jd, NULL, var, d);
399 assert((var->flags & INOUT));
402 #if defined(ENABLE_LSRA)
405 /* walk through all instructions */
408 /* currentline = 0; */
410 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
411 if (iptr->line != currentline) {
412 dseg_addlinenumber(cd, iptr->line);
413 currentline = iptr->line;
416 MCODECHECK(64); /* an instruction usually needs < 64 words */
420 case ICMD_NOP: /* ... ==> ... */
421 case ICMD_POP: /* ..., value ==> ... */
422 case ICMD_POP2: /* ..., value, value ==> ... */
425 case ICMD_INLINE_START:
427 REPLACEMENT_POINT_INLINE_START(cd, iptr);
430 case ICMD_INLINE_BODY:
432 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
433 dseg_addlinenumber_inline_start(cd, iptr);
434 dseg_addlinenumber(cd, iptr->line);
437 case ICMD_INLINE_END:
439 dseg_addlinenumber_inline_end(cd, iptr);
440 dseg_addlinenumber(cd, iptr->line);
443 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
446 emit_nullpointer_check(cd, iptr, s1);
449 /* constant operations ************************************************/
451 case ICMD_ICONST: /* ... ==> ..., constant */
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454 ICONST(d, iptr->sx.val.i);
455 emit_store_dst(jd, iptr, d);
458 case ICMD_LCONST: /* ... ==> ..., constant */
460 #if SIZEOF_VOID_P == 8
461 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
465 LCONST(d, iptr->sx.val.l);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_FCONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
472 disp = dseg_add_float(cd, iptr->sx.val.f);
473 M_FLD(d, REG_PV, disp);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_DCONST: /* ... ==> ..., constant */
479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
480 disp = dseg_add_double(cd, iptr->sx.val.d);
481 M_DLD(d, REG_PV, disp);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_ACONST: /* ... ==> ..., constant */
487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
489 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
490 cr = iptr->sx.val.c.ref;
491 disp = dseg_add_unique_address(cd, cr);
493 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
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_arrayheader, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, data[0]));
1967 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, 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, 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 codegen_add_patch_ref(cd, 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 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2001 M_ALD(REG_ITMP1, REG_PV, disp);
2003 switch (fieldtype) {
2005 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2006 M_ILD_INTERN(d, REG_ITMP1, 0);
2009 #if SIZEOF_VOID_P == 8
2010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2014 M_LLD_INTERN(d, REG_ITMP1, 0);
2017 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2018 M_ALD_INTERN(d, REG_ITMP1, 0);
2021 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2022 M_FLD_INTERN(d, REG_ITMP1, 0);
2025 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2026 M_DLD_INTERN(d, REG_ITMP1, 0);
2029 emit_store_dst(jd, iptr, d);
2032 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2034 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2035 uf = iptr->sx.s23.s3.uf;
2036 fieldtype = uf->fieldref->parseddesc.fd->type;
2037 disp = dseg_add_unique_address(cd, uf);
2039 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2042 fi = iptr->sx.s23.s3.fmiref->p.field;
2043 fieldtype = fi->type;
2044 disp = dseg_add_address(cd, &(fi->value));
2046 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2047 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2050 M_ALD(REG_ITMP1, REG_PV, disp);
2052 switch (fieldtype) {
2054 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2055 M_IST_INTERN(s1, REG_ITMP1, 0);
2058 #if SIZEOF_VOID_P == 8
2059 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2061 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2063 M_LST_INTERN(s1, REG_ITMP1, 0);
2066 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2067 M_AST_INTERN(s1, REG_ITMP1, 0);
2070 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2071 M_FST_INTERN(s1, REG_ITMP1, 0);
2074 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2075 M_DST_INTERN(s1, REG_ITMP1, 0);
2080 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2081 /* val = value (in current instruction) */
2082 /* following NOP) */
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 codegen_add_patch_ref(cd, 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 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2100 M_ALD(REG_ITMP1, REG_PV, disp);
2102 switch (fieldtype) {
2104 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2107 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2110 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2113 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2116 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2122 case ICMD_GETFIELD: /* ... ==> ..., value */
2124 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2125 emit_nullpointer_check(cd, iptr, s1);
2127 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2128 uf = iptr->sx.s23.s3.uf;
2129 fieldtype = uf->fieldref->parseddesc.fd->type;
2132 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2135 fi = iptr->sx.s23.s3.fmiref->p.field;
2136 fieldtype = fi->type;
2140 switch (fieldtype) {
2142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2146 #if SIZEOF_VOID_P == 8
2147 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2151 M_LLD_GETFIELD(d, s1, disp);
2155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2159 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2163 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2167 emit_store_dst(jd, iptr, d);
2170 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2173 emit_nullpointer_check(cd, iptr, s1);
2175 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2176 uf = iptr->sx.s23.s3.uf;
2177 fieldtype = uf->fieldref->parseddesc.fd->type;
2181 fi = iptr->sx.s23.s3.fmiref->p.field;
2182 fieldtype = fi->type;
2186 #if SIZEOF_VOID_P == 8
2187 if (IS_INT_LNG_TYPE(fieldtype))
2188 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2190 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2192 if (IS_INT_LNG_TYPE(fieldtype)) {
2193 if (IS_2_WORD_TYPE(fieldtype))
2194 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2196 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2199 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2202 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2203 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2205 switch (fieldtype) {
2207 M_IST(s2, s1, disp);
2210 M_LST(s2, s1, disp);
2213 M_AST(s2, s1, disp);
2216 M_FST(s2, s1, disp);
2219 M_DST(s2, s1, disp);
2224 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2226 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2227 emit_nullpointer_check(cd, iptr, s1);
2229 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2230 unresolved_field *uf = iptr->sx.s23.s3.uf;
2232 fieldtype = uf->fieldref->parseddesc.fd->type;
2235 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2238 fieldinfo *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 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, 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 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, 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 * 8);
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 * 8);
3076 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3077 M_IST(s1, REG_SP, d * 8);
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 * 8);
3095 M_FST(s1, REG_SP, d * 8);
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 codegen_add_patch_ref(cd, 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 codegen_add_patch_ref(cd, 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_objectheader, 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 codegen_add_patch_ref(cd, 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_objectheader, 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 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_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 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3279 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3282 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, 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 codegen_add_patch_ref(cd,
3309 PATCHER_checkcast_instanceof_class,
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_objectheader, 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 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3366 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3368 M_ALD(REG_A1, REG_PV, disp);
3369 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3370 M_ALD(REG_ITMP3, REG_PV, disp);
3371 M_JSR(REG_RA, REG_ITMP3);
3374 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3375 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3377 d = codegen_reg_of_dst(jd, iptr, s1);
3381 emit_store_dst(jd, iptr, d);
3384 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3390 super = iptr->sx.s23.s3.c.cls;
3392 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3397 super = iptr->sx.s23.s3.c.cls;
3398 superindex = super->index;
3401 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3402 CODEGEN_CRITICAL_SECTION_NEW;
3404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3408 M_MOV(s1, REG_ITMP1);
3414 /* if class is not resolved, check which code to call */
3416 if (super == NULL) {
3417 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3419 cr = iptr->sx.s23.s3.c.ref;
3420 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3422 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3425 M_ILD(REG_ITMP3, REG_PV, disp);
3426 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3427 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3430 /* interface instanceof code */
3432 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3433 if (super == NULL) {
3434 cr = iptr->sx.s23.s3.c.ref;
3436 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3440 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3443 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3444 M_ILD(REG_ITMP3, REG_ITMP1,
3445 OFFSET(vftbl_t, interfacetablelength));
3446 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3447 M_BLEZ(REG_ITMP3, 3);
3449 M_ALD(REG_ITMP1, REG_ITMP1,
3450 OFFSET(vftbl_t, interfacetable[0]) -
3451 superindex * sizeof(methodptr*));
3452 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3455 emit_label_br(cd, BRANCH_LABEL_4);
3457 emit_label(cd, BRANCH_LABEL_3);
3460 /* class instanceof code */
3462 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3463 if (super == NULL) {
3464 emit_label(cd, BRANCH_LABEL_2);
3466 cr = iptr->sx.s23.s3.c.ref;
3467 disp = dseg_add_unique_address(cd, NULL);
3469 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3473 disp = dseg_add_address(cd, super->vftbl);
3475 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3478 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3479 M_ALD(REG_ITMP2, REG_PV, disp);
3481 CODEGEN_CRITICAL_SECTION_START;
3483 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3484 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3485 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3487 CODEGEN_CRITICAL_SECTION_END;
3489 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3490 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3494 emit_label(cd, BRANCH_LABEL_5);
3497 if (super == NULL) {
3498 emit_label(cd, BRANCH_LABEL_1);
3499 emit_label(cd, BRANCH_LABEL_4);
3502 emit_store_dst(jd, iptr, d);
3506 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3508 /* check for negative sizes and copy sizes to stack if necessary */
3510 MCODECHECK((iptr->s1.argcount << 1) + 64);
3512 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3514 var = VAR(iptr->sx.s23.s2.args[s1]);
3516 /* copy SAVEDVAR sizes to stack */
3518 if (!(var->flags & PREALLOC)) {
3519 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3520 #if SIZEOF_VOID_P == 8
3521 M_LST(s2, REG_SP, s1 * 8);
3523 M_IST(s2, REG_SP, (s1 + 2) * 8);
3528 /* a0 = dimension count */
3530 ICONST(REG_A0, iptr->s1.argcount);
3532 /* is patcher function set? */
3534 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3535 cr = iptr->sx.s23.s3.c.ref;
3536 disp = dseg_add_unique_address(cd, NULL);
3538 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3542 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3544 /* a1 = arraydescriptor */
3546 M_ALD(REG_A1, REG_PV, disp);
3548 /* a2 = pointer to dimensions = stack pointer */
3550 #if SIZEOF_VOID_P == 8
3551 M_MOV(REG_SP, REG_A2);
3553 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3556 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3557 M_ALD(REG_ITMP3, REG_PV, disp);
3558 M_JSR(REG_RA, REG_ITMP3);
3561 /* check for exception before result assignment */
3563 emit_exception_check(cd, iptr);
3565 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3566 M_INTMOVE(REG_RESULT, d);
3567 emit_store_dst(jd, iptr, d);
3571 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3576 } /* for instruction */
3578 MCODECHECK(64); /* XXX require smaller number? */
3580 /* At the end of a basic block we may have to append some nops,
3581 because the patcher stub calling code might be longer than the
3582 actual instruction. So codepatching does not change the
3583 following block unintentionally. */
3585 if (cd->mcodeptr < cd->lastmcodeptr) {
3586 while (cd->mcodeptr < cd->lastmcodeptr)
3590 } /* if (bptr -> flags >= BBREACHED) */
3591 } /* for basic block */
3593 dseg_createlinenumbertable(cd);
3595 /* generate stubs */
3597 emit_patcher_stubs(jd);
3598 REPLACEMENT_EMIT_STUBS(jd);
3600 /* everything's ok */
3606 /* codegen_emit_stub_compiler **************************************************
3608 Emits a stub routine which calls the compiler.
3610 *******************************************************************************/
3612 void codegen_emit_stub_compiler(jitdata *jd)
3617 /* get required compiler data */
3622 /* code for the stub */
3624 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3625 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3631 /* codegen_emit_stub_native ****************************************************
3633 Emits a stub routine which calls a native method.
3635 *******************************************************************************/
3637 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3647 s4 funcdisp; /* displacement of the function */
3649 /* get required compiler data */
3655 /* initialize variables */
3658 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3660 /* calculate stack frame size */
3662 cd->stackframesize =
3663 1 + /* return address */
3664 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3665 sizeof(localref_table) / SIZEOF_VOID_P +
3666 md->paramcount + /* for saving arguments over calls */
3667 #if SIZEOF_VOID_P == 4
3668 5 + /* additional save space (MIPS32) */
3670 1 + /* for saving return address */
3673 /* adjust stackframe size for 16-byte alignment */
3675 if (cd->stackframesize & 1)
3676 cd->stackframesize++;
3678 /* create method header */
3680 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3681 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3682 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3683 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3684 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3685 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3686 (void) dseg_addlinenumbertablesize(cd);
3687 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3689 /* generate stub code */
3691 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3692 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3694 #if !defined(NDEBUG)
3695 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3696 emit_verbosecall_enter(jd);
3699 /* get function address (this must happen before the stackframeinfo) */
3701 funcdisp = dseg_add_functionptr(cd, f);
3703 #if !defined(WITH_STATIC_CLASSPATH)
3705 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3708 /* save integer and float argument registers */
3710 #if SIZEOF_VOID_P == 8
3711 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3712 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3713 s1 = md->params[i].regoff;
3714 M_AST(s1, REG_SP, j * 8);
3719 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3720 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3721 if (!md->params[i].inmemory) {
3722 s1 = md->params[i].regoff;
3724 if (IS_2_WORD_TYPE(md->params[i].type))
3725 M_LST(s1, REG_SP, j * 8);
3727 M_IST(s1, REG_SP, j * 8);
3735 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3736 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3737 s1 = md->params[i].regoff;
3739 if (IS_2_WORD_TYPE(md->params[i].type))
3740 M_DST(s1, REG_SP, j * 8);
3742 M_FST(s1, REG_SP, j * 8);
3748 /* prepare data structures for native function call */
3750 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3751 M_MOV(REG_PV, REG_A1);
3752 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3753 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3754 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3755 M_ALD(REG_ITMP3, REG_PV, disp);
3756 M_JSR(REG_RA, REG_ITMP3);
3757 M_NOP; /* XXX fill me! */
3759 /* restore integer and float argument registers */
3761 #if SIZEOF_VOID_P == 8
3762 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3763 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3764 s1 = md->params[i].regoff;
3765 M_LLD(s1, REG_SP, j * 8);
3770 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3771 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3772 if (!md->params[i].inmemory) {
3773 s1 = md->params[i].regoff;
3775 if (IS_2_WORD_TYPE(md->params[i].type))
3776 M_LLD(s1, REG_SP, j * 8);
3778 M_ILD(s1, REG_SP, j * 8);
3786 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3787 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3788 s1 = md->params[i].regoff;
3790 if (IS_2_WORD_TYPE(md->params[i].type))
3791 M_DLD(s1, REG_SP, j * 8);
3793 M_FLD(s1, REG_SP, j * 8);
3799 /* copy or spill arguments to new locations */
3801 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3802 t = md->params[i].type;
3804 if (IS_INT_LNG_TYPE(t)) {
3805 if (!md->params[i].inmemory) {
3806 s1 = md->params[i].regoff;
3807 s2 = nmd->params[j].regoff;
3809 if (!nmd->params[j].inmemory) {
3810 #if SIZEOF_VOID_P == 8
3813 if (IS_2_WORD_TYPE(t))
3820 #if SIZEOF_VOID_P == 8
3821 M_LST(s1, REG_SP, s2 * 8);
3823 if (IS_2_WORD_TYPE(t))
3824 M_LST(s1, REG_SP, s2 * 4);
3826 M_IST(s1, REG_SP, s2 * 4);
3831 s1 = md->params[i].regoff + cd->stackframesize;
3832 s2 = nmd->params[j].regoff;
3834 #if SIZEOF_VOID_P == 8
3835 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3836 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3838 if (IS_2_WORD_TYPE(t)) {
3839 M_LLD(REG_ITMP12_PACKED, REG_SP, s1 * 8);
3840 M_LST(REG_ITMP12_PACKED, REG_SP, s2 * 4);
3843 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
3844 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3850 if (!md->params[i].inmemory) {
3851 s1 = md->params[i].regoff;
3852 s2 = nmd->params[j].regoff;
3854 if (!nmd->params[j].inmemory) {
3855 #if SIZEOF_VOID_P == 8
3856 if (IS_2_WORD_TYPE(t))
3861 /* On MIPS32 float arguments for native functions
3862 can never be in float argument registers, since
3863 the first argument is _always_ an integer
3864 argument (JNIEnv) */
3866 if (IS_2_WORD_TYPE(t)) {
3867 /* double high/low order is endian
3868 independent: even numbered holds low
3869 32-bits, odd numbered high 32-bits */
3871 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3872 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3879 #if SIZEOF_VOID_P == 8
3880 if (IS_2_WORD_TYPE(t))
3881 M_DST(s1, REG_SP, s2 * 8);
3883 M_FST(s1, REG_SP, s2 * 8);
3885 /* s1 may have been originally in 2 int registers,
3886 but was moved out by the native function
3887 argument(s), just get low register */
3889 if (IS_2_WORD_TYPE(t))
3890 M_DST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3892 M_FST(GET_LOW_REG(s1), REG_SP, s2 * 4);
3897 s1 = md->params[i].regoff + cd->stackframesize;
3898 s2 = nmd->params[j].regoff;
3900 #if SIZEOF_VOID_P == 8
3901 if (IS_2_WORD_TYPE(t)) {
3902 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3903 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3906 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3907 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3910 if (IS_2_WORD_TYPE(t)) {
3911 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3912 M_DST(REG_FTMP1, REG_SP, s2 * 4);
3915 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3916 M_FST(REG_FTMP1, REG_SP, s2 * 4);
3923 /* put class into second argument register */
3925 if (m->flags & ACC_STATIC) {
3926 disp = dseg_add_address(cd, m->class);
3927 M_ALD(REG_A1, REG_PV, disp);
3930 /* put env into first argument register */
3932 disp = dseg_add_address(cd, _Jv_env);
3933 M_ALD(REG_A0, REG_PV, disp);
3935 /* do the native function call */
3937 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3938 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3939 M_NOP; /* delay slot */
3941 /* save return value */
3943 switch (md->returntype.type) {
3944 #if SIZEOF_VOID_P == 8
3948 M_LST(REG_RESULT, REG_SP, 0 * 8);
3952 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3957 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
3960 M_LST(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
3964 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
3971 #if !defined(NDEBUG)
3972 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3973 emit_verbosecall_exit(jd);
3976 /* remove native stackframe info */
3978 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3979 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3980 M_ALD(REG_ITMP3, REG_PV, disp);
3981 M_JSR(REG_RA, REG_ITMP3);
3982 M_NOP; /* XXX fill me! */
3983 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3985 /* restore return value */
3987 switch (md->returntype.type) {
3988 #if SIZEOF_VOID_P == 8
3992 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3996 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4001 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4004 M_LLD(REG_RESULT_PACKED, REG_SP, 1*4 + 0 * 8);
4008 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4015 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4017 /* check for exception */
4019 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4020 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4022 M_RET(REG_RA); /* return to caller */
4023 M_NOP; /* DELAY SLOT */
4025 /* handle exception */
4027 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4028 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4029 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4030 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4032 /* generate patcher stubs */
4034 emit_patcher_stubs(jd);
4039 * These are local overrides for various environment variables in Emacs.
4040 * Please do not remove this and leave it at the end of the file, where
4041 * Emacs will automagically detect them.
4042 * ---------------------------------------------------------------------
4045 * indent-tabs-mode: t
4049 * vim:noexpandtab:sw=4:ts=4: