1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "vm/jit/mips/arch.h"
36 #include "vm/jit/mips/codegen.h"
38 #include "mm/memory.h"
40 #include "native/localref.h"
41 #include "native/native.h"
43 #include "threads/lock-common.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
49 #include "vm/jit/abi.h"
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/dseg.h"
53 #include "vm/jit/emit-common.h"
54 #include "vm/jit/jit.h"
55 #include "vm/jit/linenumbertable.h"
56 #include "vm/jit/patcher-common.h"
57 #include "vm/jit/reg.h"
58 #include "vm/jit/replace.h"
59 #include "vm/jit/trap.h"
61 #if defined(ENABLE_LSRA)
62 # include "vm/jit/allocator/lsra.h"
65 #include "vmcore/class.h"
66 #include "vmcore/options.h"
69 /* codegen_emit ****************************************************************
71 Generates machine code.
73 *******************************************************************************/
75 bool codegen_emit(jitdata *jd)
81 s4 len, s1, s2, s3, d, disp;
86 constant_classref *cr;
88 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
89 unresolved_method *um;
90 builtintable_entry *bte;
97 /* get required compiler data */
104 /* prevent compiler warnings */
119 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
121 /* space to save used callee saved registers */
123 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
124 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
126 cd->stackframesize = rd->memuse + savedregs_num;
128 #if defined(ENABLE_THREADS)
129 /* space to save argument of monitor_enter */
131 if (checksync && code_is_synchronized(code)) {
132 # if SIZEOF_VOID_P == 8
133 cd->stackframesize++;
136 cd->stackframesize += 2;
141 /* keep stack 16-byte aligned */
143 if (cd->stackframesize & 1)
144 cd->stackframesize++;
146 /* create method header */
148 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
149 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
151 code->synchronizedoffset = rd->memuse * 8;
153 /* REMOVEME: We still need it for exception handling in assembler. */
155 if (code_is_leafmethod(code))
156 (void) dseg_add_unique_s4(cd, 1);
158 (void) dseg_add_unique_s4(cd, 0);
160 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
161 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
163 /* create stack frame (if necessary) */
165 if (cd->stackframesize)
166 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
168 /* save return address and used callee saved registers */
170 p = cd->stackframesize;
171 if (!code_is_leafmethod(code)) {
172 p--; M_AST(REG_RA, REG_SP, p * 8);
174 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
175 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
177 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
178 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
181 /* take arguments out of register or stack frame */
185 for (p = 0, l = 0; p < md->paramcount; p++) {
186 t = md->paramtypes[p].type;
188 varindex = jd->local_map[l * 5 + t];
191 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
194 if (varindex == UNUSED)
198 s1 = md->params[p].regoff;
200 if (IS_INT_LNG_TYPE(t)) { /* integer args */
201 if (!md->params[p].inmemory) { /* register arguments */
202 #if SIZEOF_VOID_P == 8
203 if (!(var->flags & INMEMORY))
204 M_INTMOVE(s1, var->vv.regoff);
206 M_LST(s1, REG_SP, var->vv.regoff);
208 if (!(var->flags & INMEMORY)) {
209 if (IS_2_WORD_TYPE(t))
210 M_LNGMOVE(s1, var->vv.regoff);
212 M_INTMOVE(s1, var->vv.regoff);
215 if (IS_2_WORD_TYPE(t))
216 M_LST(s1, REG_SP, var->vv.regoff);
218 M_IST(s1, REG_SP, var->vv.regoff);
222 else { /* stack arguments */
223 if (!(var->flags & INMEMORY)) {
224 #if SIZEOF_VOID_P == 8
225 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
227 if (IS_2_WORD_TYPE(t))
228 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
230 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
234 var->vv.regoff = cd->stackframesize * 8 + s1;
237 else { /* floating args */
238 if (!md->params[p].inmemory) {
239 if (!(var->flags & INMEMORY)) {
240 if (IS_2_WORD_TYPE(t))
241 M_DBLMOVE(s1, var->vv.regoff);
243 M_FLTMOVE(s1, var->vv.regoff);
246 if (IS_2_WORD_TYPE(t))
247 M_DST(s1, REG_SP, var->vv.regoff);
249 M_FST(s1, REG_SP, var->vv.regoff);
253 if (!(var->flags & INMEMORY)) {
254 if (IS_2_WORD_TYPE(t))
255 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
257 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
260 var->vv.regoff = cd->stackframesize * 8 + s1;
265 /* call monitorenter function */
267 #if defined(ENABLE_THREADS)
268 if (checksync && code_is_synchronized(code)) {
269 /* stack offset for monitor argument */
273 # if !defined(NDEBUG)
274 if (opt_verbosecall) {
275 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
277 for (p = 0; p < INT_ARG_CNT; p++)
278 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
280 for (p = 0; p < FLT_ARG_CNT; p++)
281 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
283 s1 += INT_ARG_CNT + FLT_ARG_CNT;
287 /* get correct lock object */
289 if (m->flags & ACC_STATIC) {
290 disp = dseg_add_address(cd, &m->clazz->object.header);
291 M_ALD(REG_A0, REG_PV, disp);
292 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
293 M_ALD(REG_ITMP3, REG_PV, disp);
296 /* emit_nullpointer_check(cd, iptr, REG_A0); */
298 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
299 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
300 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
303 M_JSR(REG_RA, REG_ITMP3);
304 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
306 # if !defined(NDEBUG)
307 if (opt_verbosecall) {
308 for (p = 0; p < INT_ARG_CNT; p++)
309 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
311 for (p = 0; p < FLT_ARG_CNT; p++)
312 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
315 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
323 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
324 emit_verbosecall_enter(jd);
327 /* end of header generation */
329 /* create replacement points */
331 REPLACEMENT_POINTS_INIT(cd, jd);
333 /* walk through all basic blocks */
335 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
337 /* handle replacement points */
339 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
341 /* store relative start of block */
343 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
345 if (bptr->flags >= BBREACHED) {
346 /* branch resolving */
348 codegen_resolve_branchrefs(cd, bptr);
350 /* copy interface registers to their destination */
354 #if defined(ENABLE_LSRA)
358 src = bptr->invars[len];
359 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
360 /* d = reg_of_var(m, src, REG_ITMP1); */
361 if (!(src->flags & INMEMORY))
365 M_INTMOVE(REG_ITMP1, d);
366 emit_store(jd, NULL, src, d);
373 var = VAR(bptr->invars[len]);
374 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
375 d = codegen_reg_of_var(0, var, REG_ITMP1);
376 M_INTMOVE(REG_ITMP1, d);
377 emit_store(jd, NULL, var, d);
380 assert((var->flags & INOUT));
383 #if defined(ENABLE_LSRA)
386 /* walk through all instructions */
389 /* currentline = 0; */
391 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
392 if (iptr->line != currentline) {
393 linenumbertable_list_entry_add(cd, iptr->line);
394 currentline = iptr->line;
397 MCODECHECK(64); /* an instruction usually needs < 64 words */
401 case ICMD_NOP: /* ... ==> ... */
402 case ICMD_POP: /* ..., value ==> ... */
403 case ICMD_POP2: /* ..., value, value ==> ... */
406 case ICMD_INLINE_START:
408 REPLACEMENT_POINT_INLINE_START(cd, iptr);
411 case ICMD_INLINE_BODY:
413 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
414 linenumbertable_list_entry_add_inline_start(cd, iptr);
415 linenumbertable_list_entry_add(cd, iptr->line);
418 case ICMD_INLINE_END:
420 linenumbertable_list_entry_add_inline_end(cd, iptr);
421 linenumbertable_list_entry_add(cd, iptr->line);
424 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
427 emit_nullpointer_check(cd, iptr, s1);
430 /* constant operations ************************************************/
432 case ICMD_ICONST: /* ... ==> ..., constant */
434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
435 ICONST(d, iptr->sx.val.i);
436 emit_store_dst(jd, iptr, d);
439 case ICMD_LCONST: /* ... ==> ..., constant */
441 #if SIZEOF_VOID_P == 8
442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
446 LCONST(d, iptr->sx.val.l);
447 emit_store_dst(jd, iptr, d);
450 case ICMD_FCONST: /* ... ==> ..., constant */
452 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
453 disp = dseg_add_float(cd, iptr->sx.val.f);
454 M_FLD(d, REG_PV, disp);
455 emit_store_dst(jd, iptr, d);
458 case ICMD_DCONST: /* ... ==> ..., constant */
460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
461 disp = dseg_add_double(cd, iptr->sx.val.d);
462 M_DLD(d, REG_PV, disp);
463 emit_store_dst(jd, iptr, d);
466 case ICMD_ACONST: /* ... ==> ..., constant */
468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
470 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
471 cr = iptr->sx.val.c.ref;
472 disp = dseg_add_unique_address(cd, cr);
474 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
477 M_ALD(d, REG_PV, disp);
480 if (iptr->sx.val.anyptr == NULL)
481 M_INTMOVE(REG_ZERO, d);
483 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
484 M_ALD(d, REG_PV, disp);
487 emit_store_dst(jd, iptr, d);
491 /* load/store/copy/move operations ************************************/
493 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
498 case ICMD_ISTORE: /* ..., value ==> ... */
509 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
514 /* integer operations *************************************************/
516 case ICMD_INEG: /* ..., value ==> ..., - value */
518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
520 M_ISUB(REG_ZERO, s1, d);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_LNEG: /* ..., value ==> ..., - value */
526 #if SIZEOF_VOID_P == 8
527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
528 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
529 M_LSUB(REG_ZERO, s1, d);
531 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
533 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
534 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
535 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
536 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
538 emit_store_dst(jd, iptr, d);
541 case ICMD_I2L: /* ..., value ==> ..., value */
543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544 #if SIZEOF_VOID_P == 8
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
549 M_INTMOVE(s1, GET_LOW_REG(d));
550 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
552 emit_store_dst(jd, iptr, d);
555 case ICMD_L2I: /* ..., value ==> ..., value */
557 #if SIZEOF_VOID_P == 8
558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
560 M_ISLL_IMM(s1, 0, d);
562 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 M_INTMOVE(GET_LOW_REG(s1), d);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 #if SIZEOF_VOID_P == 8
574 M_LSLL_IMM(s1, 56, d);
575 M_LSRA_IMM( d, 56, d);
577 M_ISLL_IMM(s1, 24, d);
578 M_ISRA_IMM( d, 24, d);
580 emit_store_dst(jd, iptr, d);
583 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 M_AND_IMM(s1, 0xffff, d);
588 emit_store_dst(jd, iptr, d);
591 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
595 #if SIZEOF_VOID_P == 8
596 M_LSLL_IMM(s1, 48, d);
597 M_LSRA_IMM( d, 48, d);
599 M_ISLL_IMM(s1, 16, d);
600 M_ISRA_IMM( d, 16, d);
602 emit_store_dst(jd, iptr, d);
606 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
612 emit_store_dst(jd, iptr, d);
616 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
617 /* sx.val.i = constant */
619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
621 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
622 M_IADD_IMM(s1, iptr->sx.val.i, d);
624 ICONST(REG_ITMP2, iptr->sx.val.i);
625 M_IADD(s1, REG_ITMP2, d);
627 emit_store_dst(jd, iptr, d);
630 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
632 #if SIZEOF_VOID_P == 8
633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
634 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
639 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
641 M_IADD(s1, s2, GET_HIGH_REG(d));
642 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
643 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
644 if (s1 == GET_LOW_REG(d)) {
645 M_MOV(s1, REG_ITMP3);
648 M_IADD(s1, s2, GET_LOW_REG(d));
649 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
650 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
652 emit_store_dst(jd, iptr, d);
655 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
656 /* sx.val.l = constant */
658 #if SIZEOF_VOID_P == 8
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
662 M_LADD_IMM(s1, iptr->sx.val.l, d);
664 LCONST(REG_ITMP2, iptr->sx.val.l);
665 M_LADD(s1, REG_ITMP2, d);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
669 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
670 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
671 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
672 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
673 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
675 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
676 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
677 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
678 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
679 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
680 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
681 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
684 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
685 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
686 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
687 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
688 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
689 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
690 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
691 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
694 emit_store_dst(jd, iptr, d);
697 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
703 emit_store_dst(jd, iptr, d);
706 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
707 /* sx.val.i = constant */
709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
711 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
712 M_IADD_IMM(s1, -iptr->sx.val.i, d);
714 ICONST(REG_ITMP2, iptr->sx.val.i);
715 M_ISUB(s1, REG_ITMP2, d);
717 emit_store_dst(jd, iptr, d);
720 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
722 #if SIZEOF_VOID_P == 8
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
728 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
729 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
731 M_ISUB(s1, s2, GET_HIGH_REG(d));
732 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
733 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
734 M_CMPULT(s1, s2, REG_ITMP3);
735 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
736 /* if s1 is equal to REG_ITMP3 we have to reload it, since
737 the CMPULT instruction destroyed it */
739 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
740 M_ISUB(s1, s2, GET_LOW_REG(d));
743 emit_store_dst(jd, iptr, d);
746 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
747 /* sx.val.l = constant */
749 #if SIZEOF_VOID_P == 8
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
753 M_LADD_IMM(s1, -iptr->sx.val.l, d);
755 LCONST(REG_ITMP2, iptr->sx.val.l);
756 M_LSUB(s1, REG_ITMP2, d);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
760 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
761 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
762 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
763 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
764 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
765 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
766 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
768 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
769 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
770 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
771 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
772 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
775 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
776 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
777 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
778 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
779 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
780 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
781 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
782 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
785 emit_store_dst(jd, iptr, d);
788 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
797 emit_store_dst(jd, iptr, d);
800 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
801 /* sx.val.i = constant */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805 ICONST(REG_ITMP2, iptr->sx.val.i);
806 M_IMUL(s1, REG_ITMP2);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
815 #if SIZEOF_VOID_P == 8
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
825 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
831 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
833 M_MFHI(GET_HIGH_REG(d));
834 M_MFLO(GET_LOW_REG(d));
837 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
839 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
840 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
843 /* XXX do we need nops here? */
845 emit_store_dst(jd, iptr, d);
848 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
849 /* sx.val.l = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 LCONST(REG_ITMP2, iptr->sx.val.l);
854 M_LMUL(s1, REG_ITMP2);
858 emit_store_dst(jd, iptr, d);
861 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
864 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 emit_arithmetic_check(cd, iptr, s2);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 emit_arithmetic_check(cd, iptr, s2);
884 emit_store_dst(jd, iptr, d);
887 #if SIZEOF_VOID_P == 8
889 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
892 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
893 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
894 emit_arithmetic_check(cd, iptr, s2);
899 emit_store_dst(jd, iptr, d);
902 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
906 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 emit_arithmetic_check(cd, iptr, s2);
912 emit_store_dst(jd, iptr, d);
915 #else /* SIZEOF_VOID_P == 8 */
917 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
918 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
920 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
921 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
923 /* XXX TODO: only do this if arithmetic check is really done! */
924 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
925 emit_arithmetic_check(cd, iptr, REG_ITMP3);
927 M_LNGMOVE(s1, REG_A0_A1_PACKED);
928 M_LNGMOVE(s2, REG_A2_A3_PACKED);
930 bte = iptr->sx.s23.s3.bte;
931 disp = dseg_add_functionptr(cd, bte->fp);
932 M_ALD(REG_ITMP3, REG_PV, disp);
933 M_JSR(REG_RA, REG_ITMP3);
936 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
937 M_LNGMOVE(REG_RESULT_PACKED, d);
938 emit_store_dst(jd, iptr, d);
941 #endif /* SIZEOF_VOID_P == 8 */
943 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
944 /* val.i = constant */
946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
947 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
948 #if SIZEOF_VOID_P == 8
949 M_LSRA_IMM(s1, 63, REG_ITMP2);
950 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
951 M_LADD(s1, REG_ITMP2, REG_ITMP2);
952 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
954 M_ISRA_IMM(s1, 31, REG_ITMP2);
955 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
956 M_IADD(s1, REG_ITMP2, REG_ITMP2);
957 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
959 emit_store_dst(jd, iptr, d);
962 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
963 /* val.i = constant */
965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
966 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
968 M_MOV(s1, REG_ITMP1);
971 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
972 M_AND_IMM(s1, iptr->sx.val.i, d);
975 M_ISUB(REG_ZERO, s1, d);
976 M_AND_IMM(d, iptr->sx.val.i, d);
979 ICONST(REG_ITMP2, iptr->sx.val.i);
980 M_AND(s1, REG_ITMP2, d);
983 M_ISUB(REG_ZERO, s1, d);
984 M_AND(d, REG_ITMP2, d);
986 M_ISUB(REG_ZERO, d, d);
987 emit_store_dst(jd, iptr, d);
990 #if SIZEOF_VOID_P == 8
992 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
993 /* val.i = constant */
995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
996 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
997 M_LSRA_IMM(s1, 63, REG_ITMP2);
998 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
999 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1000 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1001 emit_store_dst(jd, iptr, d);
1004 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1005 /* val.l = constant */
1007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1008 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1010 M_MOV(s1, REG_ITMP1);
1013 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1014 M_AND_IMM(s1, iptr->sx.val.l, d);
1017 M_LSUB(REG_ZERO, s1, d);
1018 M_AND_IMM(d, iptr->sx.val.l, d);
1021 LCONST(REG_ITMP2, iptr->sx.val.l);
1022 M_AND(s1, REG_ITMP2, d);
1025 M_LSUB(REG_ZERO, s1, d);
1026 M_AND(d, REG_ITMP2, d);
1028 M_LSUB(REG_ZERO, d, d);
1029 emit_store_dst(jd, iptr, d);
1032 #endif /* SIZEOF_VOID_P == 8 */
1034 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1036 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1037 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1038 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1044 /* sx.val.i = constant */
1046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1048 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1049 emit_store_dst(jd, iptr, d);
1052 case ICMD_ISHR: /* ..., 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_ISHRCONST: /* ..., 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_ISRA_IMM(s1, iptr->sx.val.i, d);
1067 emit_store_dst(jd, iptr, d);
1070 case ICMD_IUSHR: /* ..., 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_IUSHRCONST: /* ..., 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_ISRL_IMM(s1, iptr->sx.val.i, d);
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1090 #if SIZEOF_VOID_P == 8
1091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1097 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1098 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1100 M_ISLL(s2, 26, REG_ITMP1);
1101 M_BGEZ(REG_ITMP1, 3);
1104 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1106 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1109 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1111 M_BEQZ(REG_ITMP1, 4);
1112 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1114 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1115 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1116 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1119 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1122 emit_store_dst(jd, iptr, d);
1125 #if SIZEOF_VOID_P == 8
1127 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1128 /* sx.val.i = constant */
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1132 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_LSHRCONST: /* ..., 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_LSRA_IMM(s1, iptr->sx.val.i, d);
1151 emit_store_dst(jd, iptr, d);
1154 case ICMD_LUSHR: /* ..., 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_LUSHRCONST: /* ..., 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_LSRL_IMM(s1, iptr->sx.val.i, d);
1169 emit_store_dst(jd, iptr, d);
1172 #endif /* SIZEOF_VOID_P == 8 */
1174 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1176 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1177 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1180 emit_store_dst(jd, iptr, d);
1183 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1184 /* sx.val.i = constant */
1186 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1188 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1189 M_AND_IMM(s1, iptr->sx.val.i, d);
1191 ICONST(REG_ITMP2, iptr->sx.val.i);
1192 M_AND(s1, REG_ITMP2, d);
1194 emit_store_dst(jd, iptr, d);
1197 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1199 #if SIZEOF_VOID_P == 8
1200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1202 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1205 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1206 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1207 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1208 M_AND(s1, s2, GET_LOW_REG(d));
1209 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1210 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1211 M_AND(s1, s2, GET_HIGH_REG(d));
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1217 /* sx.val.l = constant */
1219 #if SIZEOF_VOID_P == 8
1220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1221 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1222 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1223 M_AND_IMM(s1, iptr->sx.val.l, d);
1225 LCONST(REG_ITMP2, iptr->sx.val.l);
1226 M_AND(s1, REG_ITMP2, d);
1229 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1230 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1231 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1232 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1233 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1236 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1237 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1238 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1239 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1240 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1243 emit_store_dst(jd, iptr, d);
1246 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1249 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1250 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1252 emit_store_dst(jd, iptr, d);
1255 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1256 /* sx.val.i = constant */
1258 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1259 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1260 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1261 M_OR_IMM(s1, iptr->sx.val.i, d);
1263 ICONST(REG_ITMP2, iptr->sx.val.i);
1264 M_OR(s1, REG_ITMP2, d);
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1271 #if SIZEOF_VOID_P == 8
1272 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1273 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1274 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1277 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1278 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1279 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1280 M_OR(s1, s2, GET_LOW_REG(d));
1281 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1282 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1283 M_OR(s1, s2, GET_HIGH_REG(d));
1285 emit_store_dst(jd, iptr, d);
1288 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1289 /* sx.val.l = constant */
1291 #if SIZEOF_VOID_P == 8
1292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1294 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1295 M_OR_IMM(s1, iptr->sx.val.l, d);
1297 LCONST(REG_ITMP2, iptr->sx.val.l);
1298 M_OR(s1, REG_ITMP2, d);
1301 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1302 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1303 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1304 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1305 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1308 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1309 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1310 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1311 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1312 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1315 emit_store_dst(jd, iptr, d);
1318 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1321 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1322 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1328 /* sx.val.i = constant */
1330 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1332 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1333 M_XOR_IMM(s1, iptr->sx.val.i, d);
1335 ICONST(REG_ITMP2, iptr->sx.val.i);
1336 M_XOR(s1, REG_ITMP2, d);
1338 emit_store_dst(jd, iptr, d);
1341 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1343 #if SIZEOF_VOID_P == 8
1344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1345 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1349 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1350 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1351 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1352 M_XOR(s1, s2, GET_LOW_REG(d));
1353 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1354 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1355 M_XOR(s1, s2, GET_HIGH_REG(d));
1357 emit_store_dst(jd, iptr, d);
1360 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1361 /* sx.val.l = constant */
1363 #if SIZEOF_VOID_P == 8
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1366 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1367 M_XOR_IMM(s1, iptr->sx.val.l, d);
1369 LCONST(REG_ITMP2, iptr->sx.val.l);
1370 M_XOR(s1, REG_ITMP2, d);
1373 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1374 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1375 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1376 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1377 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1380 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1381 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1382 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1383 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1384 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1387 emit_store_dst(jd, iptr, d);
1391 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1393 #if SIZEOF_VOID_P == 8
1394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1395 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1396 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1397 M_CMPLT(s1, s2, REG_ITMP3);
1398 M_CMPLT(s2, s1, REG_ITMP1);
1399 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1401 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1402 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1404 M_CMPLT(s1, s2, REG_ITMP3);
1405 M_CMPLT(s2, s1, REG_ITMP1);
1406 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1409 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1410 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1411 M_CMPULT(s1, s2, REG_ITMP3);
1412 M_CMPULT(s2, s1, REG_ITMP1);
1413 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1415 emit_store_dst(jd, iptr, d);
1419 /* floating operations ************************************************/
1421 case ICMD_FNEG: /* ..., value ==> ..., - value */
1423 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1424 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_DNEG: /* ..., value ==> ..., - value */
1431 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1432 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1439 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1443 emit_store_dst(jd, iptr, d);
1446 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1448 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1449 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1450 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1452 emit_store_dst(jd, iptr, d);
1455 case ICMD_FSUB: /* ..., 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_DSUB: /* ..., 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_FMUL: /* ..., 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_DMUL: /* ..., 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_FDIV: /* ..., 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_DDIV: /* ..., 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);
1510 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1512 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1513 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1514 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1515 M_FDIV(s1,s2, REG_FTMP3);
1516 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1517 M_CVTLF(REG_FTMP3, REG_FTMP3);
1518 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1519 M_FSUB(s1, REG_FTMP3, d);
1520 emit_store_dst(jd, iptr, d);
1523 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1525 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1527 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1528 M_DDIV(s1,s2, REG_FTMP3);
1529 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1530 M_CVTLD(REG_FTMP3, REG_FTMP3);
1531 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1532 M_DSUB(s1, REG_FTMP3, d);
1533 emit_store_dst(jd, iptr, d);
1537 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1543 emit_store_dst(jd, iptr, d);
1546 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1552 emit_store_dst(jd, iptr, d);
1556 /* XXX these do not work correctly */
1558 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1560 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1562 M_TRUNCFI(s1, REG_FTMP1);
1563 M_MOVDI(REG_FTMP1, d);
1565 emit_store_dst(jd, iptr, d);
1568 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1570 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1572 M_TRUNCDI(s1, REG_FTMP1);
1573 M_MOVDI(REG_FTMP1, d);
1575 emit_store_dst(jd, iptr, d);
1578 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1580 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1582 M_TRUNCFL(s1, REG_FTMP1);
1583 M_MOVDL(REG_FTMP1, d);
1585 emit_store_dst(jd, iptr, d);
1588 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1590 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1592 M_TRUNCDL(s1, REG_FTMP1);
1593 M_MOVDL(REG_FTMP1, d);
1595 emit_store_dst(jd, iptr, d);
1599 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1601 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1602 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1604 emit_store_dst(jd, iptr, d);
1607 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1609 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1610 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1612 emit_store_dst(jd, iptr, d);
1615 #if SUPPORT_FLOAT_CMP
1616 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1618 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1619 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1623 M_AADD_IMM(REG_ZERO, 1, d);
1627 M_ASUB_IMM(REG_ZERO, 1, d);
1628 M_CMOVT(REG_ZERO, d);
1629 emit_store_dst(jd, iptr, d);
1632 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1634 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1635 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1639 M_ASUB_IMM(REG_ZERO, 1, d);
1643 M_AADD_IMM(REG_ZERO, 1, d);
1644 M_CMOVT(REG_ZERO, d);
1645 emit_store_dst(jd, iptr, d);
1649 #if SUPPORT_DOUBLE_CMP
1650 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl 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_AADD_IMM(REG_ZERO, 1, d);
1661 M_ASUB_IMM(REG_ZERO, 1, d);
1662 M_CMOVT(REG_ZERO, d);
1663 emit_store_dst(jd, iptr, d);
1666 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1668 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1669 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1673 M_ASUB_IMM(REG_ZERO, 1, d);
1677 M_AADD_IMM(REG_ZERO, 1, d);
1678 M_CMOVT(REG_ZERO, d);
1679 emit_store_dst(jd, iptr, d);
1684 /* memory operations **************************************************/
1686 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1689 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1690 /* implicit null-pointer check */
1691 M_ILD(d, s1, OFFSET(java_array_t, size));
1692 emit_store_dst(jd, iptr, d);
1695 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1700 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1701 M_AADD(s2, s1, REG_ITMP3);
1702 /* implicit null-pointer check */
1703 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1704 emit_store_dst(jd, iptr, d);
1707 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1712 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1713 M_AADD(s2, s1, REG_ITMP3);
1714 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1715 /* implicit null-pointer check */
1716 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1717 emit_store_dst(jd, iptr, d);
1720 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1725 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1726 M_AADD(s2, s1, REG_ITMP3);
1727 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1728 /* implicit null-pointer check */
1729 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1730 emit_store_dst(jd, iptr, d);
1733 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1736 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1737 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1738 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1739 M_ASLL_IMM(s2, 2, REG_ITMP3);
1740 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1741 /* implicit null-pointer check */
1742 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1743 emit_store_dst(jd, iptr, d);
1746 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1750 #if SIZEOF_VOID_P == 8
1751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1755 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1756 M_ASLL_IMM(s2, 3, REG_ITMP3);
1757 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1758 /* implicit null-pointer check */
1759 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1760 emit_store_dst(jd, iptr, d);
1763 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1767 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1768 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1769 M_ASLL_IMM(s2, 2, REG_ITMP3);
1770 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1771 /* implicit null-pointer check */
1772 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1773 emit_store_dst(jd, iptr, d);
1776 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1780 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1781 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1782 M_ASLL_IMM(s2, 3, REG_ITMP3);
1783 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1784 /* implicit null-pointer check */
1785 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1786 emit_store_dst(jd, iptr, d);
1789 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1792 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1794 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1795 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1796 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1797 /* implicit null-pointer check */
1798 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1799 emit_store_dst(jd, iptr, d);
1803 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1807 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1808 M_AADD(s2, s1, REG_ITMP1);
1809 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1810 /* implicit null-pointer check */
1811 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1814 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1815 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1818 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1819 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1820 M_AADD(s2, s1, REG_ITMP1);
1821 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1822 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1823 /* implicit null-pointer check */
1824 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1827 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1830 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1831 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1832 M_ASLL_IMM(s2, 2, REG_ITMP2);
1833 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1834 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1835 /* implicit null-pointer check */
1836 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1839 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1843 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1844 M_ASLL_IMM(s2, 3, REG_ITMP2);
1845 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1846 #if SIZEOF_VOID_P == 8
1847 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1849 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1851 /* implicit null-pointer check */
1852 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1855 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1858 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1859 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1860 M_ASLL_IMM(s2, 2, REG_ITMP2);
1861 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1862 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1863 /* implicit null-pointer check */
1864 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1867 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1870 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1871 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1872 M_ASLL_IMM(s2, 3, REG_ITMP2);
1873 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1874 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1875 /* implicit null-pointer check */
1876 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1880 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1883 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1884 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1885 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1887 M_INTMOVE(s1, REG_A0);
1888 M_INTMOVE(s3, REG_A1);
1889 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1890 M_ALD(REG_ITMP3, REG_PV, disp);
1891 M_JSR(REG_RA, REG_ITMP3);
1893 emit_arraystore_check(cd, iptr);
1895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1896 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1897 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1898 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1899 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1900 /* implicit null-pointer check */
1901 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1905 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1908 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1909 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1910 M_AADD(s2, s1, REG_ITMP1);
1911 /* implicit null-pointer check */
1912 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1915 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1916 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1920 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1921 M_AADD(s2, s1, REG_ITMP1);
1922 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1923 /* implicit null-pointer check */
1924 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1927 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1931 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1932 M_ASLL_IMM(s2, 2, REG_ITMP2);
1933 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1934 /* implicit null-pointer check */
1935 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1938 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1940 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1941 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1942 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1943 M_ASLL_IMM(s2, 3, REG_ITMP2);
1944 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1945 /* implicit null-pointer check */
1946 #if SIZEOF_VOID_P == 8
1947 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1949 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1953 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1955 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1956 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1957 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1958 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1959 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1960 /* implicit null-pointer check */
1961 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1965 case ICMD_GETSTATIC: /* ... ==> ..., value */
1967 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1968 uf = iptr->sx.s23.s3.uf;
1969 fieldtype = uf->fieldref->parseddesc.fd->type;
1970 disp = dseg_add_unique_address(cd, uf);
1972 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1975 fi = iptr->sx.s23.s3.fmiref->p.field;
1976 fieldtype = fi->type;
1977 disp = dseg_add_address(cd, fi->value);
1979 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1980 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1984 M_ALD(REG_ITMP1, REG_PV, disp);
1986 switch (fieldtype) {
1988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1989 M_ILD_INTERN(d, REG_ITMP1, 0);
1992 #if SIZEOF_VOID_P == 8
1993 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1997 M_LLD_INTERN(d, REG_ITMP1, 0);
2000 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2001 M_ALD_INTERN(d, REG_ITMP1, 0);
2004 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2005 M_FLD_INTERN(d, REG_ITMP1, 0);
2008 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2009 M_DLD_INTERN(d, REG_ITMP1, 0);
2012 emit_store_dst(jd, iptr, d);
2015 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2017 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2018 uf = iptr->sx.s23.s3.uf;
2019 fieldtype = uf->fieldref->parseddesc.fd->type;
2020 disp = dseg_add_unique_address(cd, uf);
2022 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2025 fi = iptr->sx.s23.s3.fmiref->p.field;
2026 fieldtype = fi->type;
2027 disp = dseg_add_address(cd, fi->value);
2029 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2030 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2034 M_ALD(REG_ITMP1, REG_PV, disp);
2036 switch (fieldtype) {
2038 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2039 M_IST_INTERN(s1, REG_ITMP1, 0);
2042 #if SIZEOF_VOID_P == 8
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2045 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2047 M_LST_INTERN(s1, REG_ITMP1, 0);
2050 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2051 M_AST_INTERN(s1, REG_ITMP1, 0);
2054 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2055 M_FST_INTERN(s1, REG_ITMP1, 0);
2058 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2059 M_DST_INTERN(s1, REG_ITMP1, 0);
2064 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2066 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2067 uf = iptr->sx.s23.s3.uf;
2068 fieldtype = uf->fieldref->parseddesc.fd->type;
2069 disp = dseg_add_unique_address(cd, uf);
2071 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2074 fi = iptr->sx.s23.s3.fmiref->p.field;
2075 fieldtype = fi->type;
2076 disp = dseg_add_address(cd, fi->value);
2078 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
2079 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2083 M_ALD(REG_ITMP1, REG_PV, disp);
2085 switch (fieldtype) {
2087 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2090 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2093 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2096 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2099 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2105 case ICMD_GETFIELD: /* ... ==> ..., value */
2107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2108 emit_nullpointer_check(cd, iptr, s1);
2110 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2111 uf = iptr->sx.s23.s3.uf;
2112 fieldtype = uf->fieldref->parseddesc.fd->type;
2115 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2118 fi = iptr->sx.s23.s3.fmiref->p.field;
2119 fieldtype = fi->type;
2123 switch (fieldtype) {
2125 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2129 #if SIZEOF_VOID_P == 8
2130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2134 M_LLD_GETFIELD(d, s1, disp);
2138 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2142 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2146 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2150 emit_store_dst(jd, iptr, d);
2153 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2156 emit_nullpointer_check(cd, iptr, s1);
2158 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2159 uf = iptr->sx.s23.s3.uf;
2160 fieldtype = uf->fieldref->parseddesc.fd->type;
2164 fi = iptr->sx.s23.s3.fmiref->p.field;
2165 fieldtype = fi->type;
2169 #if SIZEOF_VOID_P == 8
2170 if (IS_INT_LNG_TYPE(fieldtype))
2171 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2173 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2175 if (IS_INT_LNG_TYPE(fieldtype)) {
2176 if (IS_2_WORD_TYPE(fieldtype))
2177 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2179 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2182 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2185 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2186 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2188 switch (fieldtype) {
2190 M_IST(s2, s1, disp);
2193 M_LST(s2, s1, disp);
2196 M_AST(s2, s1, disp);
2199 M_FST(s2, s1, disp);
2202 M_DST(s2, s1, disp);
2207 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2210 emit_nullpointer_check(cd, iptr, s1);
2212 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2213 uf = iptr->sx.s23.s3.uf;
2214 fieldtype = uf->fieldref->parseddesc.fd->type;
2217 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2220 fi = iptr->sx.s23.s3.fmiref->p.field;
2221 fieldtype = fi->type;
2225 switch (fieldtype) {
2227 M_IST(REG_ZERO, s1, disp);
2230 M_LST(REG_ZERO, s1, disp);
2233 M_AST(REG_ZERO, s1, disp);
2236 M_FST(REG_ZERO, s1, disp);
2239 M_DST(REG_ZERO, s1, disp);
2245 /* branch operations **************************************************/
2247 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 M_INTMOVE(s1, REG_ITMP1_XPTR);
2252 #ifdef ENABLE_VERIFIER
2253 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2254 uc = iptr->sx.s23.s2.uc;
2256 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2258 #endif /* ENABLE_VERIFIER */
2260 disp = dseg_add_functionptr(cd, asm_handle_exception);
2261 M_ALD(REG_ITMP2, REG_PV, disp);
2262 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2264 M_NOP; /* nop ensures that XPC is less than the end */
2265 /* of basic block */
2269 case ICMD_GOTO: /* ... ==> ... */
2270 case ICMD_RET: /* ... ==> ... */
2272 emit_br(cd, iptr->dst.block);
2276 case ICMD_JSR: /* ... ==> ... */
2278 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2282 case ICMD_IFNULL: /* ..., value ==> ... */
2283 case ICMD_IFNONNULL:
2285 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2286 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2289 case ICMD_IFEQ: /* ..., value ==> ... */
2291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2292 if (iptr->sx.val.i == 0)
2293 emit_beqz(cd, iptr->dst.block, s1);
2295 ICONST(REG_ITMP2, iptr->sx.val.i);
2296 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2300 case ICMD_IFLT: /* ..., value ==> ... */
2302 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2303 if (iptr->sx.val.i == 0)
2304 emit_bltz(cd, iptr->dst.block, s1);
2306 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2307 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2309 ICONST(REG_ITMP2, iptr->sx.val.i);
2310 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2312 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2316 case ICMD_IFLE: /* ..., value ==> ... */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 if (iptr->sx.val.i == 0)
2320 emit_blez(cd, iptr->dst.block, s1);
2322 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2323 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2324 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2327 ICONST(REG_ITMP2, iptr->sx.val.i);
2328 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2329 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2334 case ICMD_IFNE: /* ..., value ==> ... */
2336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 if (iptr->sx.val.i == 0)
2338 emit_bnez(cd, iptr->dst.block, s1);
2340 ICONST(REG_ITMP2, iptr->sx.val.i);
2341 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2345 case ICMD_IFGT: /* ..., value ==> ... */
2347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2348 if (iptr->sx.val.i == 0)
2349 emit_bgtz(cd, iptr->dst.block, s1);
2351 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2352 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2353 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2356 ICONST(REG_ITMP2, iptr->sx.val.i);
2357 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2358 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2363 case ICMD_IFGE: /* ..., value ==> ... */
2365 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2366 if (iptr->sx.val.i == 0)
2367 emit_bgez(cd, iptr->dst.block, s1);
2369 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2370 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2372 ICONST(REG_ITMP2, iptr->sx.val.i);
2373 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2375 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2379 case ICMD_IF_LEQ: /* ..., value ==> ... */
2381 #if SIZEOF_VOID_P == 8
2382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2383 if (iptr->sx.val.l == 0)
2384 emit_beqz(cd, iptr->dst.block, s1);
2386 LCONST(REG_ITMP2, iptr->sx.val.l);
2387 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2390 if (iptr->sx.val.l == 0) {
2391 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2392 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2393 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2396 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2397 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2398 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2399 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2400 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2401 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2402 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2403 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2408 case ICMD_IF_LLT: /* ..., value ==> ... */
2410 #if SIZEOF_VOID_P == 8
2411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2412 if (iptr->sx.val.l == 0)
2413 emit_bltz(cd, iptr->dst.block, s1);
2415 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2416 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2418 LCONST(REG_ITMP2, iptr->sx.val.l);
2419 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2421 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2424 if (iptr->sx.val.l == 0) {
2425 /* if high word is less than zero, the whole long is too */
2426 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2427 emit_bltz(cd, iptr->dst.block, s1);
2430 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2431 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2432 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2433 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2434 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2435 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2437 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2438 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2439 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2444 case ICMD_IF_LLE: /* ..., value ==> ... */
2446 #if SIZEOF_VOID_P == 8
2447 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2448 if (iptr->sx.val.l == 0)
2449 emit_blez(cd, iptr->dst.block, s1);
2451 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2452 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2453 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2456 LCONST(REG_ITMP2, iptr->sx.val.l);
2457 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2458 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2462 if (iptr->sx.val.l == 0) {
2463 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2464 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2466 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2467 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2470 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2471 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2472 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2473 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2474 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2475 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2477 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2478 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2479 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2484 case ICMD_IF_LNE: /* ..., value ==> ... */
2486 #if SIZEOF_VOID_P == 8
2487 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2488 if (iptr->sx.val.l == 0)
2489 emit_bnez(cd, iptr->dst.block, s1);
2491 LCONST(REG_ITMP2, iptr->sx.val.l);
2492 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2495 if (iptr->sx.val.l == 0) {
2496 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2497 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2498 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2501 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2502 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2503 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2504 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2505 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2506 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2507 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2508 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2513 case ICMD_IF_LGT: /* ..., value ==> ... */
2515 #if SIZEOF_VOID_P == 8
2516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2517 if (iptr->sx.val.l == 0)
2518 emit_bgtz(cd, iptr->dst.block, s1);
2520 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2521 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2522 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2525 LCONST(REG_ITMP2, iptr->sx.val.l);
2526 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2527 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2531 if (iptr->sx.val.l == 0) {
2532 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2533 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2534 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2536 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2539 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2540 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2541 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2542 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2543 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2544 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2546 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2547 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2548 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2553 case ICMD_IF_LGE: /* ..., value ==> ... */
2555 #if SIZEOF_VOID_P == 8
2556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2557 if (iptr->sx.val.l == 0)
2558 emit_bgez(cd, iptr->dst.block, s1);
2560 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2561 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2564 LCONST(REG_ITMP2, iptr->sx.val.l);
2565 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2567 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2570 if (iptr->sx.val.l == 0) {
2571 /* if high word is greater equal zero, the whole long is too */
2572 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2573 emit_bgez(cd, iptr->dst.block, s1);
2576 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2577 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2578 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2579 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2580 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2581 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2583 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2584 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2585 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2590 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2591 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2592 #if SIZEOF_VOID_P == 8
2593 case ICMD_IF_LCMPEQ:
2596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2598 emit_beq(cd, iptr->dst.block, s1, s2);
2601 #if SIZEOF_VOID_P == 4
2602 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2603 /* op1 = target JavaVM pc */
2605 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2606 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2607 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2609 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2610 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2611 emit_beq(cd, iptr->dst.block, s1, s2);
2615 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2616 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2617 #if SIZEOF_VOID_P == 8
2618 case ICMD_IF_LCMPNE:
2621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2622 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2623 emit_bne(cd, iptr->dst.block, s1, s2);
2626 #if SIZEOF_VOID_P == 4
2627 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2629 /* TODO: could be optimized (XOR or SUB) */
2630 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2631 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2632 emit_bne(cd, iptr->dst.block, s1, s2);
2633 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2634 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2635 emit_bne(cd, iptr->dst.block, s1, s2);
2639 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2640 #if SIZEOF_VOID_P == 8
2641 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2646 M_CMPLT(s1, s2, REG_ITMP3);
2647 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2650 #if SIZEOF_VOID_P == 4
2651 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2653 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2654 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2655 M_CMPLT(s1, s2, REG_ITMP3);
2656 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2657 M_CMPGT(s1, s2, REG_ITMP3);
2658 /* load low-bits before the branch, so we know the distance */
2659 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2660 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2661 M_BNEZ(REG_ITMP3, 4); /* XXX */
2663 M_CMPULT(s1, s2, REG_ITMP3);
2664 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2668 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2669 #if SIZEOF_VOID_P == 8
2670 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2675 M_CMPGT(s1, s2, REG_ITMP3);
2676 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2679 #if SIZEOF_VOID_P == 4
2680 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2682 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2683 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2684 M_CMPGT(s1, s2, REG_ITMP3);
2685 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2686 M_CMPLT(s1, s2, REG_ITMP3);
2687 /* load low-bits before the branch, so we know the distance */
2688 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2689 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2690 M_BNEZ(REG_ITMP3, 4); /* XXX */
2692 M_CMPUGT(s1, s2, REG_ITMP3);
2693 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2697 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2698 #if SIZEOF_VOID_P == 8
2699 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2704 M_CMPGT(s1, s2, REG_ITMP3);
2705 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2708 #if SIZEOF_VOID_P == 4
2709 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2711 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2712 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2713 M_CMPLT(s1, s2, REG_ITMP3);
2714 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2715 M_CMPGT(s1, s2, REG_ITMP3);
2716 /* load low-bits before the branch, so we know the distance */
2717 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2718 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2719 M_BNEZ(REG_ITMP3, 4); /* XXX */
2721 M_CMPUGT(s1, s2, REG_ITMP3);
2722 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2726 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2727 #if SIZEOF_VOID_P == 8
2728 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2732 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2733 M_CMPLT(s1, s2, REG_ITMP3);
2734 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2737 #if SIZEOF_VOID_P == 4
2738 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2740 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2741 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2742 M_CMPGT(s1, s2, REG_ITMP3);
2743 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2744 M_CMPLT(s1, s2, REG_ITMP3);
2745 /* load low-bits before the branch, so we know the distance */
2746 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2747 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2748 M_BNEZ(REG_ITMP3, 4); /* XXX */
2750 M_CMPULT(s1, s2, REG_ITMP3);
2751 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2755 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2756 #if SIZEOF_VOID_P == 8
2760 REPLACEMENT_POINT_RETURN(cd, iptr);
2761 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2762 M_INTMOVE(s1, REG_RESULT);
2763 goto nowperformreturn;
2765 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2767 REPLACEMENT_POINT_RETURN(cd, iptr);
2768 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2769 M_INTMOVE(s1, REG_RESULT);
2771 #ifdef ENABLE_VERIFIER
2772 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2773 uc = iptr->sx.s23.s2.uc;
2775 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2777 #endif /* ENABLE_VERIFIER */
2778 goto nowperformreturn;
2780 #if SIZEOF_VOID_P == 4
2781 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2783 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2784 M_LNGMOVE(s1, REG_RESULT_PACKED);
2785 goto nowperformreturn;
2788 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2789 REPLACEMENT_POINT_RETURN(cd, iptr);
2790 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2791 M_FLTMOVE(s1, REG_FRESULT);
2792 goto nowperformreturn;
2794 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2796 REPLACEMENT_POINT_RETURN(cd, iptr);
2797 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2798 M_DBLMOVE(s1, REG_FRESULT);
2799 goto nowperformreturn;
2801 case ICMD_RETURN: /* ... ==> ... */
2803 REPLACEMENT_POINT_RETURN(cd, iptr);
2809 p = cd->stackframesize;
2811 #if !defined(NDEBUG)
2812 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2813 emit_verbosecall_exit(jd);
2816 #if defined(ENABLE_THREADS)
2817 if (checksync && code_is_synchronized(code)) {
2818 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2819 M_ALD(REG_ITMP3, REG_PV, disp);
2821 /* we need to save the proper return value */
2823 switch (iptr->opc) {
2826 #if SIZEOF_VOID_P == 8
2829 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2830 M_JSR(REG_RA, REG_ITMP3);
2831 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2833 #if SIZEOF_VOID_P == 4
2835 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2836 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2837 M_JSR(REG_RA, REG_ITMP3);
2843 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2844 M_JSR(REG_RA, REG_ITMP3);
2845 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2848 M_JSR(REG_RA, REG_ITMP3);
2849 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2853 /* and now restore the proper return value */
2855 switch (iptr->opc) {
2858 #if SIZEOF_VOID_P == 8
2861 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2863 #if SIZEOF_VOID_P == 4
2865 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2870 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2876 /* restore return address */
2878 if (!code_is_leafmethod(code)) {
2879 p--; M_ALD(REG_RA, REG_SP, p * 8);
2882 /* restore saved registers */
2884 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2885 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2887 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2888 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2891 /* deallocate stack and return */
2893 if (cd->stackframesize) {
2896 disp = cd->stackframesize * 8;
2897 lo = (short) (disp);
2898 hi = (short) (((disp) - lo) >> 16);
2902 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2904 M_LUI(REG_ITMP3,hi);
2905 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2907 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2920 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2923 branch_target_t *table;
2925 table = iptr->dst.table;
2927 l = iptr->sx.s23.s2.tablelow;
2928 i = iptr->sx.s23.s3.tablehigh;
2930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2932 {M_INTMOVE(s1, REG_ITMP1);}
2933 else if (l <= 32768) {
2934 M_IADD_IMM(s1, -l, REG_ITMP1);
2937 ICONST(REG_ITMP2, l);
2938 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2941 /* number of targets */
2946 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2947 emit_beqz(cd, table[0].block, REG_ITMP2);
2949 /* build jump table top down and use address of lowest entry */
2954 dseg_add_target(cd, table->block);
2959 /* length of dataseg after last dseg_add_target is used by load */
2961 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2962 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2963 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2970 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2973 lookup_target_t *lookup;
2975 lookup = iptr->dst.lookup;
2977 i = iptr->sx.s23.s2.lookupcount;
2979 MCODECHECK((i<<2)+8);
2980 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2983 ICONST(REG_ITMP2, lookup->value);
2984 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2988 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2994 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2996 bte = iptr->sx.s23.s3.bte;
3000 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3002 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3003 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3004 case ICMD_INVOKEINTERFACE:
3006 REPLACEMENT_POINT_INVOKE(cd, iptr);
3008 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3010 um = iptr->sx.s23.s3.um;
3011 md = um->methodref->parseddesc.md;
3014 lm = iptr->sx.s23.s3.fmiref->p.method;
3016 md = lm->parseddesc;
3020 s3 = md->paramcount;
3022 MCODECHECK((s3 << 1) + 64);
3024 /* copy arguments to registers or stack location */
3026 for (s3 = s3 - 1; s3 >= 0; s3--) {
3027 var = VAR(iptr->sx.s23.s2.args[s3]);
3028 d = md->params[s3].regoff;
3030 if (var->flags & PREALLOC)
3033 if (IS_INT_LNG_TYPE(var->type)) {
3034 #if SIZEOF_VOID_P == 8
3035 if (!md->params[s3].inmemory) {
3036 s1 = emit_load(jd, iptr, var, d);
3040 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3041 M_LST(s1, REG_SP, d);
3044 if (!md->params[s3].inmemory) {
3045 s1 = emit_load(jd, iptr, var, d);
3047 if (IS_2_WORD_TYPE(var->type))
3053 if (IS_2_WORD_TYPE(var->type)) {
3054 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3055 M_LST(s1, REG_SP, d);
3058 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3059 M_IST(s1, REG_SP, d);
3065 if (!md->params[s3].inmemory) {
3066 s1 = emit_load(jd, iptr, var, d);
3067 if (IS_2_WORD_TYPE(var->type))
3073 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3074 if (IS_2_WORD_TYPE(var->type))
3075 M_DST(s1, REG_SP, d);
3077 M_FST(s1, REG_SP, d);
3082 switch (iptr->opc) {
3084 if (bte->stub == NULL) {
3085 disp = dseg_add_functionptr(cd, bte->fp);
3086 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3088 /* generate the actual call */
3090 /* TWISTI: i actually don't know the reason for using
3091 REG_ITMP3 here instead of REG_PV. */
3093 M_JSR(REG_RA, REG_ITMP3);
3097 disp = dseg_add_functionptr(cd, bte->stub);
3098 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3100 /* generate the actual call */
3102 M_JSR(REG_RA, REG_PV);
3106 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3107 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3108 M_LDA(REG_PV, REG_RA, -disp);
3111 case ICMD_INVOKESPECIAL:
3112 emit_nullpointer_check(cd, iptr, REG_A0);
3115 case ICMD_INVOKESTATIC:
3117 disp = dseg_add_unique_address(cd, um);
3119 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3123 disp = dseg_add_address(cd, lm->stubroutine);
3125 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3127 /* generate the actual call */
3129 M_JSR(REG_RA, REG_PV);
3131 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3132 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3133 M_LDA(REG_PV, REG_RA, -disp);
3136 case ICMD_INVOKEVIRTUAL:
3137 emit_nullpointer_check(cd, iptr, REG_A0);
3140 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3145 s1 = OFFSET(vftbl_t, table[0]) +
3146 sizeof(methodptr) * lm->vftblindex;
3148 /* implicit null-pointer check */
3149 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3150 M_ALD(REG_PV, REG_METHODPTR, s1);
3152 /* generate the actual call */
3154 M_JSR(REG_RA, REG_PV);
3156 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3157 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3158 M_LDA(REG_PV, REG_RA, -disp);
3161 case ICMD_INVOKEINTERFACE:
3162 emit_nullpointer_check(cd, iptr, REG_A0);
3165 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3171 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3172 sizeof(methodptr*) * lm->clazz->index;
3174 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
3177 /* implicit null-pointer check */
3178 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3179 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3180 M_ALD(REG_PV, REG_METHODPTR, s2);
3182 /* generate the actual call */
3184 M_JSR(REG_RA, REG_PV);
3186 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3187 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3188 M_LDA(REG_PV, REG_RA, -disp);
3192 /* store return value */
3194 d = md->returntype.type;
3196 if (d != TYPE_VOID) {
3197 if (IS_INT_LNG_TYPE(d)) {
3198 #if SIZEOF_VOID_P == 8
3199 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3200 M_INTMOVE(REG_RESULT, s1);
3202 if (IS_2_WORD_TYPE(d)) {
3203 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3204 M_LNGMOVE(REG_RESULT_PACKED, s1);
3207 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3208 M_INTMOVE(REG_RESULT, s1);
3213 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3214 if (IS_2_WORD_TYPE(d))
3215 M_DMOV(REG_FRESULT, s1);
3217 M_FMOV(REG_FRESULT, s1);
3219 emit_store_dst(jd, iptr, s1);
3224 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3226 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3230 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3235 super = iptr->sx.s23.s3.c.cls;
3236 superindex = super->index;
3239 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3241 /* if class is not resolved, check which code to call */
3243 if (super == NULL) {
3244 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3246 cr = iptr->sx.s23.s3.c.ref;
3247 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3249 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3252 M_ILD(REG_ITMP2, REG_PV, disp);
3253 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3254 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3257 /* interface checkcast code */
3259 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3260 if (super == NULL) {
3261 cr = iptr->sx.s23.s3.c.ref;
3263 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3267 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3270 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3271 M_ILD(REG_ITMP3, REG_ITMP2,
3272 OFFSET(vftbl_t, interfacetablelength));
3273 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3274 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3276 M_ALD(REG_ITMP3, REG_ITMP2,
3277 OFFSET(vftbl_t, interfacetable[0]) -
3278 superindex * sizeof(methodptr*));
3279 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3282 emit_label_br(cd, BRANCH_LABEL_4);
3284 emit_label(cd, BRANCH_LABEL_3);
3287 /* class checkcast code */
3289 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3290 if (super == NULL) {
3291 emit_label(cd, BRANCH_LABEL_2);
3293 cr = iptr->sx.s23.s3.c.ref;
3294 disp = dseg_add_unique_address(cd, NULL);
3296 patcher_add_patch_ref(jd,
3297 PATCHER_resolve_classref_to_vftbl,
3301 disp = dseg_add_address(cd, super->vftbl);
3303 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3306 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3307 M_ALD(REG_ITMP3, REG_PV, disp);
3309 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3310 /* if (s1 != REG_ITMP1) { */
3311 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3312 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3313 /* #if defined(ENABLE_THREADS) */
3314 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3316 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3318 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3319 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3320 M_ALD(REG_ITMP3, REG_PV, disp);
3321 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3324 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3325 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3328 emit_label(cd, BRANCH_LABEL_5);
3331 if (super == NULL) {
3332 emit_label(cd, BRANCH_LABEL_1);
3333 emit_label(cd, BRANCH_LABEL_4);
3336 d = codegen_reg_of_dst(jd, iptr, s1);
3339 s1 = emit_load_s1(jd, iptr, REG_A0);
3340 M_INTMOVE(s1, REG_A0);
3342 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3343 cr = iptr->sx.s23.s3.c.ref;
3344 disp = dseg_add_unique_address(cd, NULL);
3346 patcher_add_patch_ref(jd,
3347 PATCHER_resolve_classref_to_classinfo,
3351 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3354 M_ALD(REG_A1, REG_PV, disp);
3355 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3356 M_ALD(REG_ITMP3, REG_PV, disp);
3357 M_JSR(REG_RA, REG_ITMP3);
3360 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3361 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3363 d = codegen_reg_of_dst(jd, iptr, s1);
3367 emit_store_dst(jd, iptr, d);
3370 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3376 super = iptr->sx.s23.s3.c.cls;
3378 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3383 super = iptr->sx.s23.s3.c.cls;
3384 superindex = super->index;
3387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3391 M_MOV(s1, REG_ITMP1);
3397 /* if class is not resolved, check which code to call */
3399 if (super == NULL) {
3400 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3402 cr = iptr->sx.s23.s3.c.ref;
3403 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3405 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3408 M_ILD(REG_ITMP3, REG_PV, disp);
3409 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3410 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3413 /* interface instanceof code */
3415 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3416 if (super == NULL) {
3417 cr = iptr->sx.s23.s3.c.ref;
3419 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3423 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3426 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3427 M_ILD(REG_ITMP3, REG_ITMP1,
3428 OFFSET(vftbl_t, interfacetablelength));
3429 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3430 M_BLEZ(REG_ITMP3, 3);
3432 M_ALD(REG_ITMP1, REG_ITMP1,
3433 OFFSET(vftbl_t, interfacetable[0]) -
3434 superindex * sizeof(methodptr*));
3435 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3438 emit_label_br(cd, BRANCH_LABEL_4);
3440 emit_label(cd, BRANCH_LABEL_3);
3443 /* class instanceof code */
3445 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3446 if (super == NULL) {
3447 emit_label(cd, BRANCH_LABEL_2);
3449 cr = iptr->sx.s23.s3.c.ref;
3450 disp = dseg_add_unique_address(cd, NULL);
3452 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3456 disp = dseg_add_address(cd, super->vftbl);
3458 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3461 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3462 M_ALD(REG_ITMP2, REG_PV, disp);
3464 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3465 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3466 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3468 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3469 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3473 emit_label(cd, BRANCH_LABEL_5);
3476 if (super == NULL) {
3477 emit_label(cd, BRANCH_LABEL_1);
3478 emit_label(cd, BRANCH_LABEL_4);
3481 emit_store_dst(jd, iptr, d);
3485 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3487 /* check for negative sizes and copy sizes to stack if necessary */
3489 MCODECHECK((iptr->s1.argcount << 1) + 64);
3491 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3493 var = VAR(iptr->sx.s23.s2.args[s1]);
3495 /* copy SAVEDVAR sizes to stack */
3497 if (!(var->flags & PREALLOC)) {
3498 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3499 #if SIZEOF_VOID_P == 8
3500 M_LST(s2, REG_SP, s1 * 8);
3502 M_IST(s2, REG_SP, (s1 + 2) * 8);
3507 /* a0 = dimension count */
3509 ICONST(REG_A0, iptr->s1.argcount);
3511 /* is patcher function set? */
3513 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3514 cr = iptr->sx.s23.s3.c.ref;
3515 disp = dseg_add_unique_address(cd, NULL);
3517 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3521 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3524 /* a1 = arraydescriptor */
3526 M_ALD(REG_A1, REG_PV, disp);
3528 /* a2 = pointer to dimensions = stack pointer */
3530 #if SIZEOF_VOID_P == 8
3531 M_MOV(REG_SP, REG_A2);
3533 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3536 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3537 M_ALD(REG_ITMP3, REG_PV, disp);
3538 M_JSR(REG_RA, REG_ITMP3);
3541 /* check for exception before result assignment */
3543 emit_exception_check(cd, iptr);
3545 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3546 M_INTMOVE(REG_RESULT, d);
3547 emit_store_dst(jd, iptr, d);
3551 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3556 } /* for instruction */
3558 MCODECHECK(64); /* XXX require smaller number? */
3560 /* At the end of a basic block we may have to append some nops,
3561 because the patcher stub calling code might be longer than the
3562 actual instruction. So codepatching does not change the
3563 following block unintentionally. */
3565 if (cd->mcodeptr < cd->lastmcodeptr) {
3566 while (cd->mcodeptr < cd->lastmcodeptr)
3570 } /* if (bptr -> flags >= BBREACHED) */
3571 } /* for basic block */
3573 /* generate traps */
3575 emit_patcher_traps(jd);
3577 /* everything's ok */
3583 /* codegen_emit_stub_native ****************************************************
3585 Emits a stub routine which calls a native method.
3587 *******************************************************************************/
3589 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3600 /* get required compiler data */
3606 /* initialize variables */
3610 /* calculate stack frame size */
3612 cd->stackframesize =
3613 1 + /* return address */
3614 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3615 sizeof(localref_table) / SIZEOF_VOID_P +
3616 md->paramcount + /* for saving arguments over calls */
3617 #if SIZEOF_VOID_P == 4
3618 5 + /* additional save space (MIPS32) */
3620 1 + /* for saving return address */
3623 /* adjust stackframe size for 16-byte alignment */
3625 if (cd->stackframesize & 1)
3626 cd->stackframesize++;
3628 /* create method header */
3630 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3631 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3632 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3633 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3634 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3636 /* generate stub code */
3638 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3639 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3641 #if !defined(NDEBUG)
3642 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3643 emit_verbosecall_enter(jd);
3646 /* save integer and float argument registers */
3648 #if SIZEOF_VOID_P == 8
3649 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3650 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3651 s1 = md->params[i].regoff;
3652 M_AST(s1, REG_SP, j * 8);
3657 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3658 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3659 if (!md->params[i].inmemory) {
3660 s1 = md->params[i].regoff;
3662 if (IS_2_WORD_TYPE(md->params[i].type))
3663 M_LST(s1, REG_SP, j * 8);
3665 M_IST(s1, REG_SP, j * 8);
3673 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3674 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3675 s1 = md->params[i].regoff;
3677 if (IS_2_WORD_TYPE(md->params[i].type))
3678 M_DST(s1, REG_SP, j * 8);
3680 M_FST(s1, REG_SP, j * 8);
3686 /* prepare data structures for native function call */
3688 M_MOV(REG_SP, REG_A0);
3689 M_MOV(REG_PV, REG_A1);
3690 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3691 M_ALD(REG_ITMP3, REG_PV, disp);
3692 M_JSR(REG_RA, REG_ITMP3);
3693 M_NOP; /* XXX fill me! */
3695 /* remember class argument */
3697 if (m->flags & ACC_STATIC)
3698 M_MOV(REG_RESULT, REG_ITMP3);
3700 /* restore integer and float argument registers */
3702 #if SIZEOF_VOID_P == 8
3703 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3704 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3705 s1 = md->params[i].regoff;
3706 M_LLD(s1, REG_SP, j * 8);
3711 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3712 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3713 if (!md->params[i].inmemory) {
3714 s1 = md->params[i].regoff;
3716 if (IS_2_WORD_TYPE(md->params[i].type))
3717 M_LLD(s1, REG_SP, j * 8);
3719 M_ILD(s1, REG_SP, j * 8);
3727 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3728 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3729 s1 = md->params[i].regoff;
3731 if (IS_2_WORD_TYPE(md->params[i].type))
3732 M_DLD(s1, REG_SP, j * 8);
3734 M_FLD(s1, REG_SP, j * 8);
3740 /* copy or spill arguments to new locations */
3742 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3743 t = md->params[i].type;
3745 if (IS_INT_LNG_TYPE(t)) {
3746 if (!md->params[i].inmemory) {
3747 s1 = md->params[i].regoff;
3748 s2 = nmd->params[j].regoff;
3750 if (!nmd->params[j].inmemory) {
3751 #if SIZEOF_VOID_P == 8
3754 if (IS_2_WORD_TYPE(t))
3761 #if SIZEOF_VOID_P == 8
3762 M_LST(s1, REG_SP, s2);
3764 if (IS_2_WORD_TYPE(t))
3765 M_LST(s1, REG_SP, s2);
3767 M_IST(s1, REG_SP, s2);
3772 s1 = md->params[i].regoff + cd->stackframesize * 8;
3773 s2 = nmd->params[j].regoff;
3775 #if SIZEOF_VOID_P == 8
3776 M_LLD(REG_ITMP1, REG_SP, s1);
3777 M_LST(REG_ITMP1, REG_SP, s2);
3779 if (IS_2_WORD_TYPE(t)) {
3780 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3781 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3784 M_ILD(REG_ITMP1, REG_SP, s1);
3785 M_IST(REG_ITMP1, REG_SP, s2);
3791 if (!md->params[i].inmemory) {
3792 s1 = md->params[i].regoff;
3793 s2 = nmd->params[j].regoff;
3795 if (!nmd->params[j].inmemory) {
3796 #if SIZEOF_VOID_P == 8
3797 if (IS_2_WORD_TYPE(t))
3802 /* On MIPS32 float arguments for native functions
3803 can never be in float argument registers, since
3804 the first argument is _always_ an integer
3805 argument (JNIEnv) */
3807 if (IS_2_WORD_TYPE(t)) {
3808 /* double high/low order is endian
3809 independent: even numbered holds low
3810 32-bits, odd numbered high 32-bits */
3812 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3813 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3820 #if SIZEOF_VOID_P == 8
3821 if (IS_2_WORD_TYPE(t))
3822 M_DST(s1, REG_SP, s2);
3824 M_FST(s1, REG_SP, s2);
3826 /* s1 may have been originally in 2 int registers,
3827 but was moved out by the native function
3828 argument(s), just get low register */
3830 if (IS_2_WORD_TYPE(t))
3831 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3833 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3838 s1 = md->params[i].regoff + cd->stackframesize * 8;
3839 s2 = nmd->params[j].regoff;
3841 #if SIZEOF_VOID_P == 8
3842 if (IS_2_WORD_TYPE(t)) {
3843 M_DLD(REG_FTMP1, REG_SP, s1);
3844 M_DST(REG_FTMP1, REG_SP, s2);
3847 M_FLD(REG_FTMP1, REG_SP, s1);
3848 M_FST(REG_FTMP1, REG_SP, s2);
3851 if (IS_2_WORD_TYPE(t)) {
3852 M_DLD(REG_FTMP1, REG_SP, s1);
3853 M_DST(REG_FTMP1, REG_SP, s2);
3856 M_FLD(REG_FTMP1, REG_SP, s1);
3857 M_FST(REG_FTMP1, REG_SP, s2);
3864 /* Handle native Java methods. */
3866 if (m->flags & ACC_NATIVE) {
3867 /* put class into second argument register */
3869 if (m->flags & ACC_STATIC)
3870 M_MOV(REG_ITMP3, REG_A1);
3872 /* put env into first argument register */
3874 disp = dseg_add_address(cd, _Jv_env);
3875 M_ALD(REG_A0, REG_PV, disp);
3878 /* Call the native function. */
3880 disp = dseg_add_functionptr(cd, f);
3881 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3882 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3883 M_NOP; /* delay slot */
3885 /* save return value */
3887 switch (md->returntype.type) {
3888 #if SIZEOF_VOID_P == 8
3892 M_LST(REG_RESULT, REG_SP, 0 * 8);
3896 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3901 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3904 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3908 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3915 #if !defined(NDEBUG)
3916 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3917 emit_verbosecall_exit(jd);
3920 /* remove native stackframe info */
3922 M_MOV(REG_SP, REG_A0);
3923 M_MOV(REG_PV, REG_A1);
3924 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3925 M_ALD(REG_ITMP3, REG_PV, disp);
3926 M_JSR(REG_RA, REG_ITMP3);
3927 M_NOP; /* XXX fill me! */
3928 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3930 /* restore return value */
3932 switch (md->returntype.type) {
3933 #if SIZEOF_VOID_P == 8
3937 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3941 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3946 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3949 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3953 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3960 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
3962 /* check for exception */
3964 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3965 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3967 M_RET(REG_RA); /* return to caller */
3968 M_NOP; /* DELAY SLOT */
3970 /* handle exception */
3972 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3973 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3974 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3975 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3977 /* Generate patcher traps. */
3979 emit_patcher_traps(jd);
3984 * These are local overrides for various environment variables in Emacs.
3985 * Please do not remove this and leave it at the end of the file, where
3986 * Emacs will automagically detect them.
3987 * ---------------------------------------------------------------------
3990 * indent-tabs-mode: t
3994 * vim:noexpandtab:sw=4:ts=4: