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.hpp"
41 #include "native/localref.hpp"
42 #include "native/native.hpp"
44 #include "threads/lock.hpp"
46 #include "vm/jit/builtin.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/global.h"
49 #include "vm/loader.hpp"
50 #include "vm/options.h"
53 #include "vm/jit/abi.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen-common.hpp"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/emit-common.hpp"
58 #include "vm/jit/jit.hpp"
59 #include "vm/jit/linenumbertable.hpp"
60 #include "vm/jit/parse.hpp"
61 #include "vm/jit/patcher-common.hpp"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.hpp"
64 #include "vm/jit/stacktrace.hpp"
65 #include "vm/jit/trap.hpp"
67 #if defined(ENABLE_SSA)
68 # include "vm/jit/optimizing/lsra.h"
69 # include "vm/jit/optimizing/ssa.h"
70 #elif defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
75 /* codegen_emit ****************************************************************
77 Generates machine code.
79 *******************************************************************************/
81 bool codegen_emit(jitdata *jd)
87 s4 len, s1, s2, s3, d, disp;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 unresolved_method *um;
94 builtintable_entry *bte;
101 /* get required compiler data */
108 /* prevent compiler warnings */
121 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
123 /* space to save used callee saved registers */
125 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128 cd->stackframesize = rd->memuse + savedregs_num;
130 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
131 if (checksync && code_is_synchronized(code))
132 cd->stackframesize++;
135 /* create method header */
138 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
141 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
142 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
144 code->synchronizedoffset = rd->memuse * 8;
146 /* REMOVEME: We still need it for exception handling in assembler. */
148 if (code_is_leafmethod(code))
149 (void) dseg_add_unique_s4(cd, 1);
151 (void) dseg_add_unique_s4(cd, 0);
153 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
154 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
156 /* create stack frame (if necessary) */
158 if (cd->stackframesize)
159 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
161 /* save return address and used callee saved registers */
163 p = cd->stackframesize;
164 if (!code_is_leafmethod(code)) {
165 p--; M_AST(REG_RA, REG_SP, p * 8);
167 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
168 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
170 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
171 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
174 /* take arguments out of register or stack frame */
178 for (p = 0, l = 0; p < md->paramcount; p++) {
179 t = md->paramtypes[p].type;
181 varindex = jd->local_map[l * 5 + t];
184 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
187 if (varindex == UNUSED)
192 s1 = md->params[p].regoff;
194 if (IS_INT_LNG_TYPE(t)) { /* integer args */
195 if (!md->params[p].inmemory) { /* register arguments */
196 if (!IS_INMEMORY(var->flags))
197 M_INTMOVE(s1, var->vv.regoff);
199 M_LST(s1, REG_SP, var->vv.regoff);
201 else { /* stack arguments */
202 if (!IS_INMEMORY(var->flags))
203 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
205 var->vv.regoff = cd->stackframesize * 8 + s1;
208 else { /* floating args */
209 if (!md->params[p].inmemory) { /* register arguments */
210 if (!IS_INMEMORY(var->flags))
211 M_FLTMOVE(s1, var->vv.regoff);
213 M_DST(s1, REG_SP, var->vv.regoff * 8);
215 else { /* stack arguments */
216 if (!(var->flags & INMEMORY))
217 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
219 var->vv.regoff = cd->stackframesize * 8 + s1;
224 /* call monitorenter function */
226 #if defined(ENABLE_THREADS)
227 if (checksync && code_is_synchronized(code)) {
228 /* stack offset for monitor argument */
233 if (opt_verbosecall) {
234 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
236 for (p = 0; p < INT_ARG_CNT; p++)
237 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
239 for (p = 0; p < FLT_ARG_CNT; p++)
240 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
242 s1 += INT_ARG_CNT + FLT_ARG_CNT;
244 #endif /* !defined(NDEBUG) */
246 /* decide which monitor enter function to call */
248 if (m->flags & ACC_STATIC) {
249 disp = dseg_add_address(cd, &m->clazz->object.header);
250 M_ALD(REG_A0, REG_PV, disp);
254 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
257 M_AST(REG_A0, REG_SP, s1 * 8);
258 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
259 M_ALD(REG_PV, REG_PV, disp);
260 M_JSR(REG_RA, REG_PV);
261 disp = (s4) (cd->mcodeptr - cd->mcodebase);
262 M_LDA(REG_PV, REG_RA, -disp);
265 if (opt_verbosecall) {
266 for (p = 0; p < INT_ARG_CNT; p++)
267 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
269 for (p = 0; p < FLT_ARG_CNT; p++)
270 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
272 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
274 #endif /* !defined(NDEBUG) */
278 /* call trace function */
281 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
282 emit_verbosecall_enter(jd);
287 /* end of header generation */
289 /* create replacement points */
291 REPLACEMENT_POINTS_INIT(cd, jd);
293 /* walk through all basic blocks */
295 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
297 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
299 if (bptr->flags >= BBREACHED) {
301 /* branch resolving */
303 codegen_resolve_branchrefs(cd, bptr);
305 /* handle replacement points */
307 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
309 /* copy interface registers to their destination */
313 #if defined(ENABLE_LSRA)
317 src = bptr->invars[len];
318 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
319 /* d = reg_of_var(m, src, REG_ITMP1); */
320 if (!(src->flags & INMEMORY))
324 M_INTMOVE(REG_ITMP1, d);
325 emit_store(jd, NULL, src, d);
332 var = VAR(bptr->invars[len]);
333 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
334 d = codegen_reg_of_var(0, var, REG_ITMP1);
335 M_INTMOVE(REG_ITMP1, d);
336 emit_store(jd, NULL, var, d);
339 assert((var->flags & INOUT));
342 #if defined(ENABLE_LSRA)
346 /* walk through all instructions */
350 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
351 if (iptr->line != currentline) {
352 linenumbertable_list_entry_add(cd, iptr->line);
353 currentline = iptr->line;
356 MCODECHECK(64); /* an instruction usually needs < 64 words */
359 case ICMD_NOP: /* ... ==> ... */
360 case ICMD_POP: /* ..., value ==> ... */
361 case ICMD_POP2: /* ..., value, value ==> ... */
364 case ICMD_INLINE_START:
366 REPLACEMENT_POINT_INLINE_START(cd, iptr);
369 case ICMD_INLINE_BODY:
371 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
372 linenumbertable_list_entry_add_inline_start(cd, iptr);
373 linenumbertable_list_entry_add(cd, iptr->line);
376 case ICMD_INLINE_END:
378 linenumbertable_list_entry_add_inline_end(cd, iptr);
379 linenumbertable_list_entry_add(cd, iptr->line);
382 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
385 emit_nullpointer_check(cd, iptr, s1);
388 /* constant operations ************************************************/
390 case ICMD_ICONST: /* ... ==> ..., constant */
392 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
393 ICONST(d, iptr->sx.val.i);
394 emit_store_dst(jd, iptr, d);
397 case ICMD_LCONST: /* ... ==> ..., constant */
399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
400 LCONST(d, iptr->sx.val.l);
401 emit_store_dst(jd, iptr, d);
404 case ICMD_FCONST: /* ... ==> ..., constant */
406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
407 disp = dseg_add_float(cd, iptr->sx.val.f);
408 M_FLD(d, REG_PV, disp);
409 emit_store_dst(jd, iptr, d);
412 case ICMD_DCONST: /* ... ==> ..., constant */
414 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
415 disp = dseg_add_double(cd, iptr->sx.val.d);
416 M_DLD(d, REG_PV, disp);
417 emit_store_dst(jd, iptr, d);
420 case ICMD_ACONST: /* ... ==> ..., constant */
422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
424 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
425 constant_classref *cr = iptr->sx.val.c.ref;
427 disp = dseg_add_unique_address(cd, cr);
429 /* XXX Only add the patcher, if this position needs to
430 be patched. If there was a previous position which
431 resolved the same class, the returned displacement
432 of dseg_add_address is ok to use. */
434 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
437 M_ALD(d, REG_PV, disp);
440 if (iptr->sx.val.anyptr == NULL)
441 M_INTMOVE(REG_ZERO, d);
443 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
444 M_ALD(d, REG_PV, disp);
447 emit_store_dst(jd, iptr, d);
451 /* load/store/move/copy operations ************************************/
453 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
454 case ICMD_ALOAD: /* s1 = local variable */
458 case ICMD_ISTORE: /* ..., value ==> ... */
470 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
475 /* integer operations *************************************************/
477 case ICMD_INEG: /* ..., value ==> ..., - value */
479 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
481 M_ISUB(REG_ZERO, s1, d);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_LNEG: /* ..., value ==> ..., - value */
487 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
489 M_LSUB(REG_ZERO, s1, d);
490 emit_store_dst(jd, iptr, d);
493 case ICMD_I2L: /* ..., value ==> ..., value */
495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
496 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
498 emit_store_dst(jd, iptr, d);
501 case ICMD_L2I: /* ..., value ==> ..., value */
503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
504 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
505 M_IADD(s1, REG_ZERO, d);
506 emit_store_dst(jd, iptr, d);
509 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
513 if (has_ext_instr_set) {
516 M_SLL_IMM(s1, 56, d);
517 M_SRA_IMM( d, 56, d);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
527 emit_store_dst(jd, iptr, d);
530 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
534 if (has_ext_instr_set) {
537 M_SLL_IMM(s1, 48, d);
538 M_SRA_IMM( d, 48, d);
540 emit_store_dst(jd, iptr, d);
544 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550 emit_store_dst(jd, iptr, d);
554 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
555 /* sx.val.i = constant */
557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
560 M_IADD_IMM(s1, iptr->sx.val.i, d);
561 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
562 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
564 /* XXX maybe use M_LDA? */
565 ICONST(REG_ITMP2, iptr->sx.val.i);
566 M_IADD(s1, REG_ITMP2, d);
568 emit_store_dst(jd, iptr, d);
571 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
574 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
575 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
577 emit_store_dst(jd, iptr, d);
580 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
581 /* sx.val.l = constant */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
585 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
586 M_LADD_IMM(s1, iptr->sx.val.l, d);
588 LCONST(REG_ITMP2, iptr->sx.val.l);
589 M_LADD(s1, REG_ITMP2, d);
591 emit_store_dst(jd, iptr, d);
594 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
600 emit_store_dst(jd, iptr, d);
603 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
604 /* sx.val.i = constant */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
609 M_ISUB_IMM(s1, iptr->sx.val.i, d);
611 ICONST(REG_ITMP2, iptr->sx.val.i);
612 M_ISUB(s1, REG_ITMP2, d);
614 emit_store_dst(jd, iptr, d);
617 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623 emit_store_dst(jd, iptr, d);
626 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
627 /* sx.val.l = constant */
629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
632 M_LSUB_IMM(s1, iptr->sx.val.l, d);
634 LCONST(REG_ITMP2, iptr->sx.val.l);
635 M_LSUB(s1, REG_ITMP2, d);
637 emit_store_dst(jd, iptr, d);
640 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
650 /* sx.val.i = constant */
652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
654 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
655 M_IMUL_IMM(s1, iptr->sx.val.i, d);
657 ICONST(REG_ITMP2, iptr->sx.val.i);
658 M_IMUL(s1, REG_ITMP2, d);
660 emit_store_dst(jd, iptr, d);
663 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669 emit_store_dst(jd, iptr, d);
672 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
673 /* sx.val.l = constant */
675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
678 M_LMUL_IMM(s1, iptr->sx.val.l, d);
680 LCONST(REG_ITMP2, iptr->sx.val.l);
681 M_LMUL(s1, REG_ITMP2, d);
683 emit_store_dst(jd, iptr, d);
686 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
687 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
689 s1 = emit_load_s1(jd, iptr, REG_A0);
690 s2 = emit_load_s2(jd, iptr, REG_A1);
691 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
692 emit_arithmetic_check(cd, iptr, s2);
694 M_INTMOVE(s1, REG_A0);
695 M_INTMOVE(s2, REG_A1);
696 bte = iptr->sx.s23.s3.bte;
697 disp = dseg_add_functionptr(cd, bte->fp);
698 M_ALD(REG_PV, REG_PV, disp);
699 M_JSR(REG_RA, REG_PV);
700 disp = (s4) (cd->mcodeptr - cd->mcodebase);
701 M_LDA(REG_PV, REG_RA, -disp);
703 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
704 emit_store_dst(jd, iptr, d);
707 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
708 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
710 s1 = emit_load_s1(jd, iptr, REG_A0);
711 s2 = emit_load_s2(jd, iptr, REG_A1);
712 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
713 emit_arithmetic_check(cd, iptr, s2);
715 M_INTMOVE(s1, REG_A0);
716 M_INTMOVE(s2, REG_A1);
717 bte = iptr->sx.s23.s3.bte;
718 disp = dseg_add_functionptr(cd, bte->fp);
719 M_ALD(REG_PV, REG_PV, disp);
720 M_JSR(REG_RA, REG_PV);
721 disp = (s4) (cd->mcodeptr - cd->mcodebase);
722 M_LDA(REG_PV, REG_RA, -disp);
724 M_INTMOVE(REG_RESULT, d);
725 emit_store_dst(jd, iptr, d);
728 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
729 case ICMD_LDIVPOW2: /* val.i = constant */
731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
733 if (iptr->sx.val.i <= 15) {
734 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
735 M_CMOVGE(s1, s1, REG_ITMP2);
737 M_SRA_IMM(s1, 63, REG_ITMP2);
738 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
739 M_LADD(s1, REG_ITMP2, REG_ITMP2);
741 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
742 emit_store_dst(jd, iptr, d);
745 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
747 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
748 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
749 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
750 M_AND_IMM(s2, 0x1f, REG_ITMP3);
751 M_SLL(s1, REG_ITMP3, d);
752 M_IADD(d, REG_ZERO, d);
753 emit_store_dst(jd, iptr, d);
756 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
757 /* sx.val.i = constant */
759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
760 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
761 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
762 M_IADD(d, REG_ZERO, d);
763 emit_store_dst(jd, iptr, d);
766 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
771 M_AND_IMM(s2, 0x1f, REG_ITMP3);
772 M_SRA(s1, REG_ITMP3, d);
773 emit_store_dst(jd, iptr, d);
776 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
777 /* sx.val.i = constant */
779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
780 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
781 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
790 M_AND_IMM(s2, 0x1f, REG_ITMP3);
792 M_SRL(d, REG_ITMP3, d);
793 M_IADD(d, REG_ZERO, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
798 /* sx.val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
804 M_IADD(d, REG_ZERO, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
818 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
822 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
823 emit_store_dst(jd, iptr, d);
826 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
829 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
830 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
836 /* sx.val.i = constant */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
840 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 emit_store_dst(jd, iptr, d);
853 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
854 /* sx.val.i = constant */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
858 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
859 emit_store_dst(jd, iptr, d);
862 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 emit_store_dst(jd, iptr, d);
872 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
873 /* sx.val.i = constant */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
877 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
878 M_AND_IMM(s1, iptr->sx.val.i, d);
879 } else if (iptr->sx.val.i == 0xffff) {
881 } else if (iptr->sx.val.i == 0xffffff) {
882 M_ZAPNOT_IMM(s1, 0x07, d);
884 ICONST(REG_ITMP2, iptr->sx.val.i);
885 M_AND(s1, REG_ITMP2, d);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
891 /* sx.val.i = constant */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896 M_MOV(s1, REG_ITMP1);
899 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
900 M_AND_IMM(s1, iptr->sx.val.i, d);
902 M_ISUB(REG_ZERO, s1, d);
903 M_AND_IMM(d, iptr->sx.val.i, d);
904 } else if (iptr->sx.val.i == 0xffff) {
907 M_ISUB(REG_ZERO, s1, d);
909 } else if (iptr->sx.val.i == 0xffffff) {
910 M_ZAPNOT_IMM(s1, 0x07, d);
912 M_ISUB(REG_ZERO, s1, d);
913 M_ZAPNOT_IMM(d, 0x07, d);
915 ICONST(REG_ITMP3, iptr->sx.val.i);
916 M_AND(s1, REG_ITMP3, d);
918 M_ISUB(REG_ZERO, s1, d);
919 M_AND(d, REG_ITMP3, d);
921 M_ISUB(REG_ZERO, d, d);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
926 /* sx.val.l = constant */
928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
929 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
930 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
931 M_AND_IMM(s1, iptr->sx.val.l, d);
932 } else if (iptr->sx.val.l == 0xffffL) {
934 } else if (iptr->sx.val.l == 0xffffffL) {
935 M_ZAPNOT_IMM(s1, 0x07, d);
936 } else if (iptr->sx.val.l == 0xffffffffL) {
938 } else if (iptr->sx.val.l == 0xffffffffffL) {
939 M_ZAPNOT_IMM(s1, 0x1f, d);
940 } else if (iptr->sx.val.l == 0xffffffffffffL) {
941 M_ZAPNOT_IMM(s1, 0x3f, d);
942 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
943 M_ZAPNOT_IMM(s1, 0x7f, d);
945 LCONST(REG_ITMP2, iptr->sx.val.l);
946 M_AND(s1, REG_ITMP2, d);
948 emit_store_dst(jd, iptr, d);
951 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
952 /* sx.val.l = constant */
954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
955 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
957 M_MOV(s1, REG_ITMP1);
960 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
961 M_AND_IMM(s1, iptr->sx.val.l, d);
963 M_LSUB(REG_ZERO, s1, d);
964 M_AND_IMM(d, iptr->sx.val.l, d);
965 } else if (iptr->sx.val.l == 0xffffL) {
968 M_LSUB(REG_ZERO, s1, d);
970 } else if (iptr->sx.val.l == 0xffffffL) {
971 M_ZAPNOT_IMM(s1, 0x07, d);
973 M_LSUB(REG_ZERO, s1, d);
974 M_ZAPNOT_IMM(d, 0x07, d);
975 } else if (iptr->sx.val.l == 0xffffffffL) {
978 M_LSUB(REG_ZERO, s1, d);
980 } else if (iptr->sx.val.l == 0xffffffffffL) {
981 M_ZAPNOT_IMM(s1, 0x1f, d);
983 M_LSUB(REG_ZERO, s1, d);
984 M_ZAPNOT_IMM(d, 0x1f, d);
985 } else if (iptr->sx.val.l == 0xffffffffffffL) {
986 M_ZAPNOT_IMM(s1, 0x3f, d);
988 M_LSUB(REG_ZERO, s1, d);
989 M_ZAPNOT_IMM(d, 0x3f, d);
990 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
991 M_ZAPNOT_IMM(s1, 0x7f, d);
993 M_LSUB(REG_ZERO, s1, d);
994 M_ZAPNOT_IMM(d, 0x7f, d);
996 LCONST(REG_ITMP3, iptr->sx.val.l);
997 M_AND(s1, REG_ITMP3, d);
999 M_LSUB(REG_ZERO, s1, d);
1000 M_AND(d, REG_ITMP3, d);
1002 M_LSUB(REG_ZERO, d, d);
1003 emit_store_dst(jd, iptr, d);
1006 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013 emit_store_dst(jd, iptr, d);
1016 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1017 /* sx.val.i = constant */
1019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1022 M_OR_IMM(s1, iptr->sx.val.i, d);
1024 ICONST(REG_ITMP2, iptr->sx.val.i);
1025 M_OR(s1, REG_ITMP2, d);
1027 emit_store_dst(jd, iptr, d);
1030 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1031 /* sx.val.l = constant */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1035 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1036 M_OR_IMM(s1, iptr->sx.val.l, d);
1038 LCONST(REG_ITMP2, iptr->sx.val.l);
1039 M_OR(s1, REG_ITMP2, d);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1048 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1051 emit_store_dst(jd, iptr, d);
1054 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1055 /* sx.val.i = constant */
1057 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1058 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1059 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1060 M_XOR_IMM(s1, iptr->sx.val.i, d);
1062 ICONST(REG_ITMP2, iptr->sx.val.i);
1063 M_XOR(s1, REG_ITMP2, d);
1065 emit_store_dst(jd, iptr, d);
1068 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1069 /* sx.val.l = constant */
1071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1072 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1073 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1074 M_XOR_IMM(s1, iptr->sx.val.l, d);
1076 LCONST(REG_ITMP2, iptr->sx.val.l);
1077 M_XOR(s1, REG_ITMP2, d);
1079 emit_store_dst(jd, iptr, d);
1083 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1088 M_CMPLT(s1, s2, REG_ITMP3);
1089 M_CMPLT(s2, s1, REG_ITMP1);
1090 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1091 emit_store_dst(jd, iptr, d);
1095 /* floating operations ************************************************/
1097 case ICMD_FNEG: /* ..., value ==> ..., - value */
1099 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1100 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_DNEG: /* ..., value ==> ..., - value */
1107 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1108 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1110 emit_store_dst(jd, iptr, d);
1113 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1115 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1118 if (d == s1 || d == s2) {
1119 M_FADDS(s1, s2, REG_FTMP3);
1121 M_FMOV(REG_FTMP3, d);
1126 emit_store_dst(jd, iptr, d);
1129 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1131 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1132 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1133 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1134 if (d == s1 || d == s2) {
1135 M_DADDS(s1, s2, REG_FTMP3);
1137 M_FMOV(REG_FTMP3, d);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1147 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1148 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1149 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1150 if (d == s1 || d == s2) {
1151 M_FSUBS(s1, s2, REG_FTMP3);
1153 M_FMOV(REG_FTMP3, d);
1158 emit_store_dst(jd, iptr, d);
1161 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1163 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1164 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1166 if (d == s1 || d == s2) {
1167 M_DSUBS(s1, s2, REG_FTMP3);
1169 M_FMOV(REG_FTMP3, d);
1174 emit_store_dst(jd, iptr, d);
1177 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1179 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1180 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1181 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1182 if (d == s1 || d == s2) {
1183 M_FMULS(s1, s2, REG_FTMP3);
1185 M_FMOV(REG_FTMP3, d);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1197 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1198 if (d == s1 || d == s2) {
1199 M_DMULS(s1, s2, REG_FTMP3);
1201 M_FMOV(REG_FTMP3, d);
1206 emit_store_dst(jd, iptr, d);
1209 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1211 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1212 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1213 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1214 if (d == s1 || d == s2) {
1215 M_FDIVS(s1, s2, REG_FTMP3);
1217 M_FMOV(REG_FTMP3, d);
1222 emit_store_dst(jd, iptr, d);
1225 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1227 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1228 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1229 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1230 if (d == s1 || d == s2) {
1231 M_DDIVS(s1, s2, REG_FTMP3);
1233 M_FMOV(REG_FTMP3, d);
1238 emit_store_dst(jd, iptr, d);
1241 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1243 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1244 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1245 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1246 M_LST(s1, REG_PV, disp);
1247 M_DLD(d, REG_PV, disp);
1249 emit_store_dst(jd, iptr, d);
1252 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1255 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1256 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1257 M_LST(s1, REG_PV, disp);
1258 M_DLD(d, REG_PV, disp);
1260 emit_store_dst(jd, iptr, d);
1263 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1267 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1268 M_CVTDL_C(s1, REG_FTMP2);
1269 M_CVTLI(REG_FTMP2, REG_FTMP3);
1270 M_DST(REG_FTMP3, REG_PV, disp);
1271 M_ILD(d, REG_PV, disp);
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1277 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1279 disp = dseg_add_unique_double(cd, 0.0); /* FIXME Not thread safe! */
1280 M_CVTDL_C(s1, REG_FTMP2);
1281 M_DST(REG_FTMP2, REG_PV, disp);
1282 M_LLD(d, REG_PV, disp);
1283 emit_store_dst(jd, iptr, d);
1286 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1288 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1289 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1292 emit_store_dst(jd, iptr, d);
1295 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1297 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1298 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1306 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1307 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1308 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1309 M_LSUB_IMM(REG_ZERO, 1, d);
1310 M_FCMPEQS(s1, s2, REG_FTMP3);
1312 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1314 M_FCMPLTS(s2, s1, REG_FTMP3);
1316 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1317 M_LADD_IMM(REG_ZERO, 1, d);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1323 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1326 M_LADD_IMM(REG_ZERO, 1, d);
1327 M_FCMPEQS(s1, s2, REG_FTMP3);
1329 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1331 M_FCMPLTS(s1, s2, REG_FTMP3);
1333 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1334 M_LSUB_IMM(REG_ZERO, 1, d);
1335 emit_store_dst(jd, iptr, d);
1339 /* memory operations **************************************************/
1341 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1345 /* implicit null-pointer check */
1346 M_ILD(d, s1, OFFSET(java_array_t, size));
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1353 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1355 /* implicit null-pointer check */
1356 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1357 if (has_ext_instr_set) {
1358 M_LADD(s2, s1, REG_ITMP1);
1359 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1363 M_LADD(s2, s1, REG_ITMP1);
1364 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1365 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1366 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1367 M_SRA_IMM(d, 56, d);
1369 emit_store_dst(jd, iptr, d);
1372 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1374 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1375 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1376 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1377 /* implicit null-pointer check */
1378 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1379 if (has_ext_instr_set) {
1380 M_LADD(s2, s1, REG_ITMP1);
1381 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1382 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1385 M_LADD (s2, s1, REG_ITMP1);
1386 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1387 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1388 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1389 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1391 emit_store_dst(jd, iptr, d);
1394 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1396 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1399 /* implicit null-pointer check */
1400 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1401 if (has_ext_instr_set) {
1402 M_LADD(s2, s1, REG_ITMP1);
1403 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1404 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1407 M_LADD(s2, s1, REG_ITMP1);
1408 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1409 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1410 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1411 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1412 M_SRA_IMM(d, 48, d);
1414 emit_store_dst(jd, iptr, d);
1417 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1420 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1422 /* implicit null-pointer check */
1423 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1424 M_S4ADDQ(s2, s1, REG_ITMP1);
1425 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1432 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1434 /* implicit null-pointer check */
1435 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436 M_S8ADDQ(s2, s1, REG_ITMP1);
1437 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1438 emit_store_dst(jd, iptr, d);
1441 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1444 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1445 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1446 /* implicit null-pointer check */
1447 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1448 M_S4ADDQ(s2, s1, REG_ITMP1);
1449 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1450 emit_store_dst(jd, iptr, d);
1453 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1457 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1458 /* implicit null-pointer check */
1459 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1460 M_S8ADDQ(s2, s1, REG_ITMP1);
1461 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1470 /* implicit null-pointer check */
1471 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1472 M_SAADDQ(s2, s1, REG_ITMP1);
1473 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1474 emit_store_dst(jd, iptr, d);
1478 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1480 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1481 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1482 /* implicit null-pointer check */
1483 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1484 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1485 if (has_ext_instr_set) {
1486 M_LADD(s2, s1, REG_ITMP1);
1487 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1490 M_LADD(s2, s1, REG_ITMP1);
1491 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1492 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1493 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1494 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1495 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1496 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1500 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1502 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1503 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1504 /* implicit null-pointer check */
1505 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1506 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1507 if (has_ext_instr_set) {
1508 M_LADD(s2, s1, REG_ITMP1);
1509 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1510 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1513 M_LADD(s2, s1, REG_ITMP1);
1514 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1515 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1516 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1517 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1518 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1519 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1520 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1524 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1527 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1528 /* implicit null-pointer check */
1529 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1530 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1531 if (has_ext_instr_set) {
1532 M_LADD(s2, s1, REG_ITMP1);
1533 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1534 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1537 M_LADD(s2, s1, REG_ITMP1);
1538 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1539 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1540 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1541 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1542 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1543 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1544 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1548 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1552 /* implicit null-pointer check */
1553 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1554 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1555 M_S4ADDQ(s2, s1, REG_ITMP1);
1556 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1559 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1563 /* implicit null-pointer check */
1564 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1565 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1566 M_S8ADDQ(s2, s1, REG_ITMP1);
1567 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1570 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1574 /* implicit null-pointer check */
1575 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1576 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1577 M_S4ADDQ(s2, s1, REG_ITMP1);
1578 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1581 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1584 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1585 /* implicit null-pointer check */
1586 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1587 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1588 M_S8ADDQ(s2, s1, REG_ITMP1);
1589 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1592 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1594 s1 = emit_load_s1(jd, iptr, REG_A0);
1595 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1596 /* implicit null-pointer check */
1597 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1598 s3 = emit_load_s3(jd, iptr, REG_A1);
1600 M_INTMOVE(s1, REG_A0);
1601 M_INTMOVE(s3, REG_A1);
1603 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1604 M_ALD(REG_PV, REG_PV, disp);
1605 M_JSR(REG_RA, REG_PV);
1606 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1607 M_LDA(REG_PV, REG_RA, -disp);
1608 emit_arraystore_check(cd, iptr);
1610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1611 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1612 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1613 M_SAADDQ(s2, s1, REG_ITMP1);
1614 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1618 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1622 /* implicit null-pointer check */
1623 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1624 if (has_ext_instr_set) {
1625 M_LADD(s2, s1, REG_ITMP1);
1626 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1629 M_LADD(s2, s1, REG_ITMP1);
1630 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1631 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1632 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1633 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1634 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1635 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1639 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
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 if (has_ext_instr_set) {
1646 M_LADD(s2, s1, REG_ITMP1);
1647 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1648 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1651 M_LADD(s2, s1, REG_ITMP1);
1652 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1653 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1654 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1655 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1656 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1657 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1658 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1662 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666 /* implicit null-pointer check */
1667 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1668 if (has_ext_instr_set) {
1669 M_LADD(s2, s1, REG_ITMP1);
1670 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1671 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1674 M_LADD(s2, s1, REG_ITMP1);
1675 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1676 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1677 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1678 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1679 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1680 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1681 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1685 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1688 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1689 /* implicit null-pointer check */
1690 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1691 M_S4ADDQ(s2, s1, REG_ITMP1);
1692 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1695 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1699 /* implicit null-pointer check */
1700 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1701 M_S8ADDQ(s2, s1, REG_ITMP1);
1702 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1705 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1708 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1709 /* implicit null-pointer check */
1710 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1711 M_SAADDQ(s2, s1, REG_ITMP1);
1712 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1716 case ICMD_GETSTATIC: /* ... ==> ..., value */
1718 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1719 uf = iptr->sx.s23.s3.uf;
1720 fieldtype = uf->fieldref->parseddesc.fd->type;
1721 disp = dseg_add_unique_address(cd, uf);
1723 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1726 fi = iptr->sx.s23.s3.fmiref->p.field;
1727 fieldtype = fi->type;
1728 disp = dseg_add_address(cd, fi->value);
1730 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1731 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1735 M_ALD(REG_ITMP1, REG_PV, disp);
1736 switch (fieldtype) {
1738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1739 M_ILD(d, REG_ITMP1, 0);
1742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1743 M_LLD(d, REG_ITMP1, 0);
1746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1747 M_ALD(d, REG_ITMP1, 0);
1750 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1751 M_FLD(d, REG_ITMP1, 0);
1754 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1755 M_DLD(d, REG_ITMP1, 0);
1758 emit_store_dst(jd, iptr, d);
1761 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1763 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1764 uf = iptr->sx.s23.s3.uf;
1765 fieldtype = uf->fieldref->parseddesc.fd->type;
1766 disp = dseg_add_unique_address(cd, uf);
1768 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1771 fi = iptr->sx.s23.s3.fmiref->p.field;
1772 fieldtype = fi->type;
1773 disp = dseg_add_address(cd, fi->value);
1775 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1776 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1780 M_ALD(REG_ITMP1, REG_PV, disp);
1781 switch (fieldtype) {
1783 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1784 M_IST(s1, REG_ITMP1, 0);
1787 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1788 M_LST(s1, REG_ITMP1, 0);
1791 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1792 M_AST(s1, REG_ITMP1, 0);
1795 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1796 M_FST(s1, REG_ITMP1, 0);
1799 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1800 M_DST(s1, REG_ITMP1, 0);
1805 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1806 /* val = value (in current instruction) */
1807 /* following NOP) */
1809 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1810 uf = iptr->sx.s23.s3.uf;
1811 fieldtype = uf->fieldref->parseddesc.fd->type;
1812 disp = dseg_add_unique_address(cd, uf);
1814 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1817 fi = iptr->sx.s23.s3.fmiref->p.field;
1818 fieldtype = fi->type;
1819 disp = dseg_add_address(cd, fi->value);
1821 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1822 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1826 M_ALD(REG_ITMP1, REG_PV, disp);
1827 switch (fieldtype) {
1829 M_IST(REG_ZERO, REG_ITMP1, 0);
1832 M_LST(REG_ZERO, REG_ITMP1, 0);
1835 M_AST(REG_ZERO, REG_ITMP1, 0);
1838 M_FST(REG_ZERO, REG_ITMP1, 0);
1841 M_DST(REG_ZERO, REG_ITMP1, 0);
1847 case ICMD_GETFIELD: /* ... ==> ..., value */
1849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1851 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1852 uf = iptr->sx.s23.s3.uf;
1853 fieldtype = uf->fieldref->parseddesc.fd->type;
1856 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1859 fi = iptr->sx.s23.s3.fmiref->p.field;
1860 fieldtype = fi->type;
1864 /* implicit null-pointer check */
1865 switch (fieldtype) {
1867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1879 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1883 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1887 emit_store_dst(jd, iptr, d);
1890 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1892 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1894 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1895 uf = iptr->sx.s23.s3.uf;
1896 fieldtype = uf->fieldref->parseddesc.fd->type;
1901 fi = iptr->sx.s23.s3.fmiref->p.field;
1902 fieldtype = fi->type;
1906 if (IS_INT_LNG_TYPE(fieldtype))
1907 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1909 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1911 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1912 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1914 /* implicit null-pointer check */
1915 switch (fieldtype) {
1917 M_IST(s2, s1, disp);
1920 M_LST(s2, s1, disp);
1923 M_AST(s2, s1, disp);
1926 M_FST(s2, s1, disp);
1929 M_DST(s2, s1, disp);
1934 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1935 /* val = value (in current instruction) */
1936 /* following NOP) */
1938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1940 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1941 uf = iptr->sx.s23.s3.uf;
1942 fieldtype = uf->fieldref->parseddesc.fd->type;
1945 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1948 fi = iptr->sx.s23.s3.fmiref->p.field;
1949 fieldtype = fi->type;
1953 /* implicit null-pointer check */
1954 switch (fieldtype) {
1956 M_IST(REG_ZERO, s1, disp);
1959 M_LST(REG_ZERO, s1, disp);
1962 M_AST(REG_ZERO, s1, disp);
1965 M_FST(REG_ZERO, s1, disp);
1968 M_DST(REG_ZERO, s1, disp);
1974 /* branch operations **************************************************/
1976 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1979 M_INTMOVE(s1, REG_ITMP1_XPTR);
1981 #ifdef ENABLE_VERIFIER
1982 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1983 unresolved_class *uc = iptr->sx.s23.s2.uc;
1985 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1987 #endif /* ENABLE_VERIFIER */
1989 disp = dseg_add_functionptr(cd, asm_handle_exception);
1990 M_ALD(REG_ITMP2, REG_PV, disp);
1991 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
1992 M_NOP; /* nop ensures that XPC is less than the end */
1993 /* of basic block */
1997 case ICMD_GOTO: /* ... ==> ... */
1998 case ICMD_RET: /* ... ==> ... */
2000 emit_br(cd, iptr->dst.block);
2004 case ICMD_JSR: /* ... ==> ... */
2006 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2010 case ICMD_IFNULL: /* ..., value ==> ... */
2011 case ICMD_IFNONNULL:
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2014 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2017 case ICMD_IFEQ: /* ..., value ==> ... */
2019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2020 if (iptr->sx.val.i == 0)
2021 emit_beqz(cd, iptr->dst.block, s1);
2023 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2024 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2026 ICONST(REG_ITMP2, iptr->sx.val.i);
2027 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2029 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2033 case ICMD_IFLT: /* ..., value ==> ... */
2035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2036 if (iptr->sx.val.i == 0)
2037 emit_bltz(cd, iptr->dst.block, s1);
2039 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2040 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2042 ICONST(REG_ITMP2, iptr->sx.val.i);
2043 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2045 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2049 case ICMD_IFLE: /* ..., value ==> ... */
2051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2052 if (iptr->sx.val.i == 0)
2053 emit_blez(cd, iptr->dst.block, s1);
2055 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2056 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2058 ICONST(REG_ITMP2, iptr->sx.val.i);
2059 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2061 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2065 case ICMD_IFNE: /* ..., value ==> ... */
2067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2068 if (iptr->sx.val.i == 0)
2069 emit_bnez(cd, iptr->dst.block, s1);
2071 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2072 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2074 ICONST(REG_ITMP2, iptr->sx.val.i);
2075 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2077 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2081 case ICMD_IFGT: /* ..., value ==> ... */
2083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2084 if (iptr->sx.val.i == 0)
2085 emit_bgtz(cd, iptr->dst.block, s1);
2087 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2088 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2090 ICONST(REG_ITMP2, iptr->sx.val.i);
2091 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2093 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2097 case ICMD_IFGE: /* ..., value ==> ... */
2099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2100 if (iptr->sx.val.i == 0)
2101 emit_bgez(cd, iptr->dst.block, s1);
2103 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2104 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2106 ICONST(REG_ITMP2, iptr->sx.val.i);
2107 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2109 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2113 case ICMD_IF_LEQ: /* ..., value ==> ... */
2115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2116 if (iptr->sx.val.l == 0)
2117 emit_beqz(cd, iptr->dst.block, s1);
2119 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2120 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2122 LCONST(REG_ITMP2, iptr->sx.val.l);
2123 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2125 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2129 case ICMD_IF_LLT: /* ..., value ==> ... */
2131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132 if (iptr->sx.val.l == 0)
2133 emit_bltz(cd, iptr->dst.block, s1);
2135 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2136 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2138 LCONST(REG_ITMP2, iptr->sx.val.l);
2139 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2141 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2145 case ICMD_IF_LLE: /* ..., value ==> ... */
2147 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2148 if (iptr->sx.val.l == 0)
2149 emit_blez(cd, iptr->dst.block, s1);
2151 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2152 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2154 LCONST(REG_ITMP2, iptr->sx.val.l);
2155 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2157 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2161 case ICMD_IF_LNE: /* ..., value ==> ... */
2163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2164 if (iptr->sx.val.l == 0)
2165 emit_bnez(cd, iptr->dst.block, s1);
2167 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2168 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2170 LCONST(REG_ITMP2, iptr->sx.val.l);
2171 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2173 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2177 case ICMD_IF_LGT: /* ..., value ==> ... */
2179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2180 if (iptr->sx.val.l == 0)
2181 emit_bgtz(cd, iptr->dst.block, s1);
2183 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2184 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2186 LCONST(REG_ITMP2, iptr->sx.val.l);
2187 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2189 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2193 case ICMD_IF_LGE: /* ..., value ==> ... */
2195 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2196 if (iptr->sx.val.l == 0)
2197 emit_bgez(cd, iptr->dst.block, s1);
2199 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2200 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2202 LCONST(REG_ITMP2, iptr->sx.val.l);
2203 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2205 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2209 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2210 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2211 case ICMD_IF_ACMPEQ:
2213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2214 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2215 M_CMPEQ(s1, s2, REG_ITMP1);
2216 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2219 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2220 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2221 case ICMD_IF_ACMPNE:
2223 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2224 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2225 M_CMPEQ(s1, s2, REG_ITMP1);
2226 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2229 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2230 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2234 M_CMPLT(s1, s2, REG_ITMP1);
2235 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2238 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2239 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2241 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2242 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2243 M_CMPLE(s1, s2, REG_ITMP1);
2244 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2247 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2248 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2250 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2251 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2252 M_CMPLE(s1, s2, REG_ITMP1);
2253 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2256 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2257 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2259 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2260 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2261 M_CMPLT(s1, s2, REG_ITMP1);
2262 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2266 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2269 REPLACEMENT_POINT_RETURN(cd, iptr);
2270 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2271 M_INTMOVE(s1, REG_RESULT);
2272 goto nowperformreturn;
2274 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2276 REPLACEMENT_POINT_RETURN(cd, iptr);
2277 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2278 M_INTMOVE(s1, REG_RESULT);
2280 #ifdef ENABLE_VERIFIER
2281 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2282 unresolved_class *uc = iptr->sx.s23.s2.uc;
2284 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2286 #endif /* ENABLE_VERIFIER */
2287 goto nowperformreturn;
2289 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2292 REPLACEMENT_POINT_RETURN(cd, iptr);
2293 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2294 M_FLTMOVE(s1, REG_FRESULT);
2295 goto nowperformreturn;
2297 case ICMD_RETURN: /* ... ==> ... */
2299 REPLACEMENT_POINT_RETURN(cd, iptr);
2305 p = cd->stackframesize;
2307 /* call trace function */
2309 #if !defined(NDEBUG)
2310 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2311 emit_verbosecall_exit(jd);
2314 #if defined(ENABLE_THREADS)
2315 if (checksync && code_is_synchronized(code)) {
2316 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2318 switch (iptr->opc) {
2322 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2326 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2330 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2331 M_ALD(REG_PV, REG_PV, disp);
2332 M_JSR(REG_RA, REG_PV);
2333 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2334 M_LDA(REG_PV, REG_RA, disp);
2336 switch (iptr->opc) {
2340 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2344 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2350 /* restore return address */
2352 if (!code_is_leafmethod(code)) {
2353 p--; M_LLD(REG_RA, REG_SP, p * 8);
2356 /* restore saved registers */
2358 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2359 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2361 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2362 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2365 /* deallocate stack */
2367 if (cd->stackframesize)
2368 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2370 M_RET(REG_ZERO, REG_RA);
2376 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2379 branch_target_t *table;
2381 table = iptr->dst.table;
2383 l = iptr->sx.s23.s2.tablelow;
2384 i = iptr->sx.s23.s3.tablehigh;
2386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2388 M_INTMOVE(s1, REG_ITMP1);
2389 } else if (l <= 32768) {
2390 M_LDA(REG_ITMP1, s1, -l);
2392 ICONST(REG_ITMP2, l);
2393 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2396 /* number of targets */
2402 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2404 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2405 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2407 emit_beqz(cd, table[0].block, REG_ITMP2);
2409 /* build jump table top down and use address of lowest entry */
2414 dseg_add_target(cd, table->block);
2419 /* length of dataseg after last dseg_add_target is used by load */
2421 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2422 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2423 M_JMP(REG_ZERO, REG_ITMP2);
2428 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2431 lookup_target_t *lookup;
2433 lookup = iptr->dst.lookup;
2435 i = iptr->sx.s23.s2.lookupcount;
2437 MCODECHECK((i<<2)+8);
2438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2441 val = lookup->value;
2442 if ((val >= 0) && (val <= 255)) {
2443 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2445 if ((val >= -32768) && (val <= 32767)) {
2446 M_LDA(REG_ITMP2, REG_ZERO, val);
2448 disp = dseg_add_s4(cd, val);
2449 M_ILD(REG_ITMP2, REG_PV, disp);
2451 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2453 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2457 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2463 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2465 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2467 bte = iptr->sx.s23.s3.bte;
2471 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2473 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2474 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2475 case ICMD_INVOKEINTERFACE:
2477 REPLACEMENT_POINT_INVOKE(cd, iptr);
2479 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2481 um = iptr->sx.s23.s3.um;
2482 md = um->methodref->parseddesc.md;
2485 lm = iptr->sx.s23.s3.fmiref->p.method;
2487 md = lm->parseddesc;
2491 s3 = md->paramcount;
2493 MCODECHECK((s3 << 1) + 64);
2495 /* copy arguments to registers or stack location */
2497 for (s3 = s3 - 1; s3 >= 0; s3--) {
2498 var = VAR(iptr->sx.s23.s2.args[s3]);
2499 d = md->params[s3].regoff;
2501 /* already preallocated (ARGVAR)? */
2503 if (var->flags & PREALLOC)
2506 if (IS_INT_LNG_TYPE(var->type)) {
2507 if (!md->params[s3].inmemory) {
2508 s1 = emit_load(jd, iptr, var, d);
2512 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2513 M_LST(s1, REG_SP, d);
2517 if (!md->params[s3].inmemory) {
2518 s1 = emit_load(jd, iptr, var, d);
2522 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2523 M_DST(s1, REG_SP, d);
2528 switch (iptr->opc) {
2530 if (bte->stub == NULL)
2531 disp = dseg_add_functionptr(cd, bte->fp);
2533 disp = dseg_add_functionptr(cd, bte->stub);
2535 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2537 /* generate the actual call */
2539 M_JSR(REG_RA, REG_PV);
2540 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2541 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2542 M_LDA(REG_PV, REG_RA, -disp);
2545 case ICMD_INVOKESPECIAL:
2546 emit_nullpointer_check(cd, iptr, REG_A0);
2549 case ICMD_INVOKESTATIC:
2551 disp = dseg_add_unique_address(cd, um);
2553 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2557 disp = dseg_add_address(cd, lm->stubroutine);
2559 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2561 /* generate the actual call */
2563 M_JSR(REG_RA, REG_PV);
2564 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2565 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2566 M_LDA(REG_PV, REG_RA, -disp);
2569 case ICMD_INVOKEVIRTUAL:
2571 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2576 s1 = OFFSET(vftbl_t, table[0]) +
2577 sizeof(methodptr) * lm->vftblindex;
2579 /* implicit null-pointer check */
2580 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2581 M_ALD(REG_PV, REG_METHODPTR, s1);
2583 /* generate the actual call */
2585 M_JSR(REG_RA, REG_PV);
2586 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2587 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2588 M_LDA(REG_PV, REG_RA, -disp);
2591 case ICMD_INVOKEINTERFACE:
2593 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2599 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2600 sizeof(methodptr*) * lm->clazz->index;
2602 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2605 /* implicit null-pointer check */
2606 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2607 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2608 M_ALD(REG_PV, REG_METHODPTR, s2);
2610 /* generate the actual call */
2612 M_JSR(REG_RA, REG_PV);
2613 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2614 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2615 M_LDA(REG_PV, REG_RA, -disp);
2619 /* store the return value */
2621 d = md->returntype.type;
2623 if (d != TYPE_VOID) {
2624 if (IS_INT_LNG_TYPE(d)) {
2625 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2626 M_INTMOVE(REG_RESULT, s1);
2629 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2630 M_FLTMOVE(REG_FRESULT, s1);
2632 emit_store_dst(jd, iptr, s1);
2637 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2639 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2640 /* object type cast-check */
2645 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2650 super = iptr->sx.s23.s3.c.cls;
2651 superindex = super->index;
2654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2656 /* if class is not resolved, check which code to call */
2658 if (super == NULL) {
2659 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2661 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2663 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2664 iptr->sx.s23.s3.c.ref,
2667 M_ILD(REG_ITMP2, REG_PV, disp);
2668 disp = dseg_add_s4(cd, ACC_INTERFACE);
2669 M_ILD(REG_ITMP3, REG_PV, disp);
2670 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2671 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2674 /* interface checkcast code */
2676 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2677 if (super == NULL) {
2678 patcher_add_patch_ref(jd,
2679 PATCHER_checkcast_interface,
2680 iptr->sx.s23.s3.c.ref,
2684 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2686 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2687 M_ILD(REG_ITMP3, REG_ITMP2,
2688 OFFSET(vftbl_t, interfacetablelength));
2689 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2690 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2692 M_ALD(REG_ITMP3, REG_ITMP2,
2693 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2694 superindex * sizeof(methodptr*)));
2695 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2698 emit_label_br(cd, BRANCH_LABEL_4);
2700 emit_label(cd, BRANCH_LABEL_3);
2703 /* class checkcast code */
2705 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2706 if (super == NULL) {
2707 emit_label(cd, BRANCH_LABEL_2);
2709 disp = dseg_add_unique_address(cd, NULL);
2711 patcher_add_patch_ref(jd,
2712 PATCHER_resolve_classref_to_vftbl,
2713 iptr->sx.s23.s3.c.ref,
2717 disp = dseg_add_address(cd, super->vftbl);
2719 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2722 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2723 M_ALD(REG_ITMP3, REG_PV, disp);
2725 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2726 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2727 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2728 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2729 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2730 emit_label_bnez(cd, BRANCH_LABEL_6, REG_ITMP1); /* good */
2732 if (super == NULL) {
2733 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2734 M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2735 emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* throw */
2738 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2739 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2740 M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
2741 emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* throw */
2743 M_ALD(REG_ITMP3, REG_PV, disp);
2744 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2745 M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2746 M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2747 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2748 emit_label_bnez(cd, BRANCH_LABEL_7, REG_ITMP1); /* good */
2750 emit_label(cd, BRANCH_LABEL_9);
2752 emit_label(cd, BRANCH_LABEL_10);
2754 /* reload s1, might have been destroyed */
2755 emit_load_s1(jd, iptr, REG_ITMP1);
2756 M_ALD_INTERN(s1, REG_ZERO, TRAP_ClassCastException);
2758 emit_label(cd, BRANCH_LABEL_7);
2759 emit_label(cd, BRANCH_LABEL_6);
2760 /* reload s1, might have been destroyed */
2761 emit_load_s1(jd, iptr, REG_ITMP1);
2764 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2765 M_CMPEQ(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2766 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP2, s1);
2770 emit_label(cd, BRANCH_LABEL_5);
2773 if (super == NULL) {
2774 emit_label(cd, BRANCH_LABEL_1);
2775 emit_label(cd, BRANCH_LABEL_4);
2778 d = codegen_reg_of_dst(jd, iptr, s1);
2781 /* array type cast-check */
2783 s1 = emit_load_s1(jd, iptr, REG_A0);
2784 M_INTMOVE(s1, REG_A0);
2786 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2787 disp = dseg_add_unique_address(cd, NULL);
2789 patcher_add_patch_ref(jd,
2790 PATCHER_resolve_classref_to_classinfo,
2791 iptr->sx.s23.s3.c.ref,
2795 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2797 M_ALD(REG_A1, REG_PV, disp);
2798 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2799 M_ALD(REG_PV, REG_PV, disp);
2800 M_JSR(REG_RA, REG_PV);
2801 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2802 M_LDA(REG_PV, REG_RA, -disp);
2804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2805 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2807 d = codegen_reg_of_dst(jd, iptr, s1);
2811 emit_store_dst(jd, iptr, d);
2814 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2818 vftbl_t *supervftbl;
2821 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2827 super = iptr->sx.s23.s3.c.cls;
2828 superindex = super->index;
2829 supervftbl = super->vftbl;
2832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2836 M_MOV(s1, REG_ITMP1);
2840 /* if class is not resolved, check which code to call */
2842 if (super == NULL) {
2844 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2846 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2848 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2849 iptr->sx.s23.s3.c.ref, disp);
2851 M_ILD(REG_ITMP3, REG_PV, disp);
2853 disp = dseg_add_s4(cd, ACC_INTERFACE);
2854 M_ILD(REG_ITMP2, REG_PV, disp);
2855 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2856 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2859 /* interface instanceof code */
2861 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2862 if (super == NULL) {
2863 /* If d == REG_ITMP2, then it's destroyed in check
2868 patcher_add_patch_ref(jd,
2869 PATCHER_instanceof_interface,
2870 iptr->sx.s23.s3.c.ref, 0);
2874 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2877 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2878 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2879 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2880 M_BLEZ(REG_ITMP3, 2);
2881 M_ALD(REG_ITMP1, REG_ITMP1,
2882 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2883 superindex * sizeof(methodptr*)));
2884 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2887 emit_label_br(cd, BRANCH_LABEL_4);
2889 emit_label(cd, BRANCH_LABEL_3);
2892 /* class instanceof code */
2894 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2895 if (super == NULL) {
2896 emit_label(cd, BRANCH_LABEL_2);
2898 disp = dseg_add_unique_address(cd, NULL);
2900 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2901 iptr->sx.s23.s3.c.ref,
2905 disp = dseg_add_address(cd, supervftbl);
2908 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2911 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2912 M_ALD(REG_ITMP3, REG_PV, disp);
2914 if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
2915 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2916 M_LADD(REG_ITMP1, REG_ITMP2, REG_ITMP1);
2917 M_ALD(REG_ITMP1, REG_ITMP1, 0);
2918 M_CMPEQ(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2919 emit_label_beqz(cd, BRANCH_LABEL_8, REG_ITMP1);
2921 emit_label_br(cd, BRANCH_LABEL_6); /* true */
2922 emit_label(cd, BRANCH_LABEL_8);
2924 if (super == NULL) {
2925 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
2926 M_CMPEQ_IMM(REG_ITMP1, OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
2927 emit_label_beqz(cd, BRANCH_LABEL_10, REG_ITMP1); /* false */
2930 M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
2932 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, subtype_depth));
2933 M_CMPLE(REG_ITMP1, REG_ITMP3, REG_ITMP3);
2934 emit_label_beqz(cd, BRANCH_LABEL_9, REG_ITMP3); /* false */
2936 M_ALD(REG_ITMP3, REG_PV, disp);
2937 M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
2938 M_S8ADDQ(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2939 M_ALD(REG_ITMP1, REG_ITMP2, -DISPLAY_SIZE*8);
2940 M_CMPEQ(REG_ITMP1, REG_ITMP3, d);
2943 emit_label_br(cd, BRANCH_LABEL_7);
2944 emit_label(cd, BRANCH_LABEL_9);
2946 emit_label(cd, BRANCH_LABEL_10);
2947 if (d == REG_ITMP2) {
2950 emit_label(cd, BRANCH_LABEL_7);
2952 emit_label(cd, BRANCH_LABEL_6);
2955 M_ALD(REG_ITMP2, REG_ITMP2, super->vftbl->subtype_offset);
2956 M_CMPEQ(REG_ITMP2, REG_ITMP3, d);
2960 emit_label(cd, BRANCH_LABEL_5);
2963 if (super == NULL) {
2964 emit_label(cd, BRANCH_LABEL_1);
2965 emit_label(cd, BRANCH_LABEL_4);
2968 emit_store_dst(jd, iptr, d);
2972 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2974 /* check for negative sizes and copy sizes to stack if necessary */
2976 MCODECHECK((iptr->s1.argcount << 1) + 64);
2978 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2980 var = VAR(iptr->sx.s23.s2.args[s1]);
2982 /* copy SAVEDVAR sizes to stack */
2984 /* Already Preallocated? */
2986 if (!(var->flags & PREALLOC)) {
2987 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2988 M_LST(s2, REG_SP, s1 * 8);
2992 /* a0 = dimension count */
2994 ICONST(REG_A0, iptr->s1.argcount);
2996 /* is patcher function set? */
2998 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2999 disp = dseg_add_unique_address(cd, 0);
3001 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3002 iptr->sx.s23.s3.c.ref,
3006 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3008 /* a1 = arraydescriptor */
3010 M_ALD(REG_A1, REG_PV, disp);
3012 /* a2 = pointer to dimensions = stack pointer */
3014 M_INTMOVE(REG_SP, REG_A2);
3016 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3017 M_ALD(REG_PV, REG_PV, disp);
3018 M_JSR(REG_RA, REG_PV);
3019 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3020 M_LDA(REG_PV, REG_RA, -disp);
3022 /* check for exception before result assignment */
3024 emit_exception_check(cd, iptr);
3026 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3027 M_INTMOVE(REG_RESULT, d);
3028 emit_store_dst(jd, iptr, d);
3032 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3037 } /* for instruction */
3039 } /* if (bptr -> flags >= BBREACHED) */
3040 } /* for basic block */
3042 /* generate traps */
3044 emit_patcher_traps(jd);
3046 /* everything's ok */
3052 /* codegen_emit_stub_native ****************************************************
3054 Emits a stub routine which calls a native method.
3056 *******************************************************************************/
3058 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3069 /* get required compiler data */
3075 /* initialize variables */
3079 /* calculate stack frame size */
3081 cd->stackframesize =
3082 1 + /* return address */
3083 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3084 sizeof(localref_table) / SIZEOF_VOID_P +
3085 1 + /* methodinfo for call trace */
3089 /* create method header */
3091 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3092 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3093 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3094 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3095 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3097 /* generate stub code */
3099 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3100 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3102 #if defined(ENABLE_GC_CACAO)
3103 /* Save callee saved integer registers in stackframeinfo (GC may
3104 need to recover them during a collection). */
3106 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3107 OFFSET(stackframeinfo_t, intregs);
3109 for (i = 0; i < INT_SAV_CNT; i++)
3110 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3113 /* save integer and float argument registers */
3115 for (i = 0; i < md->paramcount; i++) {
3116 if (!md->params[i].inmemory) {
3117 s1 = md->params[i].regoff;
3119 switch (md->paramtypes[i].type) {
3123 M_LST(s1, REG_SP, i * 8);
3126 M_FST(s1, REG_SP, i * 8);
3129 M_DST(s1, REG_SP, i * 8);
3135 /* prepare data structures for native function call */
3137 M_MOV(REG_SP, REG_A0);
3138 M_MOV(REG_PV, REG_A1);
3139 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3140 M_ALD(REG_PV, REG_PV, disp);
3141 M_JSR(REG_RA, REG_PV);
3142 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3143 M_LDA(REG_PV, REG_RA, -disp);
3145 /* remember class argument */
3147 if (m->flags & ACC_STATIC)
3148 M_MOV(REG_RESULT, REG_ITMP3);
3150 /* restore integer and float argument registers */
3152 for (i = 0; i < md->paramcount; i++) {
3153 if (!md->params[i].inmemory) {
3154 s1 = md->params[i].regoff;
3156 switch (md->paramtypes[i].type) {
3160 M_LLD(s1, REG_SP, i * 8);
3163 M_FLD(s1, REG_SP, i * 8);
3166 M_DLD(s1, REG_SP, i * 8);
3172 /* copy or spill arguments to new locations */
3174 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3175 t = md->paramtypes[i].type;
3177 if (IS_INT_LNG_TYPE(t)) {
3178 if (!md->params[i].inmemory) {
3179 s1 = md->params[i].regoff;
3180 s2 = nmd->params[j].regoff;
3182 if (!nmd->params[j].inmemory)
3185 M_LST(s1, REG_SP, s2);
3188 s1 = md->params[i].regoff + cd->stackframesize * 8;
3189 s2 = nmd->params[j].regoff;
3190 M_LLD(REG_ITMP1, REG_SP, s1);
3191 M_LST(REG_ITMP1, REG_SP, s2);
3195 if (!md->params[i].inmemory) {
3196 s1 = md->params[i].regoff;
3197 s2 = nmd->params[j].regoff;
3199 if (!nmd->params[j].inmemory)
3202 if (IS_2_WORD_TYPE(t))
3203 M_DST(s1, REG_SP, s2);
3205 M_FST(s1, REG_SP, s2);
3209 s1 = md->params[i].regoff + cd->stackframesize * 8;
3210 s2 = nmd->params[j].regoff;
3211 M_DLD(REG_FTMP1, REG_SP, s1);
3212 if (IS_2_WORD_TYPE(t))
3213 M_DST(REG_FTMP1, REG_SP, s2);
3215 M_FST(REG_FTMP1, REG_SP, s2);
3220 /* Handle native Java methods. */
3222 if (m->flags & ACC_NATIVE) {
3223 /* put class into second argument register */
3225 if (m->flags & ACC_STATIC)
3226 M_MOV(REG_ITMP3, REG_A1);
3228 /* put env into first argument register */
3230 disp = dseg_add_address(cd, VM_get_jnienv());
3231 M_ALD(REG_A0, REG_PV, disp);
3234 /* Call the native function. */
3236 disp = dseg_add_functionptr(cd, f);
3237 M_ALD(REG_PV, REG_PV, disp);
3238 M_JSR(REG_RA, REG_PV); /* call native method */
3239 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3240 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3242 /* save return value */
3244 switch (md->returntype.type) {
3248 M_LST(REG_RESULT, REG_SP, 0 * 8);
3251 M_FST(REG_FRESULT, REG_SP, 0 * 8);
3254 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3260 /* remove native stackframe info */
3262 M_MOV(REG_SP, REG_A0);
3263 M_MOV(REG_PV, REG_A1);
3264 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3265 M_ALD(REG_PV, REG_PV, disp);
3266 M_JSR(REG_RA, REG_PV);
3267 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3268 M_LDA(REG_PV, REG_RA, -disp);
3269 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3271 /* restore return value */
3273 switch (md->returntype.type) {
3277 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3280 M_FLD(REG_FRESULT, REG_SP, 0 * 8);
3283 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3289 #if defined(ENABLE_GC_CACAO)
3290 /* Restore callee saved integer registers from stackframeinfo (GC
3291 might have modified them during a collection). */
3293 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3294 OFFSET(stackframeinfo_t, intregs);
3296 for (i = 0; i < INT_SAV_CNT; i++)
3297 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3300 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3301 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3303 /* check for exception */
3305 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3306 M_RET(REG_ZERO, REG_RA); /* return to caller */
3308 /* handle exception */
3310 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3312 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3313 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3314 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3319 * These are local overrides for various environment variables in Emacs.
3320 * Please do not remove this and leave it at the end of the file, where
3321 * Emacs will automagically detect them.
3322 * ---------------------------------------------------------------------
3325 * indent-tabs-mode: t
3329 * vim:noexpandtab:sw=4:ts=4: