1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 8245 2007-07-31 09:55:04Z michi $
40 #include "vm/jit/alpha/arch.h"
41 #include "vm/jit/alpha/codegen.h"
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
48 #include "threads/lock-common.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
52 #include "vm/global.h"
55 #include "vm/jit/abi.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen-common.h"
58 #include "vm/jit/dseg.h"
59 #include "vm/jit/emit-common.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/patcher-common.h"
63 #include "vm/jit/reg.h"
64 #include "vm/jit/replace.h"
65 #include "vm/jit/stacktrace.h"
67 #if defined(ENABLE_LSRA)
68 # include "vm/jit/allocator/lsra.h"
71 #include "vmcore/loader.h"
72 #include "vmcore/options.h"
75 /* codegen_emit ****************************************************************
77 Generates machine code.
79 *******************************************************************************/
81 bool codegen_emit(jitdata *jd)
87 s4 len, s1, s2, s3, d, disp;
93 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
94 unresolved_method *um;
95 builtintable_entry *bte;
102 /* get required compiler data */
109 /* prevent compiler warnings */
122 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
124 /* space to save used callee saved registers */
126 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
127 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
129 cd->stackframesize = rd->memuse + savedregs_num;
131 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
132 if (checksync && (m->flags & ACC_SYNCHRONIZED))
133 cd->stackframesize++;
136 /* create method header */
139 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
142 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
143 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
145 #if defined(ENABLE_THREADS)
146 /* IsSync contains the offset relative to the stack pointer for the
147 argument of monitor_exit used in the exception handler. Since the
148 offset could be zero and give a wrong meaning of the flag it is
152 if (checksync && (m->flags & ACC_SYNCHRONIZED))
153 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
156 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
158 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
159 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
160 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
162 dseg_addlinenumbertablesize(cd);
164 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
166 /* create exception table */
168 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
169 dseg_add_target(cd, ex->start);
170 dseg_add_target(cd, ex->end);
171 dseg_add_target(cd, ex->handler);
172 (void) dseg_add_unique_address(cd, ex->catchtype.any);
175 /* create stack frame (if necessary) */
177 if (cd->stackframesize)
178 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
180 /* save return address and used callee saved registers */
182 p = cd->stackframesize;
183 if (!jd->isleafmethod) {
184 p--; M_AST(REG_RA, REG_SP, p * 8);
186 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
187 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
189 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
193 /* take arguments out of register or stack frame */
197 for (p = 0, l = 0; p < md->paramcount; p++) {
198 t = md->paramtypes[p].type;
200 varindex = jd->local_map[l * 5 + t];
203 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
206 if (varindex == UNUSED)
211 s1 = md->params[p].regoff;
213 if (IS_INT_LNG_TYPE(t)) { /* integer args */
214 if (!md->params[p].inmemory) { /* register arguments */
215 if (!IS_INMEMORY(var->flags))
216 M_INTMOVE(s1, var->vv.regoff);
218 M_LST(s1, REG_SP, var->vv.regoff);
220 else { /* stack arguments */
221 if (!IS_INMEMORY(var->flags))
222 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
224 var->vv.regoff = cd->stackframesize * 8 + s1;
227 else { /* floating args */
228 if (!md->params[p].inmemory) { /* register arguments */
229 if (!IS_INMEMORY(var->flags))
230 M_FLTMOVE(s1, var->vv.regoff);
232 M_DST(s1, REG_SP, var->vv.regoff * 8);
234 else { /* stack arguments */
235 if (!(var->flags & INMEMORY))
236 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
238 var->vv.regoff = cd->stackframesize * 8 + s1;
243 /* call monitorenter function */
245 #if defined(ENABLE_THREADS)
246 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
247 /* stack offset for monitor argument */
252 if (opt_verbosecall) {
253 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
255 for (p = 0; p < INT_ARG_CNT; p++)
256 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
258 for (p = 0; p < FLT_ARG_CNT; p++)
259 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
261 s1 += INT_ARG_CNT + FLT_ARG_CNT;
263 #endif /* !defined(NDEBUG) */
265 /* decide which monitor enter function to call */
267 if (m->flags & ACC_STATIC) {
268 disp = dseg_add_address(cd, &m->class->object.header);
269 M_ALD(REG_A0, REG_PV, disp);
273 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
276 M_AST(REG_A0, REG_SP, s1 * 8);
277 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
278 M_ALD(REG_PV, REG_PV, disp);
279 M_JSR(REG_RA, REG_PV);
280 disp = (s4) (cd->mcodeptr - cd->mcodebase);
281 M_LDA(REG_PV, REG_RA, -disp);
284 if (opt_verbosecall) {
285 for (p = 0; p < INT_ARG_CNT; p++)
286 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
288 for (p = 0; p < FLT_ARG_CNT; p++)
289 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
291 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
293 #endif /* !defined(NDEBUG) */
297 /* call trace function */
300 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
301 emit_verbosecall_enter(jd);
306 /* end of header generation */
308 /* create replacement points */
310 REPLACEMENT_POINTS_INIT(cd, jd);
312 /* walk through all basic blocks */
314 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
316 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
318 if (bptr->flags >= BBREACHED) {
320 /* branch resolving */
322 codegen_resolve_branchrefs(cd, bptr);
324 /* handle replacement points */
326 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
328 /* copy interface registers to their destination */
332 #if defined(ENABLE_LSRA)
336 src = bptr->invars[len];
337 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
338 /* d = reg_of_var(m, src, REG_ITMP1); */
339 if (!(src->flags & INMEMORY))
343 M_INTMOVE(REG_ITMP1, d);
344 emit_store(jd, NULL, src, d);
351 var = VAR(bptr->invars[len]);
352 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
353 d = codegen_reg_of_var(0, var, REG_ITMP1);
354 M_INTMOVE(REG_ITMP1, d);
355 emit_store(jd, NULL, var, d);
358 assert((var->flags & INOUT));
361 #if defined(ENABLE_LSRA)
365 /* walk through all instructions */
369 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
370 if (iptr->line != currentline) {
371 dseg_addlinenumber(cd, iptr->line);
372 currentline = iptr->line;
375 MCODECHECK(64); /* an instruction usually needs < 64 words */
378 case ICMD_NOP: /* ... ==> ... */
379 case ICMD_POP: /* ..., value ==> ... */
380 case ICMD_POP2: /* ..., value, value ==> ... */
383 case ICMD_INLINE_START:
385 REPLACEMENT_POINT_INLINE_START(cd, iptr);
388 case ICMD_INLINE_BODY:
390 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
391 dseg_addlinenumber_inline_start(cd, iptr);
392 dseg_addlinenumber(cd, iptr->line);
395 case ICMD_INLINE_END:
397 dseg_addlinenumber_inline_end(cd, iptr);
398 dseg_addlinenumber(cd, iptr->line);
401 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
403 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
404 emit_nullpointer_check(cd, iptr, s1);
407 /* constant operations ************************************************/
409 case ICMD_ICONST: /* ... ==> ..., constant */
411 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
412 ICONST(d, iptr->sx.val.i);
413 emit_store_dst(jd, iptr, d);
416 case ICMD_LCONST: /* ... ==> ..., constant */
418 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
419 LCONST(d, iptr->sx.val.l);
420 emit_store_dst(jd, iptr, d);
423 case ICMD_FCONST: /* ... ==> ..., constant */
425 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
426 disp = dseg_add_float(cd, iptr->sx.val.f);
427 M_FLD(d, REG_PV, disp);
428 emit_store_dst(jd, iptr, d);
431 case ICMD_DCONST: /* ... ==> ..., constant */
433 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
434 disp = dseg_add_double(cd, iptr->sx.val.d);
435 M_DLD(d, REG_PV, disp);
436 emit_store_dst(jd, iptr, d);
439 case ICMD_ACONST: /* ... ==> ..., constant */
441 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
443 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
444 constant_classref *cr = iptr->sx.val.c.ref;
446 disp = dseg_add_unique_address(cd, cr);
448 /* XXX Only add the patcher, if this position needs to
449 be patched. If there was a previous position which
450 resolved the same class, the returned displacement
451 of dseg_add_address is ok to use. */
453 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
456 M_ALD(d, REG_PV, disp);
459 if (iptr->sx.val.anyptr == NULL)
460 M_INTMOVE(REG_ZERO, d);
462 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
463 M_ALD(d, REG_PV, disp);
466 emit_store_dst(jd, iptr, d);
470 /* load/store/move/copy operations ************************************/
472 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
473 case ICMD_ALOAD: /* s1 = local variable */
477 case ICMD_ISTORE: /* ..., value ==> ... */
489 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
494 /* integer operations *************************************************/
496 case ICMD_INEG: /* ..., value ==> ..., - value */
498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
499 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
500 M_ISUB(REG_ZERO, s1, d);
501 emit_store_dst(jd, iptr, d);
504 case ICMD_LNEG: /* ..., value ==> ..., - value */
506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
508 M_LSUB(REG_ZERO, s1, d);
509 emit_store_dst(jd, iptr, d);
512 case ICMD_I2L: /* ..., value ==> ..., value */
514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
517 emit_store_dst(jd, iptr, d);
520 case ICMD_L2I: /* ..., value ==> ..., value */
522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
524 M_IADD(s1, REG_ZERO, d);
525 emit_store_dst(jd, iptr, d);
528 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
532 if (has_ext_instr_set) {
535 M_SLL_IMM(s1, 56, d);
536 M_SRA_IMM( d, 56, d);
538 emit_store_dst(jd, iptr, d);
541 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
546 emit_store_dst(jd, iptr, d);
549 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
553 if (has_ext_instr_set) {
556 M_SLL_IMM(s1, 48, d);
557 M_SRA_IMM( d, 48, d);
559 emit_store_dst(jd, iptr, d);
563 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
566 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
569 emit_store_dst(jd, iptr, d);
573 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
574 /* sx.val.i = constant */
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
579 M_IADD_IMM(s1, iptr->sx.val.i, d);
580 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
581 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
583 /* XXX maybe use M_LDA? */
584 ICONST(REG_ITMP2, iptr->sx.val.i);
585 M_IADD(s1, REG_ITMP2, d);
587 emit_store_dst(jd, iptr, d);
590 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
596 emit_store_dst(jd, iptr, d);
599 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
600 /* sx.val.l = constant */
602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
604 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
605 M_LADD_IMM(s1, iptr->sx.val.l, d);
607 LCONST(REG_ITMP2, iptr->sx.val.l);
608 M_LADD(s1, REG_ITMP2, d);
610 emit_store_dst(jd, iptr, d);
613 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
617 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
619 emit_store_dst(jd, iptr, d);
622 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
623 /* sx.val.i = constant */
625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
628 M_ISUB_IMM(s1, iptr->sx.val.i, d);
630 ICONST(REG_ITMP2, iptr->sx.val.i);
631 M_ISUB(s1, REG_ITMP2, d);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
639 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
642 emit_store_dst(jd, iptr, d);
645 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
646 /* sx.val.l = constant */
648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
651 M_LSUB_IMM(s1, iptr->sx.val.l, d);
653 LCONST(REG_ITMP2, iptr->sx.val.l);
654 M_LSUB(s1, REG_ITMP2, d);
656 emit_store_dst(jd, iptr, d);
659 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
665 emit_store_dst(jd, iptr, d);
668 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
669 /* sx.val.i = constant */
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
673 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
674 M_IMUL_IMM(s1, iptr->sx.val.i, d);
676 ICONST(REG_ITMP2, iptr->sx.val.i);
677 M_IMUL(s1, REG_ITMP2, d);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688 emit_store_dst(jd, iptr, d);
691 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
692 /* sx.val.l = constant */
694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
696 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
697 M_LMUL_IMM(s1, iptr->sx.val.l, d);
699 LCONST(REG_ITMP2, iptr->sx.val.l);
700 M_LMUL(s1, REG_ITMP2, d);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
706 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
708 s1 = emit_load_s1(jd, iptr, REG_A0);
709 s2 = emit_load_s2(jd, iptr, REG_A1);
710 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
711 emit_arithmetic_check(cd, iptr, s2);
713 M_INTMOVE(s1, REG_A0);
714 M_INTMOVE(s2, REG_A1);
715 bte = iptr->sx.s23.s3.bte;
716 disp = dseg_add_functionptr(cd, bte->fp);
717 M_ALD(REG_PV, REG_PV, disp);
718 M_JSR(REG_RA, REG_PV);
719 disp = (s4) (cd->mcodeptr - cd->mcodebase);
720 M_LDA(REG_PV, REG_RA, -disp);
722 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
723 emit_store_dst(jd, iptr, d);
726 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
727 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
729 s1 = emit_load_s1(jd, iptr, REG_A0);
730 s2 = emit_load_s2(jd, iptr, REG_A1);
731 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
732 emit_arithmetic_check(cd, iptr, s2);
734 M_INTMOVE(s1, REG_A0);
735 M_INTMOVE(s2, REG_A1);
736 bte = iptr->sx.s23.s3.bte;
737 disp = dseg_add_functionptr(cd, bte->fp);
738 M_ALD(REG_PV, REG_PV, disp);
739 M_JSR(REG_RA, REG_PV);
740 disp = (s4) (cd->mcodeptr - cd->mcodebase);
741 M_LDA(REG_PV, REG_RA, -disp);
743 M_INTMOVE(REG_RESULT, d);
744 emit_store_dst(jd, iptr, d);
747 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
748 case ICMD_LDIVPOW2: /* val.i = constant */
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
752 if (iptr->sx.val.i <= 15) {
753 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
754 M_CMOVGE(s1, s1, REG_ITMP2);
756 M_SRA_IMM(s1, 63, REG_ITMP2);
757 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
758 M_LADD(s1, REG_ITMP2, REG_ITMP2);
760 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
761 emit_store_dst(jd, iptr, d);
764 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
769 M_AND_IMM(s2, 0x1f, REG_ITMP3);
770 M_SLL(s1, REG_ITMP3, d);
771 M_IADD(d, REG_ZERO, d);
772 emit_store_dst(jd, iptr, d);
775 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
776 /* sx.val.i = constant */
778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
780 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
781 M_IADD(d, REG_ZERO, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_ISHR: /* ..., 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);
791 M_SRA(s1, REG_ITMP3, d);
792 emit_store_dst(jd, iptr, d);
795 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
796 /* sx.val.i = constant */
798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
800 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
801 emit_store_dst(jd, iptr, d);
804 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809 M_AND_IMM(s2, 0x1f, REG_ITMP2);
811 M_SRL(d, REG_ITMP2, d);
812 M_IADD(d, REG_ZERO, d);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
817 /* sx.val.i = constant */
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
822 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
823 M_IADD(d, REG_ZERO, d);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
830 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
837 /* sx.val.i = constant */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_LUSHR: /* ..., 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_LUSHRCONST: /* ..., 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 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
885 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
888 emit_store_dst(jd, iptr, d);
891 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
892 /* sx.val.i = constant */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
897 M_AND_IMM(s1, iptr->sx.val.i, d);
898 } else if (iptr->sx.val.i == 0xffff) {
900 } else if (iptr->sx.val.i == 0xffffff) {
901 M_ZAPNOT_IMM(s1, 0x07, d);
903 ICONST(REG_ITMP2, iptr->sx.val.i);
904 M_AND(s1, REG_ITMP2, d);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
910 /* sx.val.i = constant */
912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 M_MOV(s1, REG_ITMP1);
918 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
919 M_AND_IMM(s1, iptr->sx.val.i, d);
921 M_ISUB(REG_ZERO, s1, d);
922 M_AND_IMM(d, iptr->sx.val.i, d);
923 } else if (iptr->sx.val.i == 0xffff) {
926 M_ISUB(REG_ZERO, s1, d);
928 } else if (iptr->sx.val.i == 0xffffff) {
929 M_ZAPNOT_IMM(s1, 0x07, d);
931 M_ISUB(REG_ZERO, s1, d);
932 M_ZAPNOT_IMM(d, 0x07, d);
934 ICONST(REG_ITMP2, iptr->sx.val.i);
935 M_AND(s1, REG_ITMP2, d);
937 M_ISUB(REG_ZERO, s1, d);
938 M_AND(d, REG_ITMP2, d);
940 M_ISUB(REG_ZERO, d, d);
941 emit_store_dst(jd, iptr, d);
944 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
945 /* sx.val.l = constant */
947 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
948 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
949 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
950 M_AND_IMM(s1, iptr->sx.val.l, d);
951 } else if (iptr->sx.val.l == 0xffffL) {
953 } else if (iptr->sx.val.l == 0xffffffL) {
954 M_ZAPNOT_IMM(s1, 0x07, d);
955 } else if (iptr->sx.val.l == 0xffffffffL) {
957 } else if (iptr->sx.val.l == 0xffffffffffL) {
958 M_ZAPNOT_IMM(s1, 0x1f, d);
959 } else if (iptr->sx.val.l == 0xffffffffffffL) {
960 M_ZAPNOT_IMM(s1, 0x3f, d);
961 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
962 M_ZAPNOT_IMM(s1, 0x7f, d);
964 LCONST(REG_ITMP2, iptr->sx.val.l);
965 M_AND(s1, REG_ITMP2, d);
967 emit_store_dst(jd, iptr, d);
970 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
971 /* sx.val.l = constant */
973 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
976 M_MOV(s1, REG_ITMP1);
979 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
980 M_AND_IMM(s1, iptr->sx.val.l, d);
982 M_LSUB(REG_ZERO, s1, d);
983 M_AND_IMM(d, iptr->sx.val.l, d);
984 } else if (iptr->sx.val.l == 0xffffL) {
987 M_LSUB(REG_ZERO, s1, d);
989 } else if (iptr->sx.val.l == 0xffffffL) {
990 M_ZAPNOT_IMM(s1, 0x07, d);
992 M_LSUB(REG_ZERO, s1, d);
993 M_ZAPNOT_IMM(d, 0x07, d);
994 } else if (iptr->sx.val.l == 0xffffffffL) {
997 M_LSUB(REG_ZERO, s1, d);
999 } else if (iptr->sx.val.l == 0xffffffffffL) {
1000 M_ZAPNOT_IMM(s1, 0x1f, d);
1002 M_LSUB(REG_ZERO, s1, d);
1003 M_ZAPNOT_IMM(d, 0x1f, d);
1004 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1005 M_ZAPNOT_IMM(s1, 0x3f, d);
1007 M_LSUB(REG_ZERO, s1, d);
1008 M_ZAPNOT_IMM(d, 0x3f, d);
1009 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1010 M_ZAPNOT_IMM(s1, 0x7f, d);
1012 M_LSUB(REG_ZERO, s1, d);
1013 M_ZAPNOT_IMM(d, 0x7f, d);
1015 LCONST(REG_ITMP2, iptr->sx.val.l);
1016 M_AND(s1, REG_ITMP2, d);
1018 M_LSUB(REG_ZERO, s1, d);
1019 M_AND(d, REG_ITMP2, d);
1021 M_LSUB(REG_ZERO, d, d);
1022 emit_store_dst(jd, iptr, d);
1025 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1028 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1029 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1030 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1036 /* sx.val.i = constant */
1038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1039 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1040 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1041 M_OR_IMM(s1, iptr->sx.val.i, d);
1043 ICONST(REG_ITMP2, iptr->sx.val.i);
1044 M_OR(s1, REG_ITMP2, d);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1050 /* sx.val.l = constant */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1055 M_OR_IMM(s1, iptr->sx.val.l, d);
1057 LCONST(REG_ITMP2, iptr->sx.val.l);
1058 M_OR(s1, REG_ITMP2, d);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1068 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1074 /* sx.val.i = constant */
1076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1078 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1079 M_XOR_IMM(s1, iptr->sx.val.i, d);
1081 ICONST(REG_ITMP2, iptr->sx.val.i);
1082 M_XOR(s1, REG_ITMP2, d);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1088 /* sx.val.l = constant */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1092 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1093 M_XOR_IMM(s1, iptr->sx.val.l, d);
1095 LCONST(REG_ITMP2, iptr->sx.val.l);
1096 M_XOR(s1, REG_ITMP2, d);
1098 emit_store_dst(jd, iptr, d);
1102 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1106 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1107 M_CMPLT(s1, s2, REG_ITMP3);
1108 M_CMPLT(s2, s1, REG_ITMP1);
1109 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1110 emit_store_dst(jd, iptr, d);
1114 /* floating operations ************************************************/
1116 case ICMD_FNEG: /* ..., value ==> ..., - value */
1118 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1119 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1121 emit_store_dst(jd, iptr, d);
1124 case ICMD_DNEG: /* ..., value ==> ..., - value */
1126 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1127 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1129 emit_store_dst(jd, iptr, d);
1132 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1134 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1135 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1136 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1140 if (d == s1 || d == s2) {
1141 M_FADDS(s1, s2, REG_FTMP3);
1143 M_FMOV(REG_FTMP3, d);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1154 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1155 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1160 if (d == s1 || d == s2) {
1161 M_DADDS(s1, s2, REG_FTMP3);
1163 M_FMOV(REG_FTMP3, d);
1169 emit_store_dst(jd, iptr, d);
1172 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1174 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1175 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1176 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1180 if (d == s1 || d == s2) {
1181 M_FSUBS(s1, s2, REG_FTMP3);
1183 M_FMOV(REG_FTMP3, d);
1189 emit_store_dst(jd, iptr, d);
1192 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1194 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1195 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1200 if (d == s1 || d == s2) {
1201 M_DSUBS(s1, s2, REG_FTMP3);
1203 M_FMOV(REG_FTMP3, d);
1209 emit_store_dst(jd, iptr, d);
1212 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1214 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1215 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1216 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1220 if (d == s1 || d == s2) {
1221 M_FMULS(s1, s2, REG_FTMP3);
1223 M_FMOV(REG_FTMP3, d);
1229 emit_store_dst(jd, iptr, d);
1232 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1234 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1235 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1236 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1240 if (d == s1 || d == s2) {
1241 M_DMULS(s1, s2, REG_FTMP3);
1243 M_FMOV(REG_FTMP3, d);
1249 emit_store_dst(jd, iptr, d);
1252 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1254 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1255 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1256 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1260 if (d == s1 || d == s2) {
1261 M_FDIVS(s1, s2, REG_FTMP3);
1263 M_FMOV(REG_FTMP3, d);
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1274 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1275 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1276 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1280 if (d == s1 || d == s2) {
1281 M_DDIVS(s1, s2, REG_FTMP3);
1283 M_FMOV(REG_FTMP3, d);
1289 emit_store_dst(jd, iptr, d);
1292 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1295 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 disp = dseg_add_unique_double(cd, 0.0);
1297 M_LST(s1, REG_PV, disp);
1298 M_DLD(d, REG_PV, disp);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1306 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1307 disp = dseg_add_unique_double(cd, 0.0);
1308 M_LST(s1, REG_PV, disp);
1309 M_DLD(d, REG_PV, disp);
1311 emit_store_dst(jd, iptr, d);
1314 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1316 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1317 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1318 disp = dseg_add_unique_double(cd, 0.0);
1319 M_CVTDL_C(s1, REG_FTMP2);
1320 M_CVTLI(REG_FTMP2, REG_FTMP3);
1321 M_DST(REG_FTMP3, REG_PV, disp);
1322 M_ILD(d, REG_PV, disp);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1328 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1329 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1330 disp = dseg_add_unique_double(cd, 0.0);
1331 M_CVTDL_C(s1, REG_FTMP2);
1332 M_DST(REG_FTMP2, REG_PV, disp);
1333 M_LLD(d, REG_PV, disp);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1339 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1343 emit_store_dst(jd, iptr, d);
1346 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1348 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1349 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1356 emit_store_dst(jd, iptr, d);
1359 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1361 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1362 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1363 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1365 M_LSUB_IMM(REG_ZERO, 1, d);
1366 M_FCMPEQ(s1, s2, REG_FTMP3);
1367 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1369 M_FCMPLT(s2, s1, REG_FTMP3);
1370 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1371 M_LADD_IMM(REG_ZERO, 1, d);
1373 M_LSUB_IMM(REG_ZERO, 1, d);
1374 M_FCMPEQS(s1, s2, REG_FTMP3);
1376 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1378 M_FCMPLTS(s2, s1, REG_FTMP3);
1380 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1381 M_LADD_IMM(REG_ZERO, 1, d);
1383 emit_store_dst(jd, iptr, d);
1386 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1388 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1389 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1392 M_LADD_IMM(REG_ZERO, 1, d);
1393 M_FCMPEQ(s1, s2, REG_FTMP3);
1394 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1396 M_FCMPLT(s1, s2, REG_FTMP3);
1397 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1398 M_LSUB_IMM(REG_ZERO, 1, d);
1400 M_LADD_IMM(REG_ZERO, 1, d);
1401 M_FCMPEQS(s1, s2, REG_FTMP3);
1403 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1405 M_FCMPLTS(s1, s2, REG_FTMP3);
1407 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1408 M_LSUB_IMM(REG_ZERO, 1, d);
1410 emit_store_dst(jd, iptr, d);
1414 /* memory operations **************************************************/
1416 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1418 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1420 /* implicit null-pointer check */
1421 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1422 emit_store_dst(jd, iptr, d);
1425 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1427 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1428 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1429 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1430 /* implicit null-pointer check */
1431 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1432 if (has_ext_instr_set) {
1433 M_LADD(s2, s1, REG_ITMP1);
1434 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1438 M_LADD(s2, s1, REG_ITMP1);
1439 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1440 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1441 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1442 M_SRA_IMM(d, 56, d);
1444 emit_store_dst(jd, iptr, d);
1447 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1452 /* implicit null-pointer check */
1453 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1454 if (has_ext_instr_set) {
1455 M_LADD(s2, s1, REG_ITMP1);
1456 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1457 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1460 M_LADD (s2, s1, REG_ITMP1);
1461 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1462 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1463 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1464 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1466 emit_store_dst(jd, iptr, d);
1469 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1471 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1474 /* implicit null-pointer check */
1475 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1476 if (has_ext_instr_set) {
1477 M_LADD(s2, s1, REG_ITMP1);
1478 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1479 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1482 M_LADD(s2, s1, REG_ITMP1);
1483 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1484 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1485 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1486 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1487 M_SRA_IMM(d, 48, d);
1489 emit_store_dst(jd, iptr, d);
1492 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1494 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1495 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1496 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1497 /* implicit null-pointer check */
1498 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1499 M_S4ADDQ(s2, s1, REG_ITMP1);
1500 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1501 emit_store_dst(jd, iptr, d);
1504 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1507 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1509 /* implicit null-pointer check */
1510 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1511 M_S8ADDQ(s2, s1, REG_ITMP1);
1512 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1513 emit_store_dst(jd, iptr, d);
1516 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1519 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1520 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1521 /* implicit null-pointer check */
1522 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1523 M_S4ADDQ(s2, s1, REG_ITMP1);
1524 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1525 emit_store_dst(jd, iptr, d);
1528 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1533 /* implicit null-pointer check */
1534 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1535 M_S8ADDQ(s2, s1, REG_ITMP1);
1536 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1537 emit_store_dst(jd, iptr, d);
1540 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1543 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1544 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1545 /* implicit null-pointer check */
1546 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1547 M_SAADDQ(s2, s1, REG_ITMP1);
1548 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1549 emit_store_dst(jd, iptr, d);
1553 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1556 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1557 /* implicit null-pointer check */
1558 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1559 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1560 if (has_ext_instr_set) {
1561 M_LADD(s2, s1, REG_ITMP1);
1562 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1565 M_LADD(s2, s1, REG_ITMP1);
1566 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1567 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1568 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1569 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1570 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1571 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1575 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1578 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1579 /* implicit null-pointer check */
1580 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1581 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1582 if (has_ext_instr_set) {
1583 M_LADD(s2, s1, REG_ITMP1);
1584 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1585 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1588 M_LADD(s2, s1, REG_ITMP1);
1589 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1590 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1591 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1592 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1593 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1594 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1595 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1599 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1602 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1603 /* implicit null-pointer check */
1604 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1605 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1606 if (has_ext_instr_set) {
1607 M_LADD(s2, s1, REG_ITMP1);
1608 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1609 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1612 M_LADD(s2, s1, REG_ITMP1);
1613 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1614 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1615 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1616 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1617 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1618 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1619 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1623 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1626 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1627 /* implicit null-pointer check */
1628 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1629 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1630 M_S4ADDQ(s2, s1, REG_ITMP1);
1631 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1634 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1637 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1638 /* implicit null-pointer check */
1639 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1640 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1641 M_S8ADDQ(s2, s1, REG_ITMP1);
1642 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1645 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1649 /* implicit null-pointer check */
1650 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1651 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1652 M_S4ADDQ(s2, s1, REG_ITMP1);
1653 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1656 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1659 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1660 /* implicit null-pointer check */
1661 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1662 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1663 M_S8ADDQ(s2, s1, REG_ITMP1);
1664 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1667 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1669 s1 = emit_load_s1(jd, iptr, REG_A0);
1670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1671 /* implicit null-pointer check */
1672 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1673 s3 = emit_load_s3(jd, iptr, REG_A1);
1675 M_INTMOVE(s1, REG_A0);
1676 M_INTMOVE(s3, REG_A1);
1678 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1679 M_ALD(REG_PV, REG_PV, disp);
1680 M_JSR(REG_RA, REG_PV);
1681 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1682 M_LDA(REG_PV, REG_RA, -disp);
1683 emit_exception_check(cd, iptr);
1685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1688 M_SAADDQ(s2, s1, REG_ITMP1);
1689 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1693 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 /* implicit null-pointer check */
1698 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1699 if (has_ext_instr_set) {
1700 M_LADD(s2, s1, REG_ITMP1);
1701 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1704 M_LADD(s2, s1, REG_ITMP1);
1705 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1706 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1707 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1708 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1709 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1710 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1714 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1717 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1718 /* implicit null-pointer check */
1719 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1720 if (has_ext_instr_set) {
1721 M_LADD(s2, s1, REG_ITMP1);
1722 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1723 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1726 M_LADD(s2, s1, REG_ITMP1);
1727 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1728 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1729 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1730 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1731 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1732 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1733 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1737 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1739 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1740 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1741 /* implicit null-pointer check */
1742 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1743 if (has_ext_instr_set) {
1744 M_LADD(s2, s1, REG_ITMP1);
1745 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1746 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1749 M_LADD(s2, s1, REG_ITMP1);
1750 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1751 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1752 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1753 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1754 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1755 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1756 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1760 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1763 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1764 /* implicit null-pointer check */
1765 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1766 M_S4ADDQ(s2, s1, REG_ITMP1);
1767 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1770 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1774 /* implicit null-pointer check */
1775 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1776 M_S8ADDQ(s2, s1, REG_ITMP1);
1777 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1780 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1784 /* implicit null-pointer check */
1785 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1786 M_SAADDQ(s2, s1, REG_ITMP1);
1787 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1791 case ICMD_GETSTATIC: /* ... ==> ..., value */
1793 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1794 uf = iptr->sx.s23.s3.uf;
1795 fieldtype = uf->fieldref->parseddesc.fd->type;
1796 disp = dseg_add_unique_address(cd, uf);
1798 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1801 fi = iptr->sx.s23.s3.fmiref->p.field;
1802 fieldtype = fi->type;
1803 disp = dseg_add_address(cd, &(fi->value));
1805 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1806 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1810 M_ALD(REG_ITMP1, REG_PV, disp);
1811 switch (fieldtype) {
1813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1814 M_ILD(d, REG_ITMP1, 0);
1817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1818 M_LLD(d, REG_ITMP1, 0);
1821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1822 M_ALD(d, REG_ITMP1, 0);
1825 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1826 M_FLD(d, REG_ITMP1, 0);
1829 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1830 M_DLD(d, REG_ITMP1, 0);
1833 emit_store_dst(jd, iptr, d);
1836 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1838 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1839 uf = iptr->sx.s23.s3.uf;
1840 fieldtype = uf->fieldref->parseddesc.fd->type;
1841 disp = dseg_add_unique_address(cd, uf);
1843 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1846 fi = iptr->sx.s23.s3.fmiref->p.field;
1847 fieldtype = fi->type;
1848 disp = dseg_add_address(cd, &(fi->value));
1850 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1851 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1855 M_ALD(REG_ITMP1, REG_PV, disp);
1856 switch (fieldtype) {
1858 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1859 M_IST(s1, REG_ITMP1, 0);
1862 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1863 M_LST(s1, REG_ITMP1, 0);
1866 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1867 M_AST(s1, REG_ITMP1, 0);
1870 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1871 M_FST(s1, REG_ITMP1, 0);
1874 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1875 M_DST(s1, REG_ITMP1, 0);
1880 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1881 /* val = value (in current instruction) */
1882 /* following NOP) */
1884 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1885 uf = iptr->sx.s23.s3.uf;
1886 fieldtype = uf->fieldref->parseddesc.fd->type;
1887 disp = dseg_add_unique_address(cd, uf);
1889 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1892 fi = iptr->sx.s23.s3.fmiref->p.field;
1893 fieldtype = fi->type;
1894 disp = dseg_add_address(cd, &(fi->value));
1896 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1897 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1901 M_ALD(REG_ITMP1, REG_PV, disp);
1902 switch (fieldtype) {
1904 M_IST(REG_ZERO, REG_ITMP1, 0);
1907 M_LST(REG_ZERO, REG_ITMP1, 0);
1910 M_AST(REG_ZERO, REG_ITMP1, 0);
1913 M_FST(REG_ZERO, REG_ITMP1, 0);
1916 M_DST(REG_ZERO, REG_ITMP1, 0);
1922 case ICMD_GETFIELD: /* ... ==> ..., value */
1924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1926 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1927 uf = iptr->sx.s23.s3.uf;
1928 fieldtype = uf->fieldref->parseddesc.fd->type;
1931 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1934 fi = iptr->sx.s23.s3.fmiref->p.field;
1935 fieldtype = fi->type;
1939 /* implicit null-pointer check */
1940 switch (fieldtype) {
1942 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1954 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1958 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1962 emit_store_dst(jd, iptr, d);
1965 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1969 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1970 uf = iptr->sx.s23.s3.uf;
1971 fieldtype = uf->fieldref->parseddesc.fd->type;
1976 fi = iptr->sx.s23.s3.fmiref->p.field;
1977 fieldtype = fi->type;
1981 if (IS_INT_LNG_TYPE(fieldtype))
1982 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1984 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1986 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1987 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1989 /* implicit null-pointer check */
1990 switch (fieldtype) {
1992 M_IST(s2, s1, disp);
1995 M_LST(s2, s1, disp);
1998 M_AST(s2, s1, disp);
2001 M_FST(s2, s1, disp);
2004 M_DST(s2, s1, disp);
2009 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2010 /* val = value (in current instruction) */
2011 /* following NOP) */
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2015 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2016 uf = iptr->sx.s23.s3.uf;
2017 fieldtype = uf->fieldref->parseddesc.fd->type;
2020 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2023 fi = iptr->sx.s23.s3.fmiref->p.field;
2024 fieldtype = fi->type;
2028 /* implicit null-pointer check */
2029 switch (fieldtype) {
2031 M_IST(REG_ZERO, s1, disp);
2034 M_LST(REG_ZERO, s1, disp);
2037 M_AST(REG_ZERO, s1, disp);
2040 M_FST(REG_ZERO, s1, disp);
2043 M_DST(REG_ZERO, s1, disp);
2049 /* branch operations **************************************************/
2051 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2054 M_INTMOVE(s1, REG_ITMP1_XPTR);
2056 #ifdef ENABLE_VERIFIER
2057 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2058 unresolved_class *uc = iptr->sx.s23.s2.uc;
2060 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2062 #endif /* ENABLE_VERIFIER */
2064 disp = dseg_add_functionptr(cd, asm_handle_exception);
2065 M_ALD(REG_ITMP2, REG_PV, disp);
2066 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2067 M_NOP; /* nop ensures that XPC is less than the end */
2068 /* of basic block */
2072 case ICMD_GOTO: /* ... ==> ... */
2073 case ICMD_RET: /* ... ==> ... */
2075 emit_br(cd, iptr->dst.block);
2079 case ICMD_JSR: /* ... ==> ... */
2081 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2085 case ICMD_IFNULL: /* ..., value ==> ... */
2086 case ICMD_IFNONNULL:
2088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2089 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2092 case ICMD_IFEQ: /* ..., value ==> ... */
2094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2095 if (iptr->sx.val.i == 0)
2096 emit_beqz(cd, iptr->dst.block, s1);
2098 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2099 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2101 ICONST(REG_ITMP2, iptr->sx.val.i);
2102 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2104 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2108 case ICMD_IFLT: /* ..., value ==> ... */
2110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2111 if (iptr->sx.val.i == 0)
2112 emit_bltz(cd, iptr->dst.block, s1);
2114 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2115 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2117 ICONST(REG_ITMP2, iptr->sx.val.i);
2118 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2120 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2124 case ICMD_IFLE: /* ..., value ==> ... */
2126 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2127 if (iptr->sx.val.i == 0)
2128 emit_blez(cd, iptr->dst.block, s1);
2130 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2131 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2133 ICONST(REG_ITMP2, iptr->sx.val.i);
2134 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2136 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2140 case ICMD_IFNE: /* ..., value ==> ... */
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2143 if (iptr->sx.val.i == 0)
2144 emit_bnez(cd, iptr->dst.block, s1);
2146 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2147 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2149 ICONST(REG_ITMP2, iptr->sx.val.i);
2150 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2152 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2156 case ICMD_IFGT: /* ..., value ==> ... */
2158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2159 if (iptr->sx.val.i == 0)
2160 emit_bgtz(cd, iptr->dst.block, s1);
2162 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2163 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2165 ICONST(REG_ITMP2, iptr->sx.val.i);
2166 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2168 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2172 case ICMD_IFGE: /* ..., value ==> ... */
2174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2175 if (iptr->sx.val.i == 0)
2176 emit_bgez(cd, iptr->dst.block, s1);
2178 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2179 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2181 ICONST(REG_ITMP2, iptr->sx.val.i);
2182 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2184 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2188 case ICMD_IF_LEQ: /* ..., value ==> ... */
2190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2191 if (iptr->sx.val.l == 0)
2192 emit_beqz(cd, iptr->dst.block, s1);
2194 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2195 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2197 LCONST(REG_ITMP2, iptr->sx.val.l);
2198 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2200 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2204 case ICMD_IF_LLT: /* ..., value ==> ... */
2206 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2207 if (iptr->sx.val.l == 0)
2208 emit_bltz(cd, iptr->dst.block, s1);
2210 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2211 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2213 LCONST(REG_ITMP2, iptr->sx.val.l);
2214 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2216 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2220 case ICMD_IF_LLE: /* ..., value ==> ... */
2222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2223 if (iptr->sx.val.l == 0)
2224 emit_blez(cd, iptr->dst.block, s1);
2226 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2227 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2229 LCONST(REG_ITMP2, iptr->sx.val.l);
2230 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2232 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2236 case ICMD_IF_LNE: /* ..., value ==> ... */
2238 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2239 if (iptr->sx.val.l == 0)
2240 emit_bnez(cd, iptr->dst.block, s1);
2242 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2243 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2245 LCONST(REG_ITMP2, iptr->sx.val.l);
2246 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2248 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2252 case ICMD_IF_LGT: /* ..., value ==> ... */
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2255 if (iptr->sx.val.l == 0)
2256 emit_bgtz(cd, iptr->dst.block, s1);
2258 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2259 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2261 LCONST(REG_ITMP2, iptr->sx.val.l);
2262 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2264 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2268 case ICMD_IF_LGE: /* ..., value ==> ... */
2270 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2271 if (iptr->sx.val.l == 0)
2272 emit_bgez(cd, iptr->dst.block, s1);
2274 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2275 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2277 LCONST(REG_ITMP2, iptr->sx.val.l);
2278 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2280 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2284 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2285 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2286 case ICMD_IF_ACMPEQ:
2288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2289 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2290 M_CMPEQ(s1, s2, REG_ITMP1);
2291 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2294 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2295 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2296 case ICMD_IF_ACMPNE:
2298 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2299 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2300 M_CMPEQ(s1, s2, REG_ITMP1);
2301 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2304 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2305 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2308 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2309 M_CMPLT(s1, s2, REG_ITMP1);
2310 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2313 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2314 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2316 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2317 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2318 M_CMPLE(s1, s2, REG_ITMP1);
2319 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2322 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2323 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2326 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2327 M_CMPLE(s1, s2, REG_ITMP1);
2328 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2331 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2332 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2336 M_CMPLT(s1, s2, REG_ITMP1);
2337 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2341 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2344 REPLACEMENT_POINT_RETURN(cd, iptr);
2345 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2346 M_INTMOVE(s1, REG_RESULT);
2347 goto nowperformreturn;
2349 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2351 REPLACEMENT_POINT_RETURN(cd, iptr);
2352 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2353 M_INTMOVE(s1, REG_RESULT);
2355 #ifdef ENABLE_VERIFIER
2356 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2357 unresolved_class *uc = iptr->sx.s23.s2.uc;
2359 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2361 #endif /* ENABLE_VERIFIER */
2362 goto nowperformreturn;
2364 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2367 REPLACEMENT_POINT_RETURN(cd, iptr);
2368 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2369 M_FLTMOVE(s1, REG_FRESULT);
2370 goto nowperformreturn;
2372 case ICMD_RETURN: /* ... ==> ... */
2374 REPLACEMENT_POINT_RETURN(cd, iptr);
2380 p = cd->stackframesize;
2382 /* call trace function */
2384 #if !defined(NDEBUG)
2385 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2386 emit_verbosecall_exit(jd);
2389 #if defined(ENABLE_THREADS)
2390 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2391 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2393 switch (iptr->opc) {
2397 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2401 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2405 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2406 M_ALD(REG_PV, REG_PV, disp);
2407 M_JSR(REG_RA, REG_PV);
2408 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2409 M_LDA(REG_PV, REG_RA, disp);
2411 switch (iptr->opc) {
2415 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2419 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2425 /* restore return address */
2427 if (!jd->isleafmethod) {
2428 p--; M_LLD(REG_RA, REG_SP, p * 8);
2431 /* restore saved registers */
2433 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2434 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2436 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2437 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2440 /* deallocate stack */
2442 if (cd->stackframesize)
2443 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2445 M_RET(REG_ZERO, REG_RA);
2451 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2454 branch_target_t *table;
2456 table = iptr->dst.table;
2458 l = iptr->sx.s23.s2.tablelow;
2459 i = iptr->sx.s23.s3.tablehigh;
2461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2463 M_INTMOVE(s1, REG_ITMP1);
2464 } else if (l <= 32768) {
2465 M_LDA(REG_ITMP1, s1, -l);
2467 ICONST(REG_ITMP2, l);
2468 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2471 /* number of targets */
2477 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2479 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2480 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2482 emit_beqz(cd, table[0].block, REG_ITMP2);
2484 /* build jump table top down and use address of lowest entry */
2489 dseg_add_target(cd, table->block);
2494 /* length of dataseg after last dseg_add_target is used by load */
2496 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2497 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2498 M_JMP(REG_ZERO, REG_ITMP2);
2503 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2506 lookup_target_t *lookup;
2508 lookup = iptr->dst.lookup;
2510 i = iptr->sx.s23.s2.lookupcount;
2512 MCODECHECK((i<<2)+8);
2513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2516 val = lookup->value;
2517 if ((val >= 0) && (val <= 255)) {
2518 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2520 if ((val >= -32768) && (val <= 32767)) {
2521 M_LDA(REG_ITMP2, REG_ZERO, val);
2523 disp = dseg_add_s4(cd, val);
2524 M_ILD(REG_ITMP2, REG_PV, disp);
2526 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2528 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2532 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2538 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2540 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2542 bte = iptr->sx.s23.s3.bte;
2546 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2548 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2549 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2550 case ICMD_INVOKEINTERFACE:
2552 REPLACEMENT_POINT_INVOKE(cd, iptr);
2554 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2556 um = iptr->sx.s23.s3.um;
2557 md = um->methodref->parseddesc.md;
2560 lm = iptr->sx.s23.s3.fmiref->p.method;
2562 md = lm->parseddesc;
2566 s3 = md->paramcount;
2568 MCODECHECK((s3 << 1) + 64);
2570 /* copy arguments to registers or stack location */
2572 for (s3 = s3 - 1; s3 >= 0; s3--) {
2573 var = VAR(iptr->sx.s23.s2.args[s3]);
2574 d = md->params[s3].regoff;
2576 /* already preallocated (ARGVAR)? */
2578 if (var->flags & PREALLOC)
2581 if (IS_INT_LNG_TYPE(var->type)) {
2582 if (!md->params[s3].inmemory) {
2583 s1 = emit_load(jd, iptr, var, d);
2587 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2588 M_LST(s1, REG_SP, d);
2592 if (!md->params[s3].inmemory) {
2593 s1 = emit_load(jd, iptr, var, d);
2597 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2598 M_DST(s1, REG_SP, d);
2603 switch (iptr->opc) {
2605 if (bte->stub == NULL)
2606 disp = dseg_add_functionptr(cd, bte->fp);
2608 disp = dseg_add_functionptr(cd, bte->stub);
2610 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2612 /* generate the actual call */
2614 M_JSR(REG_RA, REG_PV);
2615 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2616 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2617 M_LDA(REG_PV, REG_RA, -disp);
2619 emit_exception_check(cd, iptr);
2622 case ICMD_INVOKESPECIAL:
2623 emit_nullpointer_check(cd, iptr, REG_A0);
2626 case ICMD_INVOKESTATIC:
2628 disp = dseg_add_unique_address(cd, um);
2630 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2634 disp = dseg_add_address(cd, lm->stubroutine);
2636 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2638 /* generate the actual call */
2640 M_JSR(REG_RA, REG_PV);
2641 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2642 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2643 M_LDA(REG_PV, REG_RA, -disp);
2646 case ICMD_INVOKEVIRTUAL:
2648 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2653 s1 = OFFSET(vftbl_t, table[0]) +
2654 sizeof(methodptr) * lm->vftblindex;
2656 /* implicit null-pointer check */
2657 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2658 M_ALD(REG_PV, REG_METHODPTR, s1);
2660 /* generate the actual call */
2662 M_JSR(REG_RA, REG_PV);
2663 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2664 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2665 M_LDA(REG_PV, REG_RA, -disp);
2668 case ICMD_INVOKEINTERFACE:
2670 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2676 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2677 sizeof(methodptr*) * lm->class->index;
2679 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2682 /* implicit null-pointer check */
2683 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2684 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2685 M_ALD(REG_PV, REG_METHODPTR, s2);
2687 /* generate the actual call */
2689 M_JSR(REG_RA, REG_PV);
2690 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2691 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2692 M_LDA(REG_PV, REG_RA, -disp);
2696 /* store the return value */
2698 d = md->returntype.type;
2700 if (d != TYPE_VOID) {
2701 if (IS_INT_LNG_TYPE(d)) {
2702 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2703 M_INTMOVE(REG_RESULT, s1);
2706 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2707 M_FLTMOVE(REG_FRESULT, s1);
2709 emit_store_dst(jd, iptr, s1);
2714 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2716 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2717 /* object type cast-check */
2722 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2727 super = iptr->sx.s23.s3.c.cls;
2728 superindex = super->index;
2731 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2732 CODEGEN_CRITICAL_SECTION_NEW;
2734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2736 /* if class is not resolved, check which code to call */
2738 if (super == NULL) {
2739 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2741 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2743 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2744 iptr->sx.s23.s3.c.ref,
2747 M_ILD(REG_ITMP2, REG_PV, disp);
2748 disp = dseg_add_s4(cd, ACC_INTERFACE);
2749 M_ILD(REG_ITMP3, REG_PV, disp);
2750 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2751 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2754 /* interface checkcast code */
2756 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2757 if (super == NULL) {
2758 patcher_add_patch_ref(jd,
2759 PATCHER_checkcast_interface,
2760 iptr->sx.s23.s3.c.ref,
2764 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2766 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2767 M_ILD(REG_ITMP3, REG_ITMP2,
2768 OFFSET(vftbl_t, interfacetablelength));
2769 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2770 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2772 M_ALD(REG_ITMP3, REG_ITMP2,
2773 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2774 superindex * sizeof(methodptr*)));
2775 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2778 emit_label_br(cd, BRANCH_LABEL_4);
2780 emit_label(cd, BRANCH_LABEL_3);
2783 /* class checkcast code */
2785 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2786 if (super == NULL) {
2787 emit_label(cd, BRANCH_LABEL_2);
2789 disp = dseg_add_unique_address(cd, NULL);
2791 patcher_add_patch_ref(jd,
2792 PATCHER_resolve_classref_to_vftbl,
2793 iptr->sx.s23.s3.c.ref,
2797 disp = dseg_add_address(cd, super->vftbl);
2799 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2802 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2803 M_ALD(REG_ITMP3, REG_PV, disp);
2805 CODEGEN_CRITICAL_SECTION_START;
2807 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2808 /* if (s1 != REG_ITMP1) { */
2809 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2810 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2811 /* #if defined(ENABLE_THREADS) */
2812 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2814 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2817 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2818 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2819 M_ALD(REG_ITMP3, REG_PV, disp);
2820 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2822 CODEGEN_CRITICAL_SECTION_END;
2825 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2826 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2829 emit_label(cd, BRANCH_LABEL_5);
2832 if (super == NULL) {
2833 emit_label(cd, BRANCH_LABEL_1);
2834 emit_label(cd, BRANCH_LABEL_4);
2837 d = codegen_reg_of_dst(jd, iptr, s1);
2840 /* array type cast-check */
2842 s1 = emit_load_s1(jd, iptr, REG_A0);
2843 M_INTMOVE(s1, REG_A0);
2845 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2846 disp = dseg_add_unique_address(cd, NULL);
2848 patcher_add_patch_ref(jd,
2849 PATCHER_resolve_classref_to_classinfo,
2850 iptr->sx.s23.s3.c.ref,
2854 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2856 M_ALD(REG_A1, REG_PV, disp);
2857 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2858 M_ALD(REG_PV, REG_PV, disp);
2859 M_JSR(REG_RA, REG_PV);
2860 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2861 M_LDA(REG_PV, REG_RA, -disp);
2863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2864 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2866 d = codegen_reg_of_dst(jd, iptr, s1);
2870 emit_store_dst(jd, iptr, d);
2873 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2877 vftbl_t *supervftbl;
2880 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2886 super = iptr->sx.s23.s3.c.cls;
2887 superindex = super->index;
2888 supervftbl = super->vftbl;
2891 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2892 CODEGEN_CRITICAL_SECTION_NEW;
2894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2898 M_MOV(s1, REG_ITMP1);
2902 /* if class is not resolved, check which code to call */
2904 if (super == NULL) {
2906 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2908 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2910 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2911 iptr->sx.s23.s3.c.ref, disp);
2913 M_ILD(REG_ITMP3, REG_PV, disp);
2915 disp = dseg_add_s4(cd, ACC_INTERFACE);
2916 M_ILD(REG_ITMP2, REG_PV, disp);
2917 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2918 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2921 /* interface instanceof code */
2923 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2924 if (super == NULL) {
2925 /* If d == REG_ITMP2, then it's destroyed in check
2930 patcher_add_patch_ref(jd,
2931 PATCHER_instanceof_interface,
2932 iptr->sx.s23.s3.c.ref, 0);
2936 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2939 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2940 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2941 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2942 M_BLEZ(REG_ITMP3, 2);
2943 M_ALD(REG_ITMP1, REG_ITMP1,
2944 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2945 superindex * sizeof(methodptr*)));
2946 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2949 emit_label_br(cd, BRANCH_LABEL_4);
2951 emit_label(cd, BRANCH_LABEL_3);
2954 /* class instanceof code */
2956 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2957 if (super == NULL) {
2958 emit_label(cd, BRANCH_LABEL_2);
2960 disp = dseg_add_unique_address(cd, NULL);
2962 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2963 iptr->sx.s23.s3.c.ref,
2967 disp = dseg_add_address(cd, supervftbl);
2970 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2973 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2974 M_ALD(REG_ITMP2, REG_PV, disp);
2976 CODEGEN_CRITICAL_SECTION_START;
2978 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2979 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2980 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2982 CODEGEN_CRITICAL_SECTION_END;
2984 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2985 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
2988 emit_label(cd, BRANCH_LABEL_5);
2991 if (super == NULL) {
2992 emit_label(cd, BRANCH_LABEL_1);
2993 emit_label(cd, BRANCH_LABEL_4);
2996 emit_store_dst(jd, iptr, d);
3000 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3002 /* check for negative sizes and copy sizes to stack if necessary */
3004 MCODECHECK((iptr->s1.argcount << 1) + 64);
3006 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3008 var = VAR(iptr->sx.s23.s2.args[s1]);
3010 /* copy SAVEDVAR sizes to stack */
3012 /* Already Preallocated? */
3014 if (!(var->flags & PREALLOC)) {
3015 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3016 M_LST(s2, REG_SP, s1 * 8);
3020 /* a0 = dimension count */
3022 ICONST(REG_A0, iptr->s1.argcount);
3024 /* is patcher function set? */
3026 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3027 disp = dseg_add_unique_address(cd, 0);
3029 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3030 iptr->sx.s23.s3.c.ref,
3034 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3036 /* a1 = arraydescriptor */
3038 M_ALD(REG_A1, REG_PV, disp);
3040 /* a2 = pointer to dimensions = stack pointer */
3042 M_INTMOVE(REG_SP, REG_A2);
3044 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3045 M_ALD(REG_PV, REG_PV, disp);
3046 M_JSR(REG_RA, REG_PV);
3047 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3048 M_LDA(REG_PV, REG_RA, -disp);
3050 /* check for exception before result assignment */
3052 emit_exception_check(cd, iptr);
3054 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3055 M_INTMOVE(REG_RESULT, d);
3056 emit_store_dst(jd, iptr, d);
3060 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3065 } /* for instruction */
3067 } /* if (bptr -> flags >= BBREACHED) */
3068 } /* for basic block */
3070 dseg_createlinenumbertable(cd);
3072 /* generate traps */
3074 emit_patcher_traps(jd);
3076 /* everything's ok */
3082 /* codegen_emit_stub_compiler **************************************************
3084 Emits a stub routine which calls the compiler.
3086 *******************************************************************************/
3088 void codegen_emit_stub_compiler(jitdata *jd)
3093 /* get required compiler data */
3098 /* code for the stub */
3100 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3101 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3102 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3106 /* codegen_emit_stub_builtin ***************************************************
3108 Emits a stub routine which calls a builtin function.
3110 *******************************************************************************/
3112 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
3121 /* get required compiler data */
3126 /* set some variables */
3130 /* calculate stack frame size */
3132 cd->stackframesize =
3133 1 + /* return address */
3134 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3137 /* create method header */
3139 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3140 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3141 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3142 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3143 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3144 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3145 (void) dseg_addlinenumbertablesize(cd);
3146 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3148 /* generate stub code */
3150 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3151 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3154 #if defined(ENABLE_GC_CACAO)
3155 /* Save callee saved integer registers in stackframeinfo (GC may
3156 need to recover them during a collection). */
3158 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3159 OFFSET(stackframeinfo, intregs);
3161 for (i = 0; i < INT_SAV_CNT; i++)
3162 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3165 /* save integer and float argument registers */
3167 for (i = 0; i < md->paramcount; i++) {
3168 if (!md->params[i].inmemory) {
3169 s1 = md->params[i].regoff;
3171 switch (md->paramtypes[i].type) {
3175 M_LST(s1, REG_SP, i * 8);
3179 M_DST(s1, REG_SP, i * 8);
3185 /* prepare data structures for native function call */
3187 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3188 M_MOV(REG_PV, REG_A1);
3189 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3190 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3191 disp = dseg_add_functionptr(cd, codegen_stub_builtin_enter);
3192 M_ALD(REG_PV, REG_PV, disp);
3193 M_JSR(REG_RA, REG_PV);
3194 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3195 M_LDA(REG_PV, REG_RA, -disp);
3197 /* restore integer and float argument registers */
3199 for (i = 0; i < md->paramcount; i++) {
3200 if (!md->params[i].inmemory) {
3201 s1 = md->params[i].regoff;
3203 switch (md->paramtypes[i].type) {
3207 M_LLD(s1, REG_SP, i * 8);
3211 M_DLD(s1, REG_SP, i * 8);
3217 /* do the builtin function call */
3219 disp = dseg_add_functionptr(cd, bte->fp);
3220 M_ALD(REG_PV, REG_PV, disp);
3221 M_JSR(REG_RA, REG_PV);
3222 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3223 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3225 /* save return value */
3227 switch (md->returntype.type) {
3231 M_LST(REG_RESULT, REG_SP, 0 * 8);
3235 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3241 /* remove native stackframe info */
3243 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3244 disp = dseg_add_functionptr(cd, codegen_stub_builtin_exit);
3245 M_ALD(REG_PV, REG_PV, disp);
3246 M_JSR(REG_RA, REG_PV);
3247 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3248 M_LDA(REG_PV, REG_RA, -disp);
3249 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3251 /* restore return value */
3253 switch (md->returntype.type) {
3257 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3261 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3267 #if defined(ENABLE_GC_CACAO)
3268 /* Restore callee saved integer registers from stackframeinfo (GC
3269 might have modified them during a collection). */
3271 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3272 OFFSET(stackframeinfo, intregs);
3274 for (i = 0; i < INT_SAV_CNT; i++)
3275 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3278 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3279 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3281 M_RET(REG_ZERO, REG_RA); /* return to caller */
3285 /* codegen_emit_stub_native ****************************************************
3287 Emits a stub routine which calls a native method.
3289 *******************************************************************************/
3291 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3298 s4 i, j; /* count variables */
3301 s4 funcdisp; /* displacement of the function */
3303 /* get required compiler data */
3309 /* initialize variables */
3312 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3314 /* calculate stack frame size */
3316 cd->stackframesize =
3317 1 + /* return address */
3318 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3319 sizeof(localref_table) / SIZEOF_VOID_P +
3320 1 + /* methodinfo for call trace */
3324 /* create method header */
3326 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3327 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3328 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3329 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3330 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3331 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3332 (void) dseg_addlinenumbertablesize(cd);
3333 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3335 /* generate stub code */
3337 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3338 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3340 /* call trace function */
3342 #if !defined(NDEBUG)
3343 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3344 emit_verbosecall_enter(jd);
3347 /* get function address (this must happen before the stackframeinfo) */
3349 funcdisp = dseg_add_functionptr(cd, f);
3351 #if !defined(WITH_STATIC_CLASSPATH)
3353 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3356 #if defined(ENABLE_GC_CACAO)
3357 /* Save callee saved integer registers in stackframeinfo (GC may
3358 need to recover them during a collection). */
3360 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3361 OFFSET(stackframeinfo, intregs);
3363 for (i = 0; i < INT_SAV_CNT; i++)
3364 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3367 /* save integer and float argument registers */
3369 for (i = 0; i < md->paramcount; i++) {
3370 if (!md->params[i].inmemory) {
3371 s1 = md->params[i].regoff;
3373 switch (md->paramtypes[i].type) {
3377 M_LST(s1, REG_SP, i * 8);
3381 M_DST(s1, REG_SP, i * 8);
3387 /* prepare data structures for native function call */
3389 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3390 M_MOV(REG_PV, REG_A1);
3391 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3392 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3393 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3394 M_ALD(REG_PV, REG_PV, disp);
3395 M_JSR(REG_RA, REG_PV);
3396 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3397 M_LDA(REG_PV, REG_RA, -disp);
3399 /* restore integer and float argument registers */
3401 for (i = 0; i < md->paramcount; i++) {
3402 if (!md->params[i].inmemory) {
3403 s1 = md->params[i].regoff;
3405 switch (md->paramtypes[i].type) {
3409 M_LLD(s1, REG_SP, i * 8);
3413 M_DLD(s1, REG_SP, i * 8);
3419 /* copy or spill arguments to new locations */
3421 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3422 t = md->paramtypes[i].type;
3424 if (IS_INT_LNG_TYPE(t)) {
3425 if (!md->params[i].inmemory) {
3426 s1 = md->params[i].regoff;
3427 s2 = nmd->params[j].regoff;
3429 if (!nmd->params[j].inmemory)
3432 M_LST(s1, REG_SP, s2);
3435 s1 = md->params[i].regoff + cd->stackframesize * 8;
3436 s2 = nmd->params[j].regoff;
3437 M_LLD(REG_ITMP1, REG_SP, s1);
3438 M_LST(REG_ITMP1, REG_SP, s2);
3442 if (!md->params[i].inmemory) {
3443 s1 = md->params[i].regoff;
3444 s2 = nmd->params[j].regoff;
3446 if (!nmd->params[j].inmemory)
3449 if (IS_2_WORD_TYPE(t))
3450 M_DST(s1, REG_SP, s2);
3452 M_FST(s1, REG_SP, s2);
3456 s1 = md->params[i].regoff + cd->stackframesize * 8;
3457 s2 = nmd->params[j].regoff;
3458 M_DLD(REG_FTMP1, REG_SP, s1);
3459 if (IS_2_WORD_TYPE(t))
3460 M_DST(REG_FTMP1, REG_SP, s2);
3462 M_FST(REG_FTMP1, REG_SP, s2);
3467 /* put class into second argument register */
3469 if (m->flags & ACC_STATIC) {
3470 disp = dseg_add_address(cd, m->class);
3471 M_ALD(REG_A1, REG_PV, disp);
3474 /* put env into first argument register */
3476 disp = dseg_add_address(cd, _Jv_env);
3477 M_ALD(REG_A0, REG_PV, disp);
3479 /* do the native function call */
3481 M_ALD(REG_PV, REG_PV, funcdisp);
3482 M_JSR(REG_RA, REG_PV); /* call native method */
3483 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3484 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3486 /* save return value */
3488 switch (md->returntype.type) {
3492 M_LST(REG_RESULT, REG_SP, 0 * 8);
3496 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3502 /* call finished trace */
3504 #if !defined(NDEBUG)
3505 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3506 emit_verbosecall_exit(jd);
3509 /* remove native stackframe info */
3511 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3512 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3513 M_ALD(REG_PV, REG_PV, disp);
3514 M_JSR(REG_RA, REG_PV);
3515 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3516 M_LDA(REG_PV, REG_RA, -disp);
3517 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3519 /* restore return value */
3521 switch (md->returntype.type) {
3525 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3529 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3535 #if defined(ENABLE_GC_CACAO)
3536 /* Restore callee saved integer registers from stackframeinfo (GC
3537 might have modified them during a collection). */
3539 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3540 OFFSET(stackframeinfo, intregs);
3542 for (i = 0; i < INT_SAV_CNT; i++)
3543 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3546 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3547 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3549 /* check for exception */
3551 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3552 M_RET(REG_ZERO, REG_RA); /* return to caller */
3554 /* handle exception */
3556 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3558 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3559 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3560 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3562 /* generate patcher stubs */
3564 emit_patcher_traps(jd);
3569 * These are local overrides for various environment variables in Emacs.
3570 * Please do not remove this and leave it at the end of the file, where
3571 * Emacs will automagically detect them.
3572 * ---------------------------------------------------------------------
3575 * indent-tabs-mode: t
3579 * vim:noexpandtab:sw=4:ts=4: