1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
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
36 #include "vm/jit/alpha/arch.h"
37 #include "vm/jit/alpha/codegen.h"
39 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/localref.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/linenumbertable.h"
59 #include "vm/jit/parse.h"
60 #include "vm/jit/patcher-common.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vm/jit/trap.h"
66 #if defined(ENABLE_SSA)
67 # include "vm/jit/optimizing/lsra.h"
68 # include "vm/jit/optimizing/ssa.h"
69 #elif defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
77 /* codegen_emit ****************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen_emit(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
94 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
95 unresolved_method *um;
96 builtintable_entry *bte;
103 /* get required compiler data */
110 /* prevent compiler warnings */
123 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
125 /* space to save used callee saved registers */
127 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
130 cd->stackframesize = rd->memuse + savedregs_num;
132 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
133 if (checksync && code_is_synchronized(code))
134 cd->stackframesize++;
137 /* create method header */
140 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
143 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
144 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
146 code->synchronizedoffset = rd->memuse * 8;
148 /* REMOVEME: We still need it for exception handling in assembler. */
150 if (code_is_leafmethod(code))
151 (void) dseg_add_unique_s4(cd, 1);
153 (void) dseg_add_unique_s4(cd, 0);
155 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
156 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
158 /* create stack frame (if necessary) */
160 if (cd->stackframesize)
161 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
163 /* save return address and used callee saved registers */
165 p = cd->stackframesize;
166 if (!code_is_leafmethod(code)) {
167 p--; M_AST(REG_RA, REG_SP, p * 8);
169 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
170 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
172 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
173 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
176 /* take arguments out of register or stack frame */
180 for (p = 0, l = 0; p < md->paramcount; p++) {
181 t = md->paramtypes[p].type;
183 varindex = jd->local_map[l * 5 + t];
186 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
189 if (varindex == UNUSED)
194 s1 = md->params[p].regoff;
196 if (IS_INT_LNG_TYPE(t)) { /* integer args */
197 if (!md->params[p].inmemory) { /* register arguments */
198 if (!IS_INMEMORY(var->flags))
199 M_INTMOVE(s1, var->vv.regoff);
201 M_LST(s1, REG_SP, var->vv.regoff);
203 else { /* stack arguments */
204 if (!IS_INMEMORY(var->flags))
205 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
207 var->vv.regoff = cd->stackframesize * 8 + s1;
210 else { /* floating args */
211 if (!md->params[p].inmemory) { /* register arguments */
212 if (!IS_INMEMORY(var->flags))
213 M_FLTMOVE(s1, var->vv.regoff);
215 M_DST(s1, REG_SP, var->vv.regoff * 8);
217 else { /* stack arguments */
218 if (!(var->flags & INMEMORY))
219 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
221 var->vv.regoff = cd->stackframesize * 8 + s1;
226 /* call monitorenter function */
228 #if defined(ENABLE_THREADS)
229 if (checksync && code_is_synchronized(code)) {
230 /* stack offset for monitor argument */
235 if (opt_verbosecall) {
236 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
238 for (p = 0; p < INT_ARG_CNT; p++)
239 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
241 for (p = 0; p < FLT_ARG_CNT; p++)
242 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
244 s1 += INT_ARG_CNT + FLT_ARG_CNT;
246 #endif /* !defined(NDEBUG) */
248 /* decide which monitor enter function to call */
250 if (m->flags & ACC_STATIC) {
251 disp = dseg_add_address(cd, &m->clazz->object.header);
252 M_ALD(REG_A0, REG_PV, disp);
256 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
259 M_AST(REG_A0, REG_SP, s1 * 8);
260 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
261 M_ALD(REG_PV, REG_PV, disp);
262 M_JSR(REG_RA, REG_PV);
263 disp = (s4) (cd->mcodeptr - cd->mcodebase);
264 M_LDA(REG_PV, REG_RA, -disp);
267 if (opt_verbosecall) {
268 for (p = 0; p < INT_ARG_CNT; p++)
269 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
271 for (p = 0; p < FLT_ARG_CNT; p++)
272 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
274 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
276 #endif /* !defined(NDEBUG) */
280 /* call trace function */
283 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
284 emit_verbosecall_enter(jd);
289 /* end of header generation */
291 /* create replacement points */
293 REPLACEMENT_POINTS_INIT(cd, jd);
295 /* walk through all basic blocks */
297 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
299 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
301 if (bptr->flags >= BBREACHED) {
303 /* branch resolving */
305 codegen_resolve_branchrefs(cd, bptr);
307 /* handle replacement points */
309 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
311 /* copy interface registers to their destination */
315 #if defined(ENABLE_LSRA)
319 src = bptr->invars[len];
320 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
321 /* d = reg_of_var(m, src, REG_ITMP1); */
322 if (!(src->flags & INMEMORY))
326 M_INTMOVE(REG_ITMP1, d);
327 emit_store(jd, NULL, src, d);
334 var = VAR(bptr->invars[len]);
335 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
336 d = codegen_reg_of_var(0, var, REG_ITMP1);
337 M_INTMOVE(REG_ITMP1, d);
338 emit_store(jd, NULL, var, d);
341 assert((var->flags & INOUT));
344 #if defined(ENABLE_LSRA)
348 /* walk through all instructions */
352 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
353 if (iptr->line != currentline) {
354 linenumbertable_list_entry_add(cd, iptr->line);
355 currentline = iptr->line;
358 MCODECHECK(64); /* an instruction usually needs < 64 words */
361 case ICMD_NOP: /* ... ==> ... */
362 case ICMD_POP: /* ..., value ==> ... */
363 case ICMD_POP2: /* ..., value, value ==> ... */
366 case ICMD_INLINE_START:
368 REPLACEMENT_POINT_INLINE_START(cd, iptr);
371 case ICMD_INLINE_BODY:
373 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
374 linenumbertable_list_entry_add_inline_start(cd, iptr);
375 linenumbertable_list_entry_add(cd, iptr->line);
378 case ICMD_INLINE_END:
380 linenumbertable_list_entry_add_inline_end(cd, iptr);
381 linenumbertable_list_entry_add(cd, iptr->line);
384 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
387 emit_nullpointer_check(cd, iptr, s1);
390 /* constant operations ************************************************/
392 case ICMD_ICONST: /* ... ==> ..., constant */
394 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
395 ICONST(d, iptr->sx.val.i);
396 emit_store_dst(jd, iptr, d);
399 case ICMD_LCONST: /* ... ==> ..., constant */
401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
402 LCONST(d, iptr->sx.val.l);
403 emit_store_dst(jd, iptr, d);
406 case ICMD_FCONST: /* ... ==> ..., constant */
408 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
409 disp = dseg_add_float(cd, iptr->sx.val.f);
410 M_FLD(d, REG_PV, disp);
411 emit_store_dst(jd, iptr, d);
414 case ICMD_DCONST: /* ... ==> ..., constant */
416 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
417 disp = dseg_add_double(cd, iptr->sx.val.d);
418 M_DLD(d, REG_PV, disp);
419 emit_store_dst(jd, iptr, d);
422 case ICMD_ACONST: /* ... ==> ..., constant */
424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
426 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
427 constant_classref *cr = iptr->sx.val.c.ref;
429 disp = dseg_add_unique_address(cd, cr);
431 /* XXX Only add the patcher, if this position needs to
432 be patched. If there was a previous position which
433 resolved the same class, the returned displacement
434 of dseg_add_address is ok to use. */
436 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
439 M_ALD(d, REG_PV, disp);
442 if (iptr->sx.val.anyptr == NULL)
443 M_INTMOVE(REG_ZERO, d);
445 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
446 M_ALD(d, REG_PV, disp);
449 emit_store_dst(jd, iptr, d);
453 /* load/store/move/copy operations ************************************/
455 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
456 case ICMD_ALOAD: /* s1 = local variable */
460 case ICMD_ISTORE: /* ..., value ==> ... */
472 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
477 /* integer operations *************************************************/
479 case ICMD_INEG: /* ..., value ==> ..., - value */
481 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
482 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
483 M_ISUB(REG_ZERO, s1, d);
484 emit_store_dst(jd, iptr, d);
487 case ICMD_LNEG: /* ..., value ==> ..., - value */
489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
490 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
491 M_LSUB(REG_ZERO, s1, d);
492 emit_store_dst(jd, iptr, d);
495 case ICMD_I2L: /* ..., value ==> ..., value */
497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
500 emit_store_dst(jd, iptr, d);
503 case ICMD_L2I: /* ..., value ==> ..., value */
505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
506 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
507 M_IADD(s1, REG_ZERO, d);
508 emit_store_dst(jd, iptr, d);
511 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
515 if (has_ext_instr_set) {
518 M_SLL_IMM(s1, 56, d);
519 M_SRA_IMM( d, 56, d);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536 if (has_ext_instr_set) {
539 M_SLL_IMM(s1, 48, d);
540 M_SRA_IMM( d, 48, d);
542 emit_store_dst(jd, iptr, d);
546 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552 emit_store_dst(jd, iptr, d);
556 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
557 /* sx.val.i = constant */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
561 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
562 M_IADD_IMM(s1, iptr->sx.val.i, d);
563 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
564 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
566 /* XXX maybe use M_LDA? */
567 ICONST(REG_ITMP2, iptr->sx.val.i);
568 M_IADD(s1, REG_ITMP2, d);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
579 emit_store_dst(jd, iptr, d);
582 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
583 /* sx.val.l = constant */
585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
586 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
588 M_LADD_IMM(s1, iptr->sx.val.l, d);
590 LCONST(REG_ITMP2, iptr->sx.val.l);
591 M_LADD(s1, REG_ITMP2, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602 emit_store_dst(jd, iptr, d);
605 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
606 /* sx.val.i = constant */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
611 M_ISUB_IMM(s1, iptr->sx.val.i, d);
613 ICONST(REG_ITMP2, iptr->sx.val.i);
614 M_ISUB(s1, REG_ITMP2, d);
616 emit_store_dst(jd, iptr, d);
619 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 emit_store_dst(jd, iptr, d);
628 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
629 /* sx.val.l = constant */
631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
633 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
634 M_LSUB_IMM(s1, iptr->sx.val.l, d);
636 LCONST(REG_ITMP2, iptr->sx.val.l);
637 M_LSUB(s1, REG_ITMP2, d);
639 emit_store_dst(jd, iptr, d);
642 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
644 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
645 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
652 /* sx.val.i = constant */
654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
657 M_IMUL_IMM(s1, iptr->sx.val.i, d);
659 ICONST(REG_ITMP2, iptr->sx.val.i);
660 M_IMUL(s1, REG_ITMP2, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
669 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
675 /* sx.val.l = constant */
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
680 M_LMUL_IMM(s1, iptr->sx.val.l, d);
682 LCONST(REG_ITMP2, iptr->sx.val.l);
683 M_LMUL(s1, REG_ITMP2, d);
685 emit_store_dst(jd, iptr, d);
688 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
689 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
691 s1 = emit_load_s1(jd, iptr, REG_A0);
692 s2 = emit_load_s2(jd, iptr, REG_A1);
693 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
694 emit_arithmetic_check(cd, iptr, s2);
696 M_INTMOVE(s1, REG_A0);
697 M_INTMOVE(s2, REG_A1);
698 bte = iptr->sx.s23.s3.bte;
699 disp = dseg_add_functionptr(cd, bte->fp);
700 M_ALD(REG_PV, REG_PV, disp);
701 M_JSR(REG_RA, REG_PV);
702 disp = (s4) (cd->mcodeptr - cd->mcodebase);
703 M_LDA(REG_PV, REG_RA, -disp);
705 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
706 emit_store_dst(jd, iptr, d);
709 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
710 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
712 s1 = emit_load_s1(jd, iptr, REG_A0);
713 s2 = emit_load_s2(jd, iptr, REG_A1);
714 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
715 emit_arithmetic_check(cd, iptr, s2);
717 M_INTMOVE(s1, REG_A0);
718 M_INTMOVE(s2, REG_A1);
719 bte = iptr->sx.s23.s3.bte;
720 disp = dseg_add_functionptr(cd, bte->fp);
721 M_ALD(REG_PV, REG_PV, disp);
722 M_JSR(REG_RA, REG_PV);
723 disp = (s4) (cd->mcodeptr - cd->mcodebase);
724 M_LDA(REG_PV, REG_RA, -disp);
726 M_INTMOVE(REG_RESULT, d);
727 emit_store_dst(jd, iptr, d);
730 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
731 case ICMD_LDIVPOW2: /* val.i = constant */
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
735 if (iptr->sx.val.i <= 15) {
736 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
737 M_CMOVGE(s1, s1, REG_ITMP2);
739 M_SRA_IMM(s1, 63, REG_ITMP2);
740 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
741 M_LADD(s1, REG_ITMP2, REG_ITMP2);
743 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
744 emit_store_dst(jd, iptr, d);
747 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
750 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752 M_AND_IMM(s2, 0x1f, REG_ITMP3);
753 M_SLL(s1, REG_ITMP3, d);
754 M_IADD(d, REG_ZERO, d);
755 emit_store_dst(jd, iptr, d);
758 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
759 /* sx.val.i = constant */
761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
763 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
764 M_IADD(d, REG_ZERO, d);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
773 M_AND_IMM(s2, 0x1f, REG_ITMP3);
774 M_SRA(s1, REG_ITMP3, d);
775 emit_store_dst(jd, iptr, d);
778 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
779 /* sx.val.i = constant */
781 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
783 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
791 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792 M_AND_IMM(s2, 0x1f, REG_ITMP2);
794 M_SRL(d, REG_ITMP2, d);
795 M_IADD(d, REG_ZERO, d);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
800 /* sx.val.i = constant */
802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
806 M_IADD(d, REG_ZERO, d);
807 emit_store_dst(jd, iptr, d);
810 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
814 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
816 emit_store_dst(jd, iptr, d);
819 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
820 /* sx.val.i = constant */
822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
823 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
838 /* sx.val.i = constant */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
843 emit_store_dst(jd, iptr, d);
846 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
856 /* sx.val.i = constant */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
867 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
875 /* sx.val.i = constant */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
880 M_AND_IMM(s1, iptr->sx.val.i, d);
881 } else if (iptr->sx.val.i == 0xffff) {
883 } else if (iptr->sx.val.i == 0xffffff) {
884 M_ZAPNOT_IMM(s1, 0x07, d);
886 ICONST(REG_ITMP2, iptr->sx.val.i);
887 M_AND(s1, REG_ITMP2, d);
889 emit_store_dst(jd, iptr, d);
892 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
893 /* sx.val.i = constant */
895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 M_MOV(s1, REG_ITMP1);
901 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
902 M_AND_IMM(s1, iptr->sx.val.i, d);
904 M_ISUB(REG_ZERO, s1, d);
905 M_AND_IMM(d, iptr->sx.val.i, d);
906 } else if (iptr->sx.val.i == 0xffff) {
909 M_ISUB(REG_ZERO, s1, d);
911 } else if (iptr->sx.val.i == 0xffffff) {
912 M_ZAPNOT_IMM(s1, 0x07, d);
914 M_ISUB(REG_ZERO, s1, d);
915 M_ZAPNOT_IMM(d, 0x07, d);
917 ICONST(REG_ITMP2, iptr->sx.val.i);
918 M_AND(s1, REG_ITMP2, d);
920 M_ISUB(REG_ZERO, s1, d);
921 M_AND(d, REG_ITMP2, d);
923 M_ISUB(REG_ZERO, d, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
928 /* sx.val.l = constant */
930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
933 M_AND_IMM(s1, iptr->sx.val.l, d);
934 } else if (iptr->sx.val.l == 0xffffL) {
936 } else if (iptr->sx.val.l == 0xffffffL) {
937 M_ZAPNOT_IMM(s1, 0x07, d);
938 } else if (iptr->sx.val.l == 0xffffffffL) {
940 } else if (iptr->sx.val.l == 0xffffffffffL) {
941 M_ZAPNOT_IMM(s1, 0x1f, d);
942 } else if (iptr->sx.val.l == 0xffffffffffffL) {
943 M_ZAPNOT_IMM(s1, 0x3f, d);
944 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
945 M_ZAPNOT_IMM(s1, 0x7f, d);
947 LCONST(REG_ITMP2, iptr->sx.val.l);
948 M_AND(s1, REG_ITMP2, d);
950 emit_store_dst(jd, iptr, d);
953 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
954 /* sx.val.l = constant */
956 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
959 M_MOV(s1, REG_ITMP1);
962 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
963 M_AND_IMM(s1, iptr->sx.val.l, d);
965 M_LSUB(REG_ZERO, s1, d);
966 M_AND_IMM(d, iptr->sx.val.l, d);
967 } else if (iptr->sx.val.l == 0xffffL) {
970 M_LSUB(REG_ZERO, s1, d);
972 } else if (iptr->sx.val.l == 0xffffffL) {
973 M_ZAPNOT_IMM(s1, 0x07, d);
975 M_LSUB(REG_ZERO, s1, d);
976 M_ZAPNOT_IMM(d, 0x07, d);
977 } else if (iptr->sx.val.l == 0xffffffffL) {
980 M_LSUB(REG_ZERO, s1, d);
982 } else if (iptr->sx.val.l == 0xffffffffffL) {
983 M_ZAPNOT_IMM(s1, 0x1f, d);
985 M_LSUB(REG_ZERO, s1, d);
986 M_ZAPNOT_IMM(d, 0x1f, d);
987 } else if (iptr->sx.val.l == 0xffffffffffffL) {
988 M_ZAPNOT_IMM(s1, 0x3f, d);
990 M_LSUB(REG_ZERO, s1, d);
991 M_ZAPNOT_IMM(d, 0x3f, d);
992 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
993 M_ZAPNOT_IMM(s1, 0x7f, d);
995 M_LSUB(REG_ZERO, s1, d);
996 M_ZAPNOT_IMM(d, 0x7f, d);
998 LCONST(REG_ITMP2, iptr->sx.val.l);
999 M_AND(s1, REG_ITMP2, d);
1001 M_LSUB(REG_ZERO, s1, d);
1002 M_AND(d, REG_ITMP2, d);
1004 M_LSUB(REG_ZERO, d, d);
1005 emit_store_dst(jd, iptr, d);
1008 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1012 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1013 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1015 emit_store_dst(jd, iptr, d);
1018 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1019 /* sx.val.i = constant */
1021 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1022 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1023 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1024 M_OR_IMM(s1, iptr->sx.val.i, d);
1026 ICONST(REG_ITMP2, iptr->sx.val.i);
1027 M_OR(s1, REG_ITMP2, d);
1029 emit_store_dst(jd, iptr, d);
1032 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1033 /* sx.val.l = constant */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1037 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1038 M_OR_IMM(s1, iptr->sx.val.l, d);
1040 LCONST(REG_ITMP2, iptr->sx.val.l);
1041 M_OR(s1, REG_ITMP2, d);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1053 emit_store_dst(jd, iptr, d);
1056 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1057 /* sx.val.i = constant */
1059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1061 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1062 M_XOR_IMM(s1, iptr->sx.val.i, d);
1064 ICONST(REG_ITMP2, iptr->sx.val.i);
1065 M_XOR(s1, REG_ITMP2, d);
1067 emit_store_dst(jd, iptr, d);
1070 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1071 /* sx.val.l = constant */
1073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1075 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1076 M_XOR_IMM(s1, iptr->sx.val.l, d);
1078 LCONST(REG_ITMP2, iptr->sx.val.l);
1079 M_XOR(s1, REG_ITMP2, d);
1081 emit_store_dst(jd, iptr, d);
1085 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1090 M_CMPLT(s1, s2, REG_ITMP3);
1091 M_CMPLT(s2, s1, REG_ITMP1);
1092 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1093 emit_store_dst(jd, iptr, d);
1097 /* floating operations ************************************************/
1099 case ICMD_FNEG: /* ..., value ==> ..., - value */
1101 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1104 emit_store_dst(jd, iptr, d);
1107 case ICMD_DNEG: /* ..., value ==> ..., - value */
1109 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1110 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1117 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1118 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1119 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1123 if (d == s1 || d == s2) {
1124 M_FADDS(s1, s2, REG_FTMP3);
1126 M_FMOV(REG_FTMP3, d);
1132 emit_store_dst(jd, iptr, d);
1135 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1137 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1138 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1139 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1143 if (d == s1 || d == s2) {
1144 M_DADDS(s1, s2, REG_FTMP3);
1146 M_FMOV(REG_FTMP3, d);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1159 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1163 if (d == s1 || d == s2) {
1164 M_FSUBS(s1, s2, REG_FTMP3);
1166 M_FMOV(REG_FTMP3, d);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1177 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1178 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1179 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1183 if (d == s1 || d == s2) {
1184 M_DSUBS(s1, s2, REG_FTMP3);
1186 M_FMOV(REG_FTMP3, d);
1192 emit_store_dst(jd, iptr, d);
1195 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1197 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1198 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1199 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1203 if (d == s1 || d == s2) {
1204 M_FMULS(s1, s2, REG_FTMP3);
1206 M_FMOV(REG_FTMP3, d);
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1217 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1218 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1219 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1223 if (d == s1 || d == s2) {
1224 M_DMULS(s1, s2, REG_FTMP3);
1226 M_FMOV(REG_FTMP3, d);
1232 emit_store_dst(jd, iptr, d);
1235 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1237 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1238 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1239 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1243 if (d == s1 || d == s2) {
1244 M_FDIVS(s1, s2, REG_FTMP3);
1246 M_FMOV(REG_FTMP3, d);
1252 emit_store_dst(jd, iptr, d);
1255 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1257 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1258 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1259 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1263 if (d == s1 || d == s2) {
1264 M_DDIVS(s1, s2, REG_FTMP3);
1266 M_FMOV(REG_FTMP3, d);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1277 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1280 M_LST(s1, REG_PV, disp);
1281 M_DLD(d, REG_PV, disp);
1283 emit_store_dst(jd, iptr, d);
1286 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1289 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1290 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1291 M_LST(s1, REG_PV, disp);
1292 M_DLD(d, REG_PV, disp);
1294 emit_store_dst(jd, iptr, d);
1297 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1299 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1301 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1302 M_CVTDL_C(s1, REG_FTMP2);
1303 M_CVTLI(REG_FTMP2, REG_FTMP3);
1304 M_DST(REG_FTMP3, REG_PV, disp);
1305 M_ILD(d, REG_PV, disp);
1306 emit_store_dst(jd, iptr, d);
1309 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1311 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1312 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1313 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1314 M_CVTDL_C(s1, REG_FTMP2);
1315 M_DST(REG_FTMP2, REG_PV, disp);
1316 M_LLD(d, REG_PV, disp);
1317 emit_store_dst(jd, iptr, d);
1320 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1322 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1323 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1326 emit_store_dst(jd, iptr, d);
1329 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1331 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1332 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1339 emit_store_dst(jd, iptr, d);
1342 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1344 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1345 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1346 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1348 M_LSUB_IMM(REG_ZERO, 1, d);
1349 M_FCMPEQ(s1, s2, REG_FTMP3);
1350 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1352 M_FCMPLT(s2, s1, REG_FTMP3);
1353 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1354 M_LADD_IMM(REG_ZERO, 1, d);
1356 M_LSUB_IMM(REG_ZERO, 1, d);
1357 M_FCMPEQS(s1, s2, REG_FTMP3);
1359 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1361 M_FCMPLTS(s2, s1, REG_FTMP3);
1363 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1364 M_LADD_IMM(REG_ZERO, 1, d);
1366 emit_store_dst(jd, iptr, d);
1369 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1371 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1372 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1373 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1375 M_LADD_IMM(REG_ZERO, 1, d);
1376 M_FCMPEQ(s1, s2, REG_FTMP3);
1377 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1379 M_FCMPLT(s1, s2, REG_FTMP3);
1380 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1381 M_LSUB_IMM(REG_ZERO, 1, d);
1383 M_LADD_IMM(REG_ZERO, 1, d);
1384 M_FCMPEQS(s1, s2, REG_FTMP3);
1386 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1388 M_FCMPLTS(s1, s2, REG_FTMP3);
1390 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1391 M_LSUB_IMM(REG_ZERO, 1, d);
1393 emit_store_dst(jd, iptr, d);
1397 /* memory operations **************************************************/
1399 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1403 /* implicit null-pointer check */
1404 M_ILD(d, s1, OFFSET(java_array_t, size));
1405 emit_store_dst(jd, iptr, d);
1408 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1410 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1411 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1412 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1413 /* implicit null-pointer check */
1414 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1415 if (has_ext_instr_set) {
1416 M_LADD(s2, s1, REG_ITMP1);
1417 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1421 M_LADD(s2, s1, REG_ITMP1);
1422 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1423 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1424 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1425 M_SRA_IMM(d, 56, d);
1427 emit_store_dst(jd, iptr, d);
1430 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1435 /* implicit null-pointer check */
1436 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1437 if (has_ext_instr_set) {
1438 M_LADD(s2, s1, REG_ITMP1);
1439 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1440 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1443 M_LADD (s2, s1, REG_ITMP1);
1444 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1445 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1446 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1447 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1449 emit_store_dst(jd, iptr, d);
1452 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1454 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1455 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1457 /* implicit null-pointer check */
1458 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1459 if (has_ext_instr_set) {
1460 M_LADD(s2, s1, REG_ITMP1);
1461 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1462 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1465 M_LADD(s2, s1, REG_ITMP1);
1466 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1467 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1468 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1469 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1470 M_SRA_IMM(d, 48, d);
1472 emit_store_dst(jd, iptr, d);
1475 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1478 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1480 /* implicit null-pointer check */
1481 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1482 M_S4ADDQ(s2, s1, REG_ITMP1);
1483 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1484 emit_store_dst(jd, iptr, d);
1487 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1491 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1492 /* implicit null-pointer check */
1493 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1494 M_S8ADDQ(s2, s1, REG_ITMP1);
1495 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1496 emit_store_dst(jd, iptr, d);
1499 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1502 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1503 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1504 /* implicit null-pointer check */
1505 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1506 M_S4ADDQ(s2, s1, REG_ITMP1);
1507 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1508 emit_store_dst(jd, iptr, d);
1511 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1515 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1516 /* implicit null-pointer check */
1517 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1518 M_S8ADDQ(s2, s1, REG_ITMP1);
1519 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1520 emit_store_dst(jd, iptr, d);
1523 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1528 /* implicit null-pointer check */
1529 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1530 M_SAADDQ(s2, s1, REG_ITMP1);
1531 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1532 emit_store_dst(jd, iptr, d);
1536 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1539 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1540 /* implicit null-pointer check */
1541 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1542 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1543 if (has_ext_instr_set) {
1544 M_LADD(s2, s1, REG_ITMP1);
1545 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1548 M_LADD(s2, s1, REG_ITMP1);
1549 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1550 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1551 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1552 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1553 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1554 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1558 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1561 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1562 /* implicit null-pointer check */
1563 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1564 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1565 if (has_ext_instr_set) {
1566 M_LADD(s2, s1, REG_ITMP1);
1567 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1568 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1571 M_LADD(s2, s1, REG_ITMP1);
1572 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1573 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1574 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1575 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1576 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1577 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1578 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1582 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1585 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1586 /* implicit null-pointer check */
1587 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1588 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1589 if (has_ext_instr_set) {
1590 M_LADD(s2, s1, REG_ITMP1);
1591 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1592 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1595 M_LADD(s2, s1, REG_ITMP1);
1596 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1597 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1598 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1599 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1600 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1601 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1602 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1606 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1609 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1610 /* implicit null-pointer check */
1611 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1612 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1613 M_S4ADDQ(s2, s1, REG_ITMP1);
1614 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1617 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621 /* implicit null-pointer check */
1622 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1623 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1624 M_S8ADDQ(s2, s1, REG_ITMP1);
1625 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1628 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1630 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1631 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1632 /* implicit null-pointer check */
1633 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1634 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1635 M_S4ADDQ(s2, s1, REG_ITMP1);
1636 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1639 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1642 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1643 /* implicit null-pointer check */
1644 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1645 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1646 M_S8ADDQ(s2, s1, REG_ITMP1);
1647 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1650 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1652 s1 = emit_load_s1(jd, iptr, REG_A0);
1653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1654 /* implicit null-pointer check */
1655 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1656 s3 = emit_load_s3(jd, iptr, REG_A1);
1658 M_INTMOVE(s1, REG_A0);
1659 M_INTMOVE(s3, REG_A1);
1661 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1662 M_ALD(REG_PV, REG_PV, disp);
1663 M_JSR(REG_RA, REG_PV);
1664 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1665 M_LDA(REG_PV, REG_RA, -disp);
1666 emit_arraystore_check(cd, iptr);
1668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1670 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1671 M_SAADDQ(s2, s1, REG_ITMP1);
1672 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1676 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1680 /* implicit null-pointer check */
1681 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1682 if (has_ext_instr_set) {
1683 M_LADD(s2, s1, REG_ITMP1);
1684 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1687 M_LADD(s2, s1, REG_ITMP1);
1688 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1689 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1690 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1691 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1692 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1693 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1697 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1701 /* implicit null-pointer check */
1702 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1703 if (has_ext_instr_set) {
1704 M_LADD(s2, s1, REG_ITMP1);
1705 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1706 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1709 M_LADD(s2, s1, REG_ITMP1);
1710 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1711 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1712 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1713 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1714 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1715 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1716 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1720 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1724 /* implicit null-pointer check */
1725 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1726 if (has_ext_instr_set) {
1727 M_LADD(s2, s1, REG_ITMP1);
1728 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1729 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1732 M_LADD(s2, s1, REG_ITMP1);
1733 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1734 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1735 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1736 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1737 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1738 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1739 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1743 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1745 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1746 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1747 /* implicit null-pointer check */
1748 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1749 M_S4ADDQ(s2, s1, REG_ITMP1);
1750 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1753 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1756 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1757 /* implicit null-pointer check */
1758 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1759 M_S8ADDQ(s2, s1, REG_ITMP1);
1760 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1763 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1767 /* implicit null-pointer check */
1768 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1769 M_SAADDQ(s2, s1, REG_ITMP1);
1770 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1774 case ICMD_GETSTATIC: /* ... ==> ..., value */
1776 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1777 uf = iptr->sx.s23.s3.uf;
1778 fieldtype = uf->fieldref->parseddesc.fd->type;
1779 disp = dseg_add_unique_address(cd, uf);
1781 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1784 fi = iptr->sx.s23.s3.fmiref->p.field;
1785 fieldtype = fi->type;
1786 disp = dseg_add_address(cd, fi->value);
1788 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1789 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1793 M_ALD(REG_ITMP1, REG_PV, disp);
1794 switch (fieldtype) {
1796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1797 M_ILD(d, REG_ITMP1, 0);
1800 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1801 M_LLD(d, REG_ITMP1, 0);
1804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1805 M_ALD(d, REG_ITMP1, 0);
1808 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1809 M_FLD(d, REG_ITMP1, 0);
1812 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1813 M_DLD(d, REG_ITMP1, 0);
1816 emit_store_dst(jd, iptr, d);
1819 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1821 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1822 uf = iptr->sx.s23.s3.uf;
1823 fieldtype = uf->fieldref->parseddesc.fd->type;
1824 disp = dseg_add_unique_address(cd, uf);
1826 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1829 fi = iptr->sx.s23.s3.fmiref->p.field;
1830 fieldtype = fi->type;
1831 disp = dseg_add_address(cd, fi->value);
1833 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1834 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1838 M_ALD(REG_ITMP1, REG_PV, disp);
1839 switch (fieldtype) {
1841 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1842 M_IST(s1, REG_ITMP1, 0);
1845 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1846 M_LST(s1, REG_ITMP1, 0);
1849 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1850 M_AST(s1, REG_ITMP1, 0);
1853 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1854 M_FST(s1, REG_ITMP1, 0);
1857 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1858 M_DST(s1, REG_ITMP1, 0);
1863 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1864 /* val = value (in current instruction) */
1865 /* following NOP) */
1867 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1868 uf = iptr->sx.s23.s3.uf;
1869 fieldtype = uf->fieldref->parseddesc.fd->type;
1870 disp = dseg_add_unique_address(cd, uf);
1872 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1875 fi = iptr->sx.s23.s3.fmiref->p.field;
1876 fieldtype = fi->type;
1877 disp = dseg_add_address(cd, fi->value);
1879 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1880 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1884 M_ALD(REG_ITMP1, REG_PV, disp);
1885 switch (fieldtype) {
1887 M_IST(REG_ZERO, REG_ITMP1, 0);
1890 M_LST(REG_ZERO, REG_ITMP1, 0);
1893 M_AST(REG_ZERO, REG_ITMP1, 0);
1896 M_FST(REG_ZERO, REG_ITMP1, 0);
1899 M_DST(REG_ZERO, REG_ITMP1, 0);
1905 case ICMD_GETFIELD: /* ... ==> ..., value */
1907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1909 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1910 uf = iptr->sx.s23.s3.uf;
1911 fieldtype = uf->fieldref->parseddesc.fd->type;
1914 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1917 fi = iptr->sx.s23.s3.fmiref->p.field;
1918 fieldtype = fi->type;
1922 /* implicit null-pointer check */
1923 switch (fieldtype) {
1925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1929 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1937 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1941 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1945 emit_store_dst(jd, iptr, d);
1948 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1952 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1953 uf = iptr->sx.s23.s3.uf;
1954 fieldtype = uf->fieldref->parseddesc.fd->type;
1959 fi = iptr->sx.s23.s3.fmiref->p.field;
1960 fieldtype = fi->type;
1964 if (IS_INT_LNG_TYPE(fieldtype))
1965 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1967 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1969 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1970 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1972 /* implicit null-pointer check */
1973 switch (fieldtype) {
1975 M_IST(s2, s1, disp);
1978 M_LST(s2, s1, disp);
1981 M_AST(s2, s1, disp);
1984 M_FST(s2, s1, disp);
1987 M_DST(s2, s1, disp);
1992 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1993 /* val = value (in current instruction) */
1994 /* following NOP) */
1996 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1999 uf = iptr->sx.s23.s3.uf;
2000 fieldtype = uf->fieldref->parseddesc.fd->type;
2003 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2006 fi = iptr->sx.s23.s3.fmiref->p.field;
2007 fieldtype = fi->type;
2011 /* implicit null-pointer check */
2012 switch (fieldtype) {
2014 M_IST(REG_ZERO, s1, disp);
2017 M_LST(REG_ZERO, s1, disp);
2020 M_AST(REG_ZERO, s1, disp);
2023 M_FST(REG_ZERO, s1, disp);
2026 M_DST(REG_ZERO, s1, disp);
2032 /* branch operations **************************************************/
2034 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2036 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2037 M_INTMOVE(s1, REG_ITMP1_XPTR);
2039 #ifdef ENABLE_VERIFIER
2040 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2041 unresolved_class *uc = iptr->sx.s23.s2.uc;
2043 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2045 #endif /* ENABLE_VERIFIER */
2047 disp = dseg_add_functionptr(cd, asm_handle_exception);
2048 M_ALD(REG_ITMP2, REG_PV, disp);
2049 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2050 M_NOP; /* nop ensures that XPC is less than the end */
2051 /* of basic block */
2055 case ICMD_GOTO: /* ... ==> ... */
2056 case ICMD_RET: /* ... ==> ... */
2058 emit_br(cd, iptr->dst.block);
2062 case ICMD_JSR: /* ... ==> ... */
2064 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2068 case ICMD_IFNULL: /* ..., value ==> ... */
2069 case ICMD_IFNONNULL:
2071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2072 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2075 case ICMD_IFEQ: /* ..., value ==> ... */
2077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2078 if (iptr->sx.val.i == 0)
2079 emit_beqz(cd, iptr->dst.block, s1);
2081 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2082 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2084 ICONST(REG_ITMP2, iptr->sx.val.i);
2085 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2087 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2091 case ICMD_IFLT: /* ..., value ==> ... */
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094 if (iptr->sx.val.i == 0)
2095 emit_bltz(cd, iptr->dst.block, s1);
2097 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2098 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2100 ICONST(REG_ITMP2, iptr->sx.val.i);
2101 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2103 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2107 case ICMD_IFLE: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 if (iptr->sx.val.i == 0)
2111 emit_blez(cd, iptr->dst.block, s1);
2113 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2114 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2116 ICONST(REG_ITMP2, iptr->sx.val.i);
2117 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2119 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2123 case ICMD_IFNE: /* ..., value ==> ... */
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 if (iptr->sx.val.i == 0)
2127 emit_bnez(cd, iptr->dst.block, s1);
2129 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2130 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2132 ICONST(REG_ITMP2, iptr->sx.val.i);
2133 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2135 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2139 case ICMD_IFGT: /* ..., value ==> ... */
2141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2142 if (iptr->sx.val.i == 0)
2143 emit_bgtz(cd, iptr->dst.block, s1);
2145 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2146 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2148 ICONST(REG_ITMP2, iptr->sx.val.i);
2149 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2151 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2155 case ICMD_IFGE: /* ..., value ==> ... */
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158 if (iptr->sx.val.i == 0)
2159 emit_bgez(cd, iptr->dst.block, s1);
2161 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2162 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2164 ICONST(REG_ITMP2, iptr->sx.val.i);
2165 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2167 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2171 case ICMD_IF_LEQ: /* ..., value ==> ... */
2173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2174 if (iptr->sx.val.l == 0)
2175 emit_beqz(cd, iptr->dst.block, s1);
2177 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2178 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2180 LCONST(REG_ITMP2, iptr->sx.val.l);
2181 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2183 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2187 case ICMD_IF_LLT: /* ..., value ==> ... */
2189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2190 if (iptr->sx.val.l == 0)
2191 emit_bltz(cd, iptr->dst.block, s1);
2193 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2194 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2196 LCONST(REG_ITMP2, iptr->sx.val.l);
2197 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2199 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2203 case ICMD_IF_LLE: /* ..., value ==> ... */
2205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206 if (iptr->sx.val.l == 0)
2207 emit_blez(cd, iptr->dst.block, s1);
2209 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2210 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2212 LCONST(REG_ITMP2, iptr->sx.val.l);
2213 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2215 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2219 case ICMD_IF_LNE: /* ..., value ==> ... */
2221 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2222 if (iptr->sx.val.l == 0)
2223 emit_bnez(cd, iptr->dst.block, s1);
2225 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2226 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2228 LCONST(REG_ITMP2, iptr->sx.val.l);
2229 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2231 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2235 case ICMD_IF_LGT: /* ..., value ==> ... */
2237 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2238 if (iptr->sx.val.l == 0)
2239 emit_bgtz(cd, iptr->dst.block, s1);
2241 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2242 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2244 LCONST(REG_ITMP2, iptr->sx.val.l);
2245 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2247 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2251 case ICMD_IF_LGE: /* ..., value ==> ... */
2253 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2254 if (iptr->sx.val.l == 0)
2255 emit_bgez(cd, iptr->dst.block, s1);
2257 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2258 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2260 LCONST(REG_ITMP2, iptr->sx.val.l);
2261 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2263 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2267 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2268 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2269 case ICMD_IF_ACMPEQ:
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2273 M_CMPEQ(s1, s2, REG_ITMP1);
2274 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2277 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2278 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2279 case ICMD_IF_ACMPNE:
2281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2282 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2283 M_CMPEQ(s1, s2, REG_ITMP1);
2284 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2287 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2288 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2291 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2292 M_CMPLT(s1, s2, REG_ITMP1);
2293 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2296 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2297 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2300 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2301 M_CMPLE(s1, s2, REG_ITMP1);
2302 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2305 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2306 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2309 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2310 M_CMPLE(s1, s2, REG_ITMP1);
2311 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2314 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2315 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2319 M_CMPLT(s1, s2, REG_ITMP1);
2320 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2324 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2327 REPLACEMENT_POINT_RETURN(cd, iptr);
2328 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2329 M_INTMOVE(s1, REG_RESULT);
2330 goto nowperformreturn;
2332 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2334 REPLACEMENT_POINT_RETURN(cd, iptr);
2335 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2336 M_INTMOVE(s1, REG_RESULT);
2338 #ifdef ENABLE_VERIFIER
2339 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2340 unresolved_class *uc = iptr->sx.s23.s2.uc;
2342 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2344 #endif /* ENABLE_VERIFIER */
2345 goto nowperformreturn;
2347 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2350 REPLACEMENT_POINT_RETURN(cd, iptr);
2351 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2352 M_FLTMOVE(s1, REG_FRESULT);
2353 goto nowperformreturn;
2355 case ICMD_RETURN: /* ... ==> ... */
2357 REPLACEMENT_POINT_RETURN(cd, iptr);
2363 p = cd->stackframesize;
2365 /* call trace function */
2367 #if !defined(NDEBUG)
2368 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2369 emit_verbosecall_exit(jd);
2372 #if defined(ENABLE_THREADS)
2373 if (checksync && code_is_synchronized(code)) {
2374 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2376 switch (iptr->opc) {
2380 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2384 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2388 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2389 M_ALD(REG_PV, REG_PV, disp);
2390 M_JSR(REG_RA, REG_PV);
2391 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2392 M_LDA(REG_PV, REG_RA, disp);
2394 switch (iptr->opc) {
2398 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2402 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2408 /* restore return address */
2410 if (!code_is_leafmethod(code)) {
2411 p--; M_LLD(REG_RA, REG_SP, p * 8);
2414 /* restore saved registers */
2416 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2417 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2419 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2420 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2423 /* deallocate stack */
2425 if (cd->stackframesize)
2426 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2428 M_RET(REG_ZERO, REG_RA);
2434 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2437 branch_target_t *table;
2439 table = iptr->dst.table;
2441 l = iptr->sx.s23.s2.tablelow;
2442 i = iptr->sx.s23.s3.tablehigh;
2444 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2446 M_INTMOVE(s1, REG_ITMP1);
2447 } else if (l <= 32768) {
2448 M_LDA(REG_ITMP1, s1, -l);
2450 ICONST(REG_ITMP2, l);
2451 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2454 /* number of targets */
2460 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2462 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2463 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2465 emit_beqz(cd, table[0].block, REG_ITMP2);
2467 /* build jump table top down and use address of lowest entry */
2472 dseg_add_target(cd, table->block);
2477 /* length of dataseg after last dseg_add_target is used by load */
2479 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2480 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2481 M_JMP(REG_ZERO, REG_ITMP2);
2486 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2489 lookup_target_t *lookup;
2491 lookup = iptr->dst.lookup;
2493 i = iptr->sx.s23.s2.lookupcount;
2495 MCODECHECK((i<<2)+8);
2496 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2499 val = lookup->value;
2500 if ((val >= 0) && (val <= 255)) {
2501 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2503 if ((val >= -32768) && (val <= 32767)) {
2504 M_LDA(REG_ITMP2, REG_ZERO, val);
2506 disp = dseg_add_s4(cd, val);
2507 M_ILD(REG_ITMP2, REG_PV, disp);
2509 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2511 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2515 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2521 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2523 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2525 bte = iptr->sx.s23.s3.bte;
2529 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2531 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2532 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2533 case ICMD_INVOKEINTERFACE:
2535 REPLACEMENT_POINT_INVOKE(cd, iptr);
2537 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2539 um = iptr->sx.s23.s3.um;
2540 md = um->methodref->parseddesc.md;
2543 lm = iptr->sx.s23.s3.fmiref->p.method;
2545 md = lm->parseddesc;
2549 s3 = md->paramcount;
2551 MCODECHECK((s3 << 1) + 64);
2553 /* copy arguments to registers or stack location */
2555 for (s3 = s3 - 1; s3 >= 0; s3--) {
2556 var = VAR(iptr->sx.s23.s2.args[s3]);
2557 d = md->params[s3].regoff;
2559 /* already preallocated (ARGVAR)? */
2561 if (var->flags & PREALLOC)
2564 if (IS_INT_LNG_TYPE(var->type)) {
2565 if (!md->params[s3].inmemory) {
2566 s1 = emit_load(jd, iptr, var, d);
2570 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2571 M_LST(s1, REG_SP, d);
2575 if (!md->params[s3].inmemory) {
2576 s1 = emit_load(jd, iptr, var, d);
2580 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2581 M_DST(s1, REG_SP, d);
2586 switch (iptr->opc) {
2588 if (bte->stub == NULL)
2589 disp = dseg_add_functionptr(cd, bte->fp);
2591 disp = dseg_add_functionptr(cd, bte->stub);
2593 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2595 /* generate the actual call */
2597 M_JSR(REG_RA, REG_PV);
2598 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2599 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2600 M_LDA(REG_PV, REG_RA, -disp);
2603 case ICMD_INVOKESPECIAL:
2604 emit_nullpointer_check(cd, iptr, REG_A0);
2607 case ICMD_INVOKESTATIC:
2609 disp = dseg_add_unique_address(cd, um);
2611 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2615 disp = dseg_add_address(cd, lm->stubroutine);
2617 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2619 /* generate the actual call */
2621 M_JSR(REG_RA, REG_PV);
2622 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2623 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2624 M_LDA(REG_PV, REG_RA, -disp);
2627 case ICMD_INVOKEVIRTUAL:
2629 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2634 s1 = OFFSET(vftbl_t, table[0]) +
2635 sizeof(methodptr) * lm->vftblindex;
2637 /* implicit null-pointer check */
2638 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2639 M_ALD(REG_PV, REG_METHODPTR, s1);
2641 /* generate the actual call */
2643 M_JSR(REG_RA, REG_PV);
2644 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2645 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2646 M_LDA(REG_PV, REG_RA, -disp);
2649 case ICMD_INVOKEINTERFACE:
2651 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2657 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2658 sizeof(methodptr*) * lm->clazz->index;
2660 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2663 /* implicit null-pointer check */
2664 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2665 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2666 M_ALD(REG_PV, REG_METHODPTR, s2);
2668 /* generate the actual call */
2670 M_JSR(REG_RA, REG_PV);
2671 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2672 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2673 M_LDA(REG_PV, REG_RA, -disp);
2677 /* store the return value */
2679 d = md->returntype.type;
2681 if (d != TYPE_VOID) {
2682 if (IS_INT_LNG_TYPE(d)) {
2683 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2684 M_INTMOVE(REG_RESULT, s1);
2687 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2688 M_FLTMOVE(REG_FRESULT, s1);
2690 emit_store_dst(jd, iptr, s1);
2695 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2697 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2698 /* object type cast-check */
2703 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2708 super = iptr->sx.s23.s3.c.cls;
2709 superindex = super->index;
2712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2714 /* if class is not resolved, check which code to call */
2716 if (super == NULL) {
2717 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2719 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2721 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2722 iptr->sx.s23.s3.c.ref,
2725 M_ILD(REG_ITMP2, REG_PV, disp);
2726 disp = dseg_add_s4(cd, ACC_INTERFACE);
2727 M_ILD(REG_ITMP3, REG_PV, disp);
2728 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2729 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2732 /* interface checkcast code */
2734 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2735 if (super == NULL) {
2736 patcher_add_patch_ref(jd,
2737 PATCHER_checkcast_interface,
2738 iptr->sx.s23.s3.c.ref,
2742 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2744 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2745 M_ILD(REG_ITMP3, REG_ITMP2,
2746 OFFSET(vftbl_t, interfacetablelength));
2747 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2748 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2750 M_ALD(REG_ITMP3, REG_ITMP2,
2751 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2752 superindex * sizeof(methodptr*)));
2753 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2756 emit_label_br(cd, BRANCH_LABEL_4);
2758 emit_label(cd, BRANCH_LABEL_3);
2761 /* class checkcast code */
2763 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2764 if (super == NULL) {
2765 emit_label(cd, BRANCH_LABEL_2);
2767 disp = dseg_add_unique_address(cd, NULL);
2769 patcher_add_patch_ref(jd,
2770 PATCHER_resolve_classref_to_vftbl,
2771 iptr->sx.s23.s3.c.ref,
2775 disp = dseg_add_address(cd, super->vftbl);
2777 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2780 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2781 M_ALD(REG_ITMP3, REG_PV, disp);
2783 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2784 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2785 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2786 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2787 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2788 emit_label_bnez(cd, BRANCH_LABEL_6, REG_ITMP1); /* good */
2790 if (super == NULL) {
2791 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2792 M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2793 emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* throw */
2796 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2797 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2798 M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
2799 emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* throw */
2801 M_ALD(REG_ITMP3, REG_PV, disp);
2802 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2803 M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2804 M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2805 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2806 emit_label_bnez(cd, BRANCH_LABEL_7, REG_ITMP1); /* good */
2808 emit_label(cd, BRANCH_LABEL_9);
2810 emit_label(cd, BRANCH_LABEL_10);
2812 /* reload s1, might have been destroyed */
2813 emit_load_s1(jd, iptr, REG_ITMP1);
2814 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
2816 emit_label(cd, BRANCH_LABEL_7);
2817 emit_label(cd, BRANCH_LABEL_6);
2818 /* reload s1, might have been destroyed */
2819 emit_load_s1(jd, iptr, REG_ITMP1);
2822 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2823 M_CMPEQ(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2824 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP2, s1);
2828 emit_label(cd, BRANCH_LABEL_5);
2831 if (super == NULL) {
2832 emit_label(cd, BRANCH_LABEL_1);
2833 emit_label(cd, BRANCH_LABEL_4);
2836 d = codegen_reg_of_dst(jd, iptr, s1);
2839 /* array type cast-check */
2841 s1 = emit_load_s1(jd, iptr, REG_A0);
2842 M_INTMOVE(s1, REG_A0);
2844 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2845 disp = dseg_add_unique_address(cd, NULL);
2847 patcher_add_patch_ref(jd,
2848 PATCHER_resolve_classref_to_classinfo,
2849 iptr->sx.s23.s3.c.ref,
2853 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2855 M_ALD(REG_A1, REG_PV, disp);
2856 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2857 M_ALD(REG_PV, REG_PV, disp);
2858 M_JSR(REG_RA, REG_PV);
2859 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2860 M_LDA(REG_PV, REG_RA, -disp);
2862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2863 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2865 d = codegen_reg_of_dst(jd, iptr, s1);
2869 emit_store_dst(jd, iptr, d);
2872 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2876 vftbl_t *supervftbl;
2879 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2885 super = iptr->sx.s23.s3.c.cls;
2886 superindex = super->index;
2887 supervftbl = super->vftbl;
2890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2891 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2894 M_MOV(s1, REG_ITMP1);
2898 /* if class is not resolved, check which code to call */
2900 if (super == NULL) {
2902 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2904 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2906 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2907 iptr->sx.s23.s3.c.ref, disp);
2909 M_ILD(REG_ITMP3, REG_PV, disp);
2911 disp = dseg_add_s4(cd, ACC_INTERFACE);
2912 M_ILD(REG_ITMP2, REG_PV, disp);
2913 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2914 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2917 /* interface instanceof code */
2919 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2920 if (super == NULL) {
2921 /* If d == REG_ITMP2, then it's destroyed in check
2926 patcher_add_patch_ref(jd,
2927 PATCHER_instanceof_interface,
2928 iptr->sx.s23.s3.c.ref, 0);
2932 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2935 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2936 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2937 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2938 M_BLEZ(REG_ITMP3, 2);
2939 M_ALD(REG_ITMP1, REG_ITMP1,
2940 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2941 superindex * sizeof(methodptr*)));
2942 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2945 emit_label_br(cd, BRANCH_LABEL_4);
2947 emit_label(cd, BRANCH_LABEL_3);
2950 /* class instanceof code */
2952 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2953 if (super == NULL) {
2954 emit_label(cd, BRANCH_LABEL_2);
2956 disp = dseg_add_unique_address(cd, NULL);
2958 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2959 iptr->sx.s23.s3.c.ref,
2963 disp = dseg_add_address(cd, supervftbl);
2966 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2969 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2970 M_ALD(REG_ITMP3, REG_PV, disp);
2972 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2973 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2974 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2975 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2976 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2977 emit_label_beqz(cd, BRANCH_LABEL_8, REG_ITMP1);
2979 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2980 emit_label(cd, BRANCH_LABEL_8);
2982 if (super == NULL) {
2983 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2984 M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2985 emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* false */
2988 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2990 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2991 M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
2992 emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* false */
2994 M_ALD(REG_ITMP3, REG_PV, disp);
2995 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2996 M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2997 M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2998 M_CMPEQ(REG_ITMP1, REG_ITMP3, d);
3001 emit_label_br(cd, BRANCH_LABEL_7);
3002 emit_label(cd, BRANCH_LABEL_9);
3004 emit_label(cd, BRANCH_LABEL_10);
3005 if (d == REG_ITMP2) {
3008 emit_label(cd, BRANCH_LABEL_7);
3010 emit_label(cd, BRANCH_LABEL_6);
3013 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
3014 M_CMPEQ(REG_ITMP2, REG_ITMP3, d);
3018 emit_label(cd, BRANCH_LABEL_5);
3021 if (super == NULL) {
3022 emit_label(cd, BRANCH_LABEL_1);
3023 emit_label(cd, BRANCH_LABEL_4);
3026 emit_store_dst(jd, iptr, d);
3030 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3032 /* check for negative sizes and copy sizes to stack if necessary */
3034 MCODECHECK((iptr->s1.argcount << 1) + 64);
3036 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3038 var = VAR(iptr->sx.s23.s2.args[s1]);
3040 /* copy SAVEDVAR sizes to stack */
3042 /* Already Preallocated? */
3044 if (!(var->flags & PREALLOC)) {
3045 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3046 M_LST(s2, REG_SP, s1 * 8);
3050 /* a0 = dimension count */
3052 ICONST(REG_A0, iptr->s1.argcount);
3054 /* is patcher function set? */
3056 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3057 disp = dseg_add_unique_address(cd, 0);
3059 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3060 iptr->sx.s23.s3.c.ref,
3064 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3066 /* a1 = arraydescriptor */
3068 M_ALD(REG_A1, REG_PV, disp);
3070 /* a2 = pointer to dimensions = stack pointer */
3072 M_INTMOVE(REG_SP, REG_A2);
3074 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3075 M_ALD(REG_PV, REG_PV, disp);
3076 M_JSR(REG_RA, REG_PV);
3077 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3078 M_LDA(REG_PV, REG_RA, -disp);
3080 /* check for exception before result assignment */
3082 emit_exception_check(cd, iptr);
3084 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3085 M_INTMOVE(REG_RESULT, d);
3086 emit_store_dst(jd, iptr, d);
3090 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3095 } /* for instruction */
3097 } /* if (bptr -> flags >= BBREACHED) */
3098 } /* for basic block */
3100 /* generate traps */
3102 emit_patcher_traps(jd);
3104 /* everything's ok */
3110 /* codegen_emit_stub_native ****************************************************
3112 Emits a stub routine which calls a native method.
3114 *******************************************************************************/
3116 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3127 /* get required compiler data */
3133 /* initialize variables */
3137 /* calculate stack frame size */
3139 cd->stackframesize =
3140 1 + /* return address */
3141 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3142 sizeof(localref_table) / SIZEOF_VOID_P +
3143 1 + /* methodinfo for call trace */
3147 /* create method header */
3149 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3150 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3151 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3152 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3153 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3155 /* generate stub code */
3157 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3158 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3160 #if defined(ENABLE_GC_CACAO)
3161 /* Save callee saved integer registers in stackframeinfo (GC may
3162 need to recover them during a collection). */
3164 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3165 OFFSET(stackframeinfo_t, intregs);
3167 for (i = 0; i < INT_SAV_CNT; i++)
3168 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3171 /* save integer and float argument registers */
3173 for (i = 0; i < md->paramcount; i++) {
3174 if (!md->params[i].inmemory) {
3175 s1 = md->params[i].regoff;
3177 switch (md->paramtypes[i].type) {
3181 M_LST(s1, REG_SP, i * 8);
3184 M_FST(s1, REG_SP, i * 8);
3187 M_DST(s1, REG_SP, i * 8);
3193 /* prepare data structures for native function call */
3195 M_MOV(REG_SP, REG_A0);
3196 M_MOV(REG_PV, REG_A1);
3197 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3198 M_ALD(REG_PV, REG_PV, disp);
3199 M_JSR(REG_RA, REG_PV);
3200 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3201 M_LDA(REG_PV, REG_RA, -disp);
3203 /* remember class argument */
3205 if (m->flags & ACC_STATIC)
3206 M_MOV(REG_RESULT, REG_ITMP3);
3208 /* restore integer and float argument registers */
3210 for (i = 0; i < md->paramcount; i++) {
3211 if (!md->params[i].inmemory) {
3212 s1 = md->params[i].regoff;
3214 switch (md->paramtypes[i].type) {
3218 M_LLD(s1, REG_SP, i * 8);
3221 M_FLD(s1, REG_SP, i * 8);
3224 M_DLD(s1, REG_SP, i * 8);
3230 /* copy or spill arguments to new locations */
3232 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3233 t = md->paramtypes[i].type;
3235 if (IS_INT_LNG_TYPE(t)) {
3236 if (!md->params[i].inmemory) {
3237 s1 = md->params[i].regoff;
3238 s2 = nmd->params[j].regoff;
3240 if (!nmd->params[j].inmemory)
3243 M_LST(s1, REG_SP, s2);
3246 s1 = md->params[i].regoff + cd->stackframesize * 8;
3247 s2 = nmd->params[j].regoff;
3248 M_LLD(REG_ITMP1, REG_SP, s1);
3249 M_LST(REG_ITMP1, REG_SP, s2);
3253 if (!md->params[i].inmemory) {
3254 s1 = md->params[i].regoff;
3255 s2 = nmd->params[j].regoff;
3257 if (!nmd->params[j].inmemory)
3260 if (IS_2_WORD_TYPE(t))
3261 M_DST(s1, REG_SP, s2);
3263 M_FST(s1, REG_SP, s2);
3267 s1 = md->params[i].regoff + cd->stackframesize * 8;
3268 s2 = nmd->params[j].regoff;
3269 M_DLD(REG_FTMP1, REG_SP, s1);
3270 if (IS_2_WORD_TYPE(t))
3271 M_DST(REG_FTMP1, REG_SP, s2);
3273 M_FST(REG_FTMP1, REG_SP, s2);
3278 /* Handle native Java methods. */
3280 if (m->flags & ACC_NATIVE) {
3281 /* put class into second argument register */
3283 if (m->flags & ACC_STATIC)
3284 M_MOV(REG_ITMP3, REG_A1);
3286 /* put env into first argument register */
3288 disp = dseg_add_address(cd, _Jv_env);
3289 M_ALD(REG_A0, REG_PV, disp);
3292 /* Call the native function. */
3294 disp = dseg_add_functionptr(cd, f);
3295 M_ALD(REG_PV, REG_PV, disp);
3296 M_JSR(REG_RA, REG_PV); /* call native method */
3297 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3298 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3300 /* save return value */
3302 switch (md->returntype.type) {
3306 M_LST(REG_RESULT, REG_SP, 0 * 8);
3309 M_FST(REG_FRESULT, REG_SP, 0 * 8);
3312 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3318 /* remove native stackframe info */
3320 M_MOV(REG_SP, REG_A0);
3321 M_MOV(REG_PV, REG_A1);
3322 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3323 M_ALD(REG_PV, REG_PV, disp);
3324 M_JSR(REG_RA, REG_PV);
3325 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3326 M_LDA(REG_PV, REG_RA, -disp);
3327 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3329 /* restore return value */
3331 switch (md->returntype.type) {
3335 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3338 M_FLD(REG_FRESULT, REG_SP, 0 * 8);
3341 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3347 #if defined(ENABLE_GC_CACAO)
3348 /* Restore callee saved integer registers from stackframeinfo (GC
3349 might have modified them during a collection). */
3351 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3352 OFFSET(stackframeinfo_t, intregs);
3354 for (i = 0; i < INT_SAV_CNT; i++)
3355 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3358 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3359 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3361 /* check for exception */
3363 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3364 M_RET(REG_ZERO, REG_RA); /* return to caller */
3366 /* handle exception */
3368 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3370 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3371 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3372 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3377 * These are local overrides for various environment variables in Emacs.
3378 * Please do not remove this and leave it at the end of the file, where
3379 * Emacs will automagically detect them.
3380 * ---------------------------------------------------------------------
3383 * indent-tabs-mode: t
3387 * vim:noexpandtab:sw=4:ts=4: