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 7640 2007-04-02 21:47:01Z twisti $
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 #if defined(ENABLE_THREADS)
49 # include "threads/native/lock.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/emit-common.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/parse.h"
64 #include "vm/jit/patcher.h"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/replace.h"
67 #include "vm/jit/stacktrace.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
77 /* codegen_emit ****************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen_emit(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
95 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
96 unresolved_method *um;
97 builtintable_entry *bte;
100 unresolved_field *uf;
104 /* get required compiler data */
111 /* prevent compiler warnings */
124 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
126 /* space to save used callee saved registers */
128 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
129 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
131 cd->stackframesize = rd->memuse + savedregs_num;
133 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
134 if (checksync && (m->flags & ACC_SYNCHRONIZED))
135 cd->stackframesize++;
138 /* create method header */
141 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
144 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
145 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
147 #if defined(ENABLE_THREADS)
148 /* IsSync contains the offset relative to the stack pointer for the
149 argument of monitor_exit used in the exception handler. Since the
150 offset could be zero and give a wrong meaning of the flag it is
154 if (checksync && (m->flags & ACC_SYNCHRONIZED))
155 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
158 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
160 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
161 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
162 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
164 dseg_addlinenumbertablesize(cd);
166 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
168 /* create exception table */
170 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
171 dseg_add_target(cd, ex->start);
172 dseg_add_target(cd, ex->end);
173 dseg_add_target(cd, ex->handler);
174 (void) dseg_add_unique_address(cd, ex->catchtype.any);
177 /* create stack frame (if necessary) */
179 if (cd->stackframesize)
180 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
182 /* save return address and used callee saved registers */
184 p = cd->stackframesize;
185 if (!jd->isleafmethod) {
186 p--; M_AST(REG_RA, REG_SP, p * 8);
188 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
189 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
191 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
192 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
195 /* take arguments out of register or stack frame */
199 for (p = 0, l = 0; p < md->paramcount; p++) {
200 t = md->paramtypes[p].type;
202 varindex = jd->local_map[l * 5 + t];
205 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
208 if (varindex == UNUSED)
213 s1 = md->params[p].regoff;
215 if (IS_INT_LNG_TYPE(t)) { /* integer args */
216 if (!md->params[p].inmemory) { /* register arguments */
217 s2 = rd->argintregs[s1];
218 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
219 M_INTMOVE(s2, var->vv.regoff);
221 } else { /* reg arg -> spilled */
222 M_LST(s2, REG_SP, var->vv.regoff * 8);
225 } else { /* stack arguments */
226 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
227 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
229 } else { /* stack arg -> spilled */
230 var->vv.regoff = cd->stackframesize + s1;
234 } else { /* floating args */
235 if (!md->params[p].inmemory) { /* register arguments */
236 s2 = rd->argfltregs[s1];
237 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
238 M_FLTMOVE(s2, var->vv.regoff);
240 } else { /* reg arg -> spilled */
241 M_DST(s2, REG_SP, var->vv.regoff * 8);
244 } else { /* stack arguments */
245 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
246 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
248 } else { /* stack-arg -> spilled */
249 var->vv.regoff = cd->stackframesize + s1;
255 /* call monitorenter function */
257 #if defined(ENABLE_THREADS)
258 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
259 /* stack offset for monitor argument */
264 if (opt_verbosecall) {
265 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
267 for (p = 0; p < INT_ARG_CNT; p++)
268 M_LST(rd->argintregs[p], REG_SP, p * 8);
270 for (p = 0; p < FLT_ARG_CNT; p++)
271 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
273 s1 += INT_ARG_CNT + FLT_ARG_CNT;
275 #endif /* !defined(NDEBUG) */
277 /* decide which monitor enter function to call */
279 if (m->flags & ACC_STATIC) {
280 disp = dseg_add_address(cd, &m->class->object.header);
281 M_ALD(REG_A0, REG_PV, disp);
285 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
288 M_AST(REG_A0, REG_SP, s1 * 8);
289 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
290 M_ALD(REG_PV, REG_PV, disp);
291 M_JSR(REG_RA, REG_PV);
292 disp = (s4) (cd->mcodeptr - cd->mcodebase);
293 M_LDA(REG_PV, REG_RA, -disp);
296 if (opt_verbosecall) {
297 for (p = 0; p < INT_ARG_CNT; p++)
298 M_LLD(rd->argintregs[p], REG_SP, p * 8);
300 for (p = 0; p < FLT_ARG_CNT; p++)
301 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
303 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
305 #endif /* !defined(NDEBUG) */
309 /* call trace function */
312 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
313 emit_verbosecall_enter(jd);
318 /* end of header generation */
320 /* create replacement points */
322 REPLACEMENT_POINTS_INIT(cd, jd);
324 /* walk through all basic blocks */
326 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
328 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
330 if (bptr->flags >= BBREACHED) {
332 /* branch resolving */
334 codegen_resolve_branchrefs(cd, bptr);
336 /* handle replacement points */
338 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
340 /* copy interface registers to their destination */
344 #if defined(ENABLE_LSRA)
348 src = bptr->invars[len];
349 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
350 /* d = reg_of_var(m, src, REG_ITMP1); */
351 if (!(src->flags & INMEMORY))
355 M_INTMOVE(REG_ITMP1, d);
356 emit_store(jd, NULL, src, d);
363 var = VAR(bptr->invars[len]);
364 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
365 d = codegen_reg_of_var(0, var, REG_ITMP1);
366 M_INTMOVE(REG_ITMP1, d);
367 emit_store(jd, NULL, var, d);
370 assert((var->flags & INOUT));
373 #if defined(ENABLE_LSRA)
377 /* walk through all instructions */
381 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
382 if (iptr->line != currentline) {
383 dseg_addlinenumber(cd, iptr->line);
384 currentline = iptr->line;
387 MCODECHECK(64); /* an instruction usually needs < 64 words */
390 case ICMD_NOP: /* ... ==> ... */
391 case ICMD_POP: /* ..., value ==> ... */
392 case ICMD_POP2: /* ..., value, value ==> ... */
395 case ICMD_INLINE_START:
397 REPLACEMENT_POINT_INLINE_START(cd, iptr);
400 case ICMD_INLINE_BODY:
402 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
403 dseg_addlinenumber_inline_start(cd, iptr);
404 dseg_addlinenumber(cd, iptr->line);
407 case ICMD_INLINE_END:
409 dseg_addlinenumber_inline_end(cd, iptr);
410 dseg_addlinenumber(cd, iptr->line);
413 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
415 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
416 emit_nullpointer_check(cd, iptr, s1);
419 /* constant operations ************************************************/
421 case ICMD_ICONST: /* ... ==> ..., constant */
423 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
424 ICONST(d, iptr->sx.val.i);
425 emit_store_dst(jd, iptr, d);
428 case ICMD_LCONST: /* ... ==> ..., constant */
430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
431 LCONST(d, iptr->sx.val.l);
432 emit_store_dst(jd, iptr, d);
435 case ICMD_FCONST: /* ... ==> ..., constant */
437 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
438 disp = dseg_add_float(cd, iptr->sx.val.f);
439 M_FLD(d, REG_PV, disp);
440 emit_store_dst(jd, iptr, d);
443 case ICMD_DCONST: /* ... ==> ..., constant */
445 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
446 disp = dseg_add_double(cd, iptr->sx.val.d);
447 M_DLD(d, REG_PV, disp);
448 emit_store_dst(jd, iptr, d);
451 case ICMD_ACONST: /* ... ==> ..., constant */
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
455 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
456 constant_classref *cr = iptr->sx.val.c.ref;
458 disp = dseg_add_unique_address(cd, cr);
460 /* XXX Only add the patcher, if this position needs to
461 be patched. If there was a previous position which
462 resolved the same class, the returned displacement
463 of dseg_add_address is ok to use. */
465 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
468 M_ALD(d, REG_PV, disp);
471 if (iptr->sx.val.anyptr == NULL)
472 M_INTMOVE(REG_ZERO, d);
474 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
475 M_ALD(d, REG_PV, disp);
478 emit_store_dst(jd, iptr, d);
482 /* load/store/move/copy operations ************************************/
484 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
485 case ICMD_ALOAD: /* s1 = local variable */
489 case ICMD_ISTORE: /* ..., value ==> ... */
496 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
501 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
502 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
506 /* integer operations *************************************************/
508 case ICMD_INEG: /* ..., value ==> ..., - value */
510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
512 M_ISUB(REG_ZERO, s1, d);
513 emit_store_dst(jd, iptr, d);
516 case ICMD_LNEG: /* ..., value ==> ..., - value */
518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
520 M_LSUB(REG_ZERO, s1, d);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_I2L: /* ..., value ==> ..., value */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_L2I: /* ..., value ==> ..., value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536 M_IADD(s1, REG_ZERO, d);
537 emit_store_dst(jd, iptr, d);
540 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
544 if (has_ext_instr_set) {
547 M_SLL_IMM(s1, 56, d);
548 M_SRA_IMM( d, 56, d);
550 emit_store_dst(jd, iptr, d);
553 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
558 emit_store_dst(jd, iptr, d);
561 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
565 if (has_ext_instr_set) {
568 M_SLL_IMM(s1, 48, d);
569 M_SRA_IMM( d, 48, d);
571 emit_store_dst(jd, iptr, d);
575 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
581 emit_store_dst(jd, iptr, d);
585 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
586 /* sx.val.i = constant */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
590 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
591 M_IADD_IMM(s1, iptr->sx.val.i, d);
592 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
593 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
595 /* XXX maybe use M_LDA? */
596 ICONST(REG_ITMP2, iptr->sx.val.i);
597 M_IADD(s1, REG_ITMP2, d);
599 emit_store_dst(jd, iptr, d);
602 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
605 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
612 /* sx.val.l = constant */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
616 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
617 M_LADD_IMM(s1, iptr->sx.val.l, d);
619 LCONST(REG_ITMP2, iptr->sx.val.l);
620 M_LADD(s1, REG_ITMP2, d);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
635 /* sx.val.i = constant */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
639 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
640 M_ISUB_IMM(s1, iptr->sx.val.i, d);
642 ICONST(REG_ITMP2, iptr->sx.val.i);
643 M_ISUB(s1, REG_ITMP2, d);
645 emit_store_dst(jd, iptr, d);
648 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
650 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
651 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
654 emit_store_dst(jd, iptr, d);
657 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
658 /* sx.val.l = constant */
660 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
661 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
662 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
663 M_LSUB_IMM(s1, iptr->sx.val.l, d);
665 LCONST(REG_ITMP2, iptr->sx.val.l);
666 M_LSUB(s1, REG_ITMP2, d);
668 emit_store_dst(jd, iptr, d);
671 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 emit_store_dst(jd, iptr, d);
680 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
681 /* sx.val.i = constant */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
686 M_IMUL_IMM(s1, iptr->sx.val.i, d);
688 ICONST(REG_ITMP2, iptr->sx.val.i);
689 M_IMUL(s1, REG_ITMP2, d);
691 emit_store_dst(jd, iptr, d);
694 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 emit_store_dst(jd, iptr, d);
703 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
704 /* sx.val.l = constant */
706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
708 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
709 M_LMUL_IMM(s1, iptr->sx.val.l, d);
711 LCONST(REG_ITMP2, iptr->sx.val.l);
712 M_LMUL(s1, REG_ITMP2, d);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
718 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
720 s1 = emit_load_s1(jd, iptr, REG_A0);
721 s2 = emit_load_s2(jd, iptr, REG_A1);
722 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
723 emit_arithmetic_check(cd, iptr, s2);
725 M_INTMOVE(s1, REG_A0);
726 M_INTMOVE(s2, REG_A1);
727 bte = iptr->sx.s23.s3.bte;
728 disp = dseg_add_functionptr(cd, bte->fp);
729 M_ALD(REG_PV, REG_PV, disp);
730 M_JSR(REG_RA, REG_PV);
731 disp = (s4) (cd->mcodeptr - cd->mcodebase);
732 M_LDA(REG_PV, REG_RA, -disp);
734 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
735 emit_store_dst(jd, iptr, d);
738 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
739 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
741 s1 = emit_load_s1(jd, iptr, REG_A0);
742 s2 = emit_load_s2(jd, iptr, REG_A1);
743 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
744 emit_arithmetic_check(cd, iptr, s2);
746 M_INTMOVE(s1, REG_A0);
747 M_INTMOVE(s2, REG_A1);
748 bte = iptr->sx.s23.s3.bte;
749 disp = dseg_add_functionptr(cd, bte->fp);
750 M_ALD(REG_PV, REG_PV, disp);
751 M_JSR(REG_RA, REG_PV);
752 disp = (s4) (cd->mcodeptr - cd->mcodebase);
753 M_LDA(REG_PV, REG_RA, -disp);
755 M_INTMOVE(REG_RESULT, d);
756 emit_store_dst(jd, iptr, d);
759 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
760 case ICMD_LDIVPOW2: /* val.i = constant */
762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
763 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764 if (iptr->sx.val.i <= 15) {
765 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
766 M_CMOVGE(s1, s1, REG_ITMP2);
768 M_SRA_IMM(s1, 63, REG_ITMP2);
769 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
770 M_LADD(s1, REG_ITMP2, REG_ITMP2);
772 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
773 emit_store_dst(jd, iptr, d);
776 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
780 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
781 M_AND_IMM(s2, 0x1f, REG_ITMP3);
782 M_SLL(s1, REG_ITMP3, d);
783 M_IADD(d, REG_ZERO, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
788 /* sx.val.i = constant */
790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
791 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
793 M_IADD(d, REG_ZERO, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
800 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_AND_IMM(s2, 0x1f, REG_ITMP3);
803 M_SRA(s1, REG_ITMP3, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
808 /* sx.val.i = constant */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
812 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 M_AND_IMM(s2, 0x1f, REG_ITMP2);
823 M_SRL(d, REG_ITMP2, d);
824 M_IADD(d, REG_ZERO, d);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
829 /* sx.val.i = constant */
831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
834 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
835 M_IADD(d, REG_ZERO, d);
836 emit_store_dst(jd, iptr, d);
839 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845 emit_store_dst(jd, iptr, d);
848 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
849 /* sx.val.i = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
854 emit_store_dst(jd, iptr, d);
857 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863 emit_store_dst(jd, iptr, d);
866 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
867 /* sx.val.i = constant */
869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
872 emit_store_dst(jd, iptr, d);
875 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
879 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
881 emit_store_dst(jd, iptr, d);
884 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
885 /* sx.val.i = constant */
887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
898 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900 emit_store_dst(jd, iptr, d);
903 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
904 /* sx.val.i = constant */
906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
907 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
908 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
909 M_AND_IMM(s1, iptr->sx.val.i, d);
910 } else if (iptr->sx.val.i == 0xffff) {
912 } else if (iptr->sx.val.i == 0xffffff) {
913 M_ZAPNOT_IMM(s1, 0x07, d);
915 ICONST(REG_ITMP2, iptr->sx.val.i);
916 M_AND(s1, REG_ITMP2, d);
918 emit_store_dst(jd, iptr, d);
921 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
922 /* sx.val.i = constant */
924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
927 M_MOV(s1, REG_ITMP1);
930 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
931 M_AND_IMM(s1, iptr->sx.val.i, d);
933 M_ISUB(REG_ZERO, s1, d);
934 M_AND_IMM(d, iptr->sx.val.i, d);
935 } else if (iptr->sx.val.i == 0xffff) {
938 M_ISUB(REG_ZERO, s1, d);
940 } else if (iptr->sx.val.i == 0xffffff) {
941 M_ZAPNOT_IMM(s1, 0x07, d);
943 M_ISUB(REG_ZERO, s1, d);
944 M_ZAPNOT_IMM(d, 0x07, d);
946 ICONST(REG_ITMP2, iptr->sx.val.i);
947 M_AND(s1, REG_ITMP2, d);
949 M_ISUB(REG_ZERO, s1, d);
950 M_AND(d, REG_ITMP2, d);
952 M_ISUB(REG_ZERO, d, d);
953 emit_store_dst(jd, iptr, d);
956 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
957 /* sx.val.l = constant */
959 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
960 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
961 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
962 M_AND_IMM(s1, iptr->sx.val.l, d);
963 } else if (iptr->sx.val.l == 0xffffL) {
965 } else if (iptr->sx.val.l == 0xffffffL) {
966 M_ZAPNOT_IMM(s1, 0x07, d);
967 } else if (iptr->sx.val.l == 0xffffffffL) {
969 } else if (iptr->sx.val.l == 0xffffffffffL) {
970 M_ZAPNOT_IMM(s1, 0x1f, d);
971 } else if (iptr->sx.val.l == 0xffffffffffffL) {
972 M_ZAPNOT_IMM(s1, 0x3f, d);
973 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
974 M_ZAPNOT_IMM(s1, 0x7f, d);
976 LCONST(REG_ITMP2, iptr->sx.val.l);
977 M_AND(s1, REG_ITMP2, d);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
983 /* sx.val.l = constant */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
988 M_MOV(s1, REG_ITMP1);
991 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
992 M_AND_IMM(s1, iptr->sx.val.l, d);
994 M_LSUB(REG_ZERO, s1, d);
995 M_AND_IMM(d, iptr->sx.val.l, d);
996 } else if (iptr->sx.val.l == 0xffffL) {
999 M_LSUB(REG_ZERO, s1, d);
1001 } else if (iptr->sx.val.l == 0xffffffL) {
1002 M_ZAPNOT_IMM(s1, 0x07, d);
1004 M_LSUB(REG_ZERO, s1, d);
1005 M_ZAPNOT_IMM(d, 0x07, d);
1006 } else if (iptr->sx.val.l == 0xffffffffL) {
1009 M_LSUB(REG_ZERO, s1, d);
1011 } else if (iptr->sx.val.l == 0xffffffffffL) {
1012 M_ZAPNOT_IMM(s1, 0x1f, d);
1014 M_LSUB(REG_ZERO, s1, d);
1015 M_ZAPNOT_IMM(d, 0x1f, d);
1016 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1017 M_ZAPNOT_IMM(s1, 0x3f, d);
1019 M_LSUB(REG_ZERO, s1, d);
1020 M_ZAPNOT_IMM(d, 0x3f, d);
1021 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1022 M_ZAPNOT_IMM(s1, 0x7f, d);
1024 M_LSUB(REG_ZERO, s1, d);
1025 M_ZAPNOT_IMM(d, 0x7f, d);
1027 LCONST(REG_ITMP2, iptr->sx.val.l);
1028 M_AND(s1, REG_ITMP2, d);
1030 M_LSUB(REG_ZERO, s1, d);
1031 M_AND(d, REG_ITMP2, d);
1033 M_LSUB(REG_ZERO, d, d);
1034 emit_store_dst(jd, iptr, d);
1037 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1040 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1041 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1042 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1044 emit_store_dst(jd, iptr, d);
1047 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1048 /* sx.val.i = constant */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1052 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1053 M_OR_IMM(s1, iptr->sx.val.i, d);
1055 ICONST(REG_ITMP2, iptr->sx.val.i);
1056 M_OR(s1, REG_ITMP2, d);
1058 emit_store_dst(jd, iptr, d);
1061 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1062 /* sx.val.l = constant */
1064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1065 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1066 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1067 M_OR_IMM(s1, iptr->sx.val.l, d);
1069 LCONST(REG_ITMP2, iptr->sx.val.l);
1070 M_OR(s1, REG_ITMP2, d);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1080 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1082 emit_store_dst(jd, iptr, d);
1085 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1086 /* sx.val.i = constant */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1090 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1091 M_XOR_IMM(s1, iptr->sx.val.i, d);
1093 ICONST(REG_ITMP2, iptr->sx.val.i);
1094 M_XOR(s1, REG_ITMP2, d);
1096 emit_store_dst(jd, iptr, d);
1099 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1100 /* sx.val.l = constant */
1102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1104 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1105 M_XOR_IMM(s1, iptr->sx.val.l, d);
1107 LCONST(REG_ITMP2, iptr->sx.val.l);
1108 M_XOR(s1, REG_ITMP2, d);
1110 emit_store_dst(jd, iptr, d);
1114 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1116 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1117 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1118 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119 M_CMPLT(s1, s2, REG_ITMP3);
1120 M_CMPLT(s2, s1, REG_ITMP1);
1121 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1122 emit_store_dst(jd, iptr, d);
1126 /* floating operations ************************************************/
1128 case ICMD_FNEG: /* ..., value ==> ..., - value */
1130 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_DNEG: /* ..., value ==> ..., - value */
1138 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1139 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1141 emit_store_dst(jd, iptr, d);
1144 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1146 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1147 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1148 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1152 if (d == s1 || d == s2) {
1153 M_FADDS(s1, s2, REG_FTMP3);
1155 M_FMOV(REG_FTMP3, d);
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1168 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1172 if (d == s1 || d == s2) {
1173 M_DADDS(s1, s2, REG_FTMP3);
1175 M_FMOV(REG_FTMP3, d);
1181 emit_store_dst(jd, iptr, d);
1184 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1186 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1188 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1192 if (d == s1 || d == s2) {
1193 M_FSUBS(s1, s2, REG_FTMP3);
1195 M_FMOV(REG_FTMP3, d);
1201 emit_store_dst(jd, iptr, d);
1204 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1207 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1208 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1212 if (d == s1 || d == s2) {
1213 M_DSUBS(s1, s2, REG_FTMP3);
1215 M_FMOV(REG_FTMP3, d);
1221 emit_store_dst(jd, iptr, d);
1224 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1226 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1227 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1228 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1232 if (d == s1 || d == s2) {
1233 M_FMULS(s1, s2, REG_FTMP3);
1235 M_FMOV(REG_FTMP3, d);
1241 emit_store_dst(jd, iptr, d);
1244 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1246 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1247 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1248 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1252 if (d == s1 || d == s2) {
1253 M_DMULS(s1, s2, REG_FTMP3);
1255 M_FMOV(REG_FTMP3, d);
1261 emit_store_dst(jd, iptr, d);
1264 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1266 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1267 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1268 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1272 if (d == s1 || d == s2) {
1273 M_FDIVS(s1, s2, REG_FTMP3);
1275 M_FMOV(REG_FTMP3, d);
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1286 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1287 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1288 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1292 if (d == s1 || d == s2) {
1293 M_DDIVS(s1, s2, REG_FTMP3);
1295 M_FMOV(REG_FTMP3, d);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1308 disp = dseg_add_unique_double(cd, 0.0);
1309 M_LST(s1, REG_PV, disp);
1310 M_DLD(d, REG_PV, disp);
1312 emit_store_dst(jd, iptr, d);
1315 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1318 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1319 disp = dseg_add_unique_double(cd, 0.0);
1320 M_LST(s1, REG_PV, disp);
1321 M_DLD(d, REG_PV, disp);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_F2I: /* ..., value ==> ..., (int) 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_CVTLI(REG_FTMP2, REG_FTMP3);
1333 M_DST(REG_FTMP3, REG_PV, disp);
1334 M_ILD(d, REG_PV, disp);
1335 emit_store_dst(jd, iptr, d);
1338 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1340 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1341 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1342 disp = dseg_add_unique_double(cd, 0.0);
1343 M_CVTDL_C(s1, REG_FTMP2);
1344 M_DST(REG_FTMP2, REG_PV, disp);
1345 M_LLD(d, REG_PV, disp);
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1351 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1352 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1355 emit_store_dst(jd, iptr, d);
1358 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1360 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1361 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1368 emit_store_dst(jd, iptr, d);
1371 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1373 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1374 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1377 M_LSUB_IMM(REG_ZERO, 1, d);
1378 M_FCMPEQ(s1, s2, REG_FTMP3);
1379 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1381 M_FCMPLT(s2, s1, REG_FTMP3);
1382 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1383 M_LADD_IMM(REG_ZERO, 1, d);
1385 M_LSUB_IMM(REG_ZERO, 1, d);
1386 M_FCMPEQS(s1, s2, REG_FTMP3);
1388 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1390 M_FCMPLTS(s2, s1, REG_FTMP3);
1392 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1393 M_LADD_IMM(REG_ZERO, 1, d);
1395 emit_store_dst(jd, iptr, d);
1398 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1400 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1401 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1404 M_LADD_IMM(REG_ZERO, 1, d);
1405 M_FCMPEQ(s1, s2, REG_FTMP3);
1406 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1408 M_FCMPLT(s1, s2, REG_FTMP3);
1409 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1410 M_LSUB_IMM(REG_ZERO, 1, d);
1412 M_LADD_IMM(REG_ZERO, 1, d);
1413 M_FCMPEQS(s1, s2, REG_FTMP3);
1415 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1417 M_FCMPLTS(s1, s2, REG_FTMP3);
1419 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1420 M_LSUB_IMM(REG_ZERO, 1, d);
1422 emit_store_dst(jd, iptr, d);
1426 /* memory operations **************************************************/
1428 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1432 /* implicit null-pointer check */
1433 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1439 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1441 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1442 /* implicit null-pointer check */
1443 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1444 if (has_ext_instr_set) {
1445 M_LADD(s2, s1, REG_ITMP1);
1446 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1450 M_LADD(s2, s1, REG_ITMP1);
1451 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1452 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1453 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1454 M_SRA_IMM(d, 56, d);
1456 emit_store_dst(jd, iptr, d);
1459 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1461 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1462 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1464 /* implicit null-pointer check */
1465 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1466 if (has_ext_instr_set) {
1467 M_LADD(s2, s1, REG_ITMP1);
1468 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1469 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1472 M_LADD (s2, s1, REG_ITMP1);
1473 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1474 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1475 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1476 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1478 emit_store_dst(jd, iptr, d);
1481 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1486 /* implicit null-pointer check */
1487 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1488 if (has_ext_instr_set) {
1489 M_LADD(s2, s1, REG_ITMP1);
1490 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1491 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1494 M_LADD(s2, s1, REG_ITMP1);
1495 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1496 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1497 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1498 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1499 M_SRA_IMM(d, 48, d);
1501 emit_store_dst(jd, iptr, d);
1504 case ICMD_IALOAD: /* ..., 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_S4ADDQ(s2, s1, REG_ITMP1);
1512 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1513 emit_store_dst(jd, iptr, d);
1516 case ICMD_LALOAD: /* ..., 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_ITMP2);
1521 /* implicit null-pointer check */
1522 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1523 M_S8ADDQ(s2, s1, REG_ITMP1);
1524 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1525 emit_store_dst(jd, iptr, d);
1528 case ICMD_FALOAD: /* ..., 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_S4ADDQ(s2, s1, REG_ITMP1);
1536 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1537 emit_store_dst(jd, iptr, d);
1540 case ICMD_DALOAD: /* ..., 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_FTMP2);
1545 /* implicit null-pointer check */
1546 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1547 M_S8ADDQ(s2, s1, REG_ITMP1);
1548 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1549 emit_store_dst(jd, iptr, d);
1552 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1557 /* implicit null-pointer check */
1558 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1559 M_SAADDQ(s2, s1, REG_ITMP1);
1560 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1561 emit_store_dst(jd, iptr, d);
1565 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1568 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1569 /* implicit null-pointer check */
1570 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1571 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1572 if (has_ext_instr_set) {
1573 M_LADD(s2, s1, REG_ITMP1);
1574 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1577 M_LADD(s2, s1, REG_ITMP1);
1578 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1579 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1580 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1581 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1582 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1583 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1587 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591 /* implicit null-pointer check */
1592 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1593 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1594 if (has_ext_instr_set) {
1595 M_LADD(s2, s1, REG_ITMP1);
1596 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1597 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1600 M_LADD(s2, s1, REG_ITMP1);
1601 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1602 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1603 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1604 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1605 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1606 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1607 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1611 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1614 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1615 /* implicit null-pointer check */
1616 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1617 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1618 if (has_ext_instr_set) {
1619 M_LADD(s2, s1, REG_ITMP1);
1620 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1621 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1624 M_LADD(s2, s1, REG_ITMP1);
1625 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1626 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1627 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1628 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1629 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1630 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1631 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1635 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1639 /* implicit null-pointer check */
1640 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 M_S4ADDQ(s2, s1, REG_ITMP1);
1643 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1646 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1649 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1650 /* implicit null-pointer check */
1651 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1652 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1653 M_S8ADDQ(s2, s1, REG_ITMP1);
1654 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1657 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1660 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1661 /* implicit null-pointer check */
1662 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1663 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1664 M_S4ADDQ(s2, s1, REG_ITMP1);
1665 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1668 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1671 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1672 /* implicit null-pointer check */
1673 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1674 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1675 M_S8ADDQ(s2, s1, REG_ITMP1);
1676 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1679 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1681 s1 = emit_load_s1(jd, iptr, REG_A0);
1682 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1683 /* implicit null-pointer check */
1684 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1685 s3 = emit_load_s3(jd, iptr, REG_A1);
1687 M_INTMOVE(s1, REG_A0);
1688 M_INTMOVE(s3, REG_A1);
1690 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1691 M_ALD(REG_PV, REG_PV, disp);
1692 M_JSR(REG_RA, REG_PV);
1693 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1694 M_LDA(REG_PV, REG_RA, -disp);
1695 emit_exception_check(cd, iptr);
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1699 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1700 M_SAADDQ(s2, s1, REG_ITMP1);
1701 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1705 case ICMD_BASTORECONST: /* ..., 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 if (has_ext_instr_set) {
1712 M_LADD(s2, s1, REG_ITMP1);
1713 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1716 M_LADD(s2, s1, REG_ITMP1);
1717 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1718 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1719 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1720 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1721 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1722 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1726 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1730 /* implicit null-pointer check */
1731 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1732 if (has_ext_instr_set) {
1733 M_LADD(s2, s1, REG_ITMP1);
1734 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1735 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1738 M_LADD(s2, s1, REG_ITMP1);
1739 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1740 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1741 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1742 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1743 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1744 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1745 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1749 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1753 /* implicit null-pointer check */
1754 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1755 if (has_ext_instr_set) {
1756 M_LADD(s2, s1, REG_ITMP1);
1757 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1758 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1761 M_LADD(s2, s1, REG_ITMP1);
1762 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1763 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1764 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1765 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1766 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1767 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1768 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1772 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1774 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1775 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1776 /* implicit null-pointer check */
1777 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1778 M_S4ADDQ(s2, s1, REG_ITMP1);
1779 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1782 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1786 /* implicit null-pointer check */
1787 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1788 M_S8ADDQ(s2, s1, REG_ITMP1);
1789 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1792 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1794 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1795 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1796 /* implicit null-pointer check */
1797 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1798 M_SAADDQ(s2, s1, REG_ITMP1);
1799 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1803 case ICMD_GETSTATIC: /* ... ==> ..., value */
1805 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1806 uf = iptr->sx.s23.s3.uf;
1807 fieldtype = uf->fieldref->parseddesc.fd->type;
1808 disp = dseg_add_unique_address(cd, uf);
1810 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1813 fi = iptr->sx.s23.s3.fmiref->p.field;
1814 fieldtype = fi->type;
1815 disp = dseg_add_address(cd, &(fi->value));
1817 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1818 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1822 M_ALD(REG_ITMP1, REG_PV, disp);
1823 switch (fieldtype) {
1825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1826 M_ILD(d, REG_ITMP1, 0);
1829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1830 M_LLD(d, REG_ITMP1, 0);
1833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1834 M_ALD(d, REG_ITMP1, 0);
1837 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1838 M_FLD(d, REG_ITMP1, 0);
1841 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1842 M_DLD(d, REG_ITMP1, 0);
1845 emit_store_dst(jd, iptr, d);
1848 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1850 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1851 uf = iptr->sx.s23.s3.uf;
1852 fieldtype = uf->fieldref->parseddesc.fd->type;
1853 disp = dseg_add_unique_address(cd, uf);
1855 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1858 fi = iptr->sx.s23.s3.fmiref->p.field;
1859 fieldtype = fi->type;
1860 disp = dseg_add_address(cd, &(fi->value));
1862 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1863 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1867 M_ALD(REG_ITMP1, REG_PV, disp);
1868 switch (fieldtype) {
1870 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1871 M_IST(s1, REG_ITMP1, 0);
1874 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1875 M_LST(s1, REG_ITMP1, 0);
1878 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1879 M_AST(s1, REG_ITMP1, 0);
1882 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1883 M_FST(s1, REG_ITMP1, 0);
1886 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1887 M_DST(s1, REG_ITMP1, 0);
1892 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1893 /* val = value (in current instruction) */
1894 /* following NOP) */
1896 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1897 uf = iptr->sx.s23.s3.uf;
1898 fieldtype = uf->fieldref->parseddesc.fd->type;
1899 disp = dseg_add_unique_address(cd, uf);
1901 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1904 fi = iptr->sx.s23.s3.fmiref->p.field;
1905 fieldtype = fi->type;
1906 disp = dseg_add_address(cd, &(fi->value));
1908 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1909 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1913 M_ALD(REG_ITMP1, REG_PV, disp);
1914 switch (fieldtype) {
1916 M_IST(REG_ZERO, REG_ITMP1, 0);
1919 M_LST(REG_ZERO, REG_ITMP1, 0);
1922 M_AST(REG_ZERO, REG_ITMP1, 0);
1925 M_FST(REG_ZERO, REG_ITMP1, 0);
1928 M_DST(REG_ZERO, REG_ITMP1, 0);
1934 case ICMD_GETFIELD: /* ... ==> ..., value */
1936 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1938 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1939 uf = iptr->sx.s23.s3.uf;
1940 fieldtype = uf->fieldref->parseddesc.fd->type;
1943 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1946 fi = iptr->sx.s23.s3.fmiref->p.field;
1947 fieldtype = fi->type;
1951 /* implicit null-pointer check */
1952 switch (fieldtype) {
1954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1958 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1962 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1966 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1970 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1974 emit_store_dst(jd, iptr, d);
1977 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1979 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1981 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1982 uf = iptr->sx.s23.s3.uf;
1983 fieldtype = uf->fieldref->parseddesc.fd->type;
1988 fi = iptr->sx.s23.s3.fmiref->p.field;
1989 fieldtype = fi->type;
1993 if (IS_INT_LNG_TYPE(fieldtype))
1994 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1996 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1998 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1999 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2001 /* implicit null-pointer check */
2002 switch (fieldtype) {
2004 M_IST(s2, s1, disp);
2007 M_LST(s2, s1, disp);
2010 M_AST(s2, s1, disp);
2013 M_FST(s2, s1, disp);
2016 M_DST(s2, s1, disp);
2021 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2022 /* val = value (in current instruction) */
2023 /* following NOP) */
2025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2027 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2028 uf = iptr->sx.s23.s3.uf;
2029 fieldtype = uf->fieldref->parseddesc.fd->type;
2032 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2035 fi = iptr->sx.s23.s3.fmiref->p.field;
2036 fieldtype = fi->type;
2040 /* implicit null-pointer check */
2041 switch (fieldtype) {
2043 M_IST(REG_ZERO, s1, disp);
2046 M_LST(REG_ZERO, s1, disp);
2049 M_AST(REG_ZERO, s1, disp);
2052 M_FST(REG_ZERO, s1, disp);
2055 M_DST(REG_ZERO, s1, disp);
2061 /* branch operations **************************************************/
2063 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2066 M_INTMOVE(s1, REG_ITMP1_XPTR);
2068 #ifdef ENABLE_VERIFIER
2069 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2070 unresolved_class *uc = iptr->sx.s23.s2.uc;
2072 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2074 #endif /* ENABLE_VERIFIER */
2076 disp = dseg_add_functionptr(cd, asm_handle_exception);
2077 M_ALD(REG_ITMP2, REG_PV, disp);
2078 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2079 M_NOP; /* nop ensures that XPC is less than the end */
2080 /* of basic block */
2084 case ICMD_GOTO: /* ... ==> ... */
2085 case ICMD_RET: /* ... ==> ... */
2087 emit_br(cd, iptr->dst.block);
2091 case ICMD_JSR: /* ... ==> ... */
2093 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2097 case ICMD_IFNULL: /* ..., value ==> ... */
2098 case ICMD_IFNONNULL:
2100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2101 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2104 case ICMD_IFEQ: /* ..., value ==> ... */
2106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2107 if (iptr->sx.val.i == 0)
2108 emit_beqz(cd, iptr->dst.block, s1);
2110 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2111 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2113 ICONST(REG_ITMP2, iptr->sx.val.i);
2114 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2116 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2120 case ICMD_IFLT: /* ..., value ==> ... */
2122 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2123 if (iptr->sx.val.i == 0)
2124 emit_bltz(cd, iptr->dst.block, s1);
2126 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2127 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2129 ICONST(REG_ITMP2, iptr->sx.val.i);
2130 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2132 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2136 case ICMD_IFLE: /* ..., value ==> ... */
2138 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2139 if (iptr->sx.val.i == 0)
2140 emit_blez(cd, iptr->dst.block, s1);
2142 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2143 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2145 ICONST(REG_ITMP2, iptr->sx.val.i);
2146 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2148 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2152 case ICMD_IFNE: /* ..., value ==> ... */
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 if (iptr->sx.val.i == 0)
2156 emit_bnez(cd, iptr->dst.block, s1);
2158 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2159 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2161 ICONST(REG_ITMP2, iptr->sx.val.i);
2162 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2164 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2168 case ICMD_IFGT: /* ..., value ==> ... */
2170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2171 if (iptr->sx.val.i == 0)
2172 emit_bgtz(cd, iptr->dst.block, s1);
2174 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2175 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2177 ICONST(REG_ITMP2, iptr->sx.val.i);
2178 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2180 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2184 case ICMD_IFGE: /* ..., value ==> ... */
2186 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2187 if (iptr->sx.val.i == 0)
2188 emit_bgez(cd, iptr->dst.block, s1);
2190 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2191 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2193 ICONST(REG_ITMP2, iptr->sx.val.i);
2194 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2196 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2200 case ICMD_IF_LEQ: /* ..., value ==> ... */
2202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2203 if (iptr->sx.val.l == 0)
2204 emit_beqz(cd, iptr->dst.block, s1);
2206 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2207 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2209 LCONST(REG_ITMP2, iptr->sx.val.l);
2210 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2212 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2216 case ICMD_IF_LLT: /* ..., value ==> ... */
2218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2219 if (iptr->sx.val.l == 0)
2220 emit_bltz(cd, iptr->dst.block, s1);
2222 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2223 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2225 LCONST(REG_ITMP2, iptr->sx.val.l);
2226 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2228 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2232 case ICMD_IF_LLE: /* ..., value ==> ... */
2234 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2235 if (iptr->sx.val.l == 0)
2236 emit_blez(cd, iptr->dst.block, s1);
2238 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2239 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2241 LCONST(REG_ITMP2, iptr->sx.val.l);
2242 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2244 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2248 case ICMD_IF_LNE: /* ..., value ==> ... */
2250 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2251 if (iptr->sx.val.l == 0)
2252 emit_bnez(cd, iptr->dst.block, s1);
2254 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2255 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2257 LCONST(REG_ITMP2, iptr->sx.val.l);
2258 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2260 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2264 case ICMD_IF_LGT: /* ..., value ==> ... */
2266 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2267 if (iptr->sx.val.l == 0)
2268 emit_bgtz(cd, iptr->dst.block, s1);
2270 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2271 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2273 LCONST(REG_ITMP2, iptr->sx.val.l);
2274 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2276 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2280 case ICMD_IF_LGE: /* ..., value ==> ... */
2282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2283 if (iptr->sx.val.l == 0)
2284 emit_bgez(cd, iptr->dst.block, s1);
2286 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2287 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2289 LCONST(REG_ITMP2, iptr->sx.val.l);
2290 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2292 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2296 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2297 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2298 case ICMD_IF_ACMPEQ:
2300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2302 M_CMPEQ(s1, s2, REG_ITMP1);
2303 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2306 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2307 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2308 case ICMD_IF_ACMPNE:
2310 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2311 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2312 M_CMPEQ(s1, s2, REG_ITMP1);
2313 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2316 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2317 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2320 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2321 M_CMPLT(s1, s2, REG_ITMP1);
2322 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2325 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2326 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2328 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2329 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2330 M_CMPLE(s1, s2, REG_ITMP1);
2331 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2334 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2335 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2338 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2339 M_CMPLE(s1, s2, REG_ITMP1);
2340 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2343 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2344 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2347 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2348 M_CMPLT(s1, s2, REG_ITMP1);
2349 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2353 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2356 REPLACEMENT_POINT_RETURN(cd, iptr);
2357 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2358 M_INTMOVE(s1, REG_RESULT);
2359 goto nowperformreturn;
2361 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2363 REPLACEMENT_POINT_RETURN(cd, iptr);
2364 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2365 M_INTMOVE(s1, REG_RESULT);
2367 #ifdef ENABLE_VERIFIER
2368 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2369 unresolved_class *uc = iptr->sx.s23.s2.uc;
2371 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2373 #endif /* ENABLE_VERIFIER */
2374 goto nowperformreturn;
2376 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2379 REPLACEMENT_POINT_RETURN(cd, iptr);
2380 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2381 M_FLTMOVE(s1, REG_FRESULT);
2382 goto nowperformreturn;
2384 case ICMD_RETURN: /* ... ==> ... */
2386 REPLACEMENT_POINT_RETURN(cd, iptr);
2392 p = cd->stackframesize;
2394 /* call trace function */
2396 #if !defined(NDEBUG)
2397 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2398 emit_verbosecall_exit(jd);
2401 #if defined(ENABLE_THREADS)
2402 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2403 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2405 switch (iptr->opc) {
2409 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2413 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2417 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2418 M_ALD(REG_PV, REG_PV, disp);
2419 M_JSR(REG_RA, REG_PV);
2420 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2421 M_LDA(REG_PV, REG_RA, disp);
2423 switch (iptr->opc) {
2427 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2431 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2437 /* restore return address */
2439 if (!jd->isleafmethod) {
2440 p--; M_LLD(REG_RA, REG_SP, p * 8);
2443 /* restore saved registers */
2445 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2446 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2448 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2449 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2452 /* deallocate stack */
2454 if (cd->stackframesize)
2455 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2457 M_RET(REG_ZERO, REG_RA);
2463 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2466 branch_target_t *table;
2468 table = iptr->dst.table;
2470 l = iptr->sx.s23.s2.tablelow;
2471 i = iptr->sx.s23.s3.tablehigh;
2473 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2475 M_INTMOVE(s1, REG_ITMP1);
2476 } else if (l <= 32768) {
2477 M_LDA(REG_ITMP1, s1, -l);
2479 ICONST(REG_ITMP2, l);
2480 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2483 /* number of targets */
2489 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2491 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2492 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2494 emit_beqz(cd, table[0].block, REG_ITMP2);
2496 /* build jump table top down and use address of lowest entry */
2501 dseg_add_target(cd, table->block);
2506 /* length of dataseg after last dseg_add_target is used by load */
2508 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2509 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2510 M_JMP(REG_ZERO, REG_ITMP2);
2515 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2518 lookup_target_t *lookup;
2520 lookup = iptr->dst.lookup;
2522 i = iptr->sx.s23.s2.lookupcount;
2524 MCODECHECK((i<<2)+8);
2525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2528 val = lookup->value;
2529 if ((val >= 0) && (val <= 255)) {
2530 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2532 if ((val >= -32768) && (val <= 32767)) {
2533 M_LDA(REG_ITMP2, REG_ZERO, val);
2535 disp = dseg_add_s4(cd, val);
2536 M_ILD(REG_ITMP2, REG_PV, disp);
2538 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2540 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2544 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2550 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2552 bte = iptr->sx.s23.s3.bte;
2556 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2558 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2559 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2560 case ICMD_INVOKEINTERFACE:
2562 REPLACEMENT_POINT_INVOKE(cd, iptr);
2564 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2566 um = iptr->sx.s23.s3.um;
2567 md = um->methodref->parseddesc.md;
2570 lm = iptr->sx.s23.s3.fmiref->p.method;
2572 md = lm->parseddesc;
2576 s3 = md->paramcount;
2578 MCODECHECK((s3 << 1) + 64);
2580 /* copy arguments to registers or stack location */
2582 for (s3 = s3 - 1; s3 >= 0; s3--) {
2583 var = VAR(iptr->sx.s23.s2.args[s3]);
2585 /* Already Preallocated (ARGVAR) ? */
2586 if (var->flags & PREALLOC)
2589 if (IS_INT_LNG_TYPE(var->type)) {
2590 if (!md->params[s3].inmemory) {
2591 s1 = rd->argintregs[md->params[s3].regoff];
2592 d = emit_load(jd, iptr, var, s1);
2596 d = emit_load(jd, iptr, var, REG_ITMP1);
2597 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2601 if (!md->params[s3].inmemory) {
2602 s1 = rd->argfltregs[md->params[s3].regoff];
2603 d = emit_load(jd, iptr, var, s1);
2607 d = emit_load(jd, iptr, var, REG_FTMP1);
2608 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2613 switch (iptr->opc) {
2615 disp = dseg_add_functionptr(cd, bte->fp);
2617 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2619 /* generate the actual call */
2621 M_JSR(REG_RA, REG_PV);
2622 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2623 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2624 M_LDA(REG_PV, REG_RA, -disp);
2626 emit_exception_check(cd, iptr);
2629 case ICMD_INVOKESPECIAL:
2630 emit_nullpointer_check(cd, iptr, REG_A0);
2633 case ICMD_INVOKESTATIC:
2635 disp = dseg_add_unique_address(cd, um);
2637 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2641 disp = dseg_add_address(cd, lm->stubroutine);
2643 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2645 /* generate the actual call */
2647 M_JSR(REG_RA, REG_PV);
2648 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2649 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2650 M_LDA(REG_PV, REG_RA, -disp);
2653 case ICMD_INVOKEVIRTUAL:
2655 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2660 s1 = OFFSET(vftbl_t, table[0]) +
2661 sizeof(methodptr) * lm->vftblindex;
2663 /* implicit null-pointer check */
2664 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2665 M_ALD(REG_PV, REG_METHODPTR, s1);
2667 /* generate the actual call */
2669 M_JSR(REG_RA, REG_PV);
2670 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2671 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2672 M_LDA(REG_PV, REG_RA, -disp);
2675 case ICMD_INVOKEINTERFACE:
2677 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2683 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2684 sizeof(methodptr*) * lm->class->index;
2686 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2689 /* implicit null-pointer check */
2690 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2691 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2692 M_ALD(REG_PV, REG_METHODPTR, s2);
2694 /* generate the actual call */
2696 M_JSR(REG_RA, REG_PV);
2697 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2698 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2699 M_LDA(REG_PV, REG_RA, -disp);
2703 /* store the return value */
2705 d = md->returntype.type;
2707 if (d != TYPE_VOID) {
2708 if (IS_INT_LNG_TYPE(d)) {
2709 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2710 M_INTMOVE(REG_RESULT, s1);
2713 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2714 M_FLTMOVE(REG_FRESULT, s1);
2716 emit_store_dst(jd, iptr, s1);
2721 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2723 /* val.a: (classinfo*) superclass */
2725 /* superclass is an interface:
2727 * OK if ((sub == NULL) ||
2728 * (sub->vftbl->interfacetablelength > super->index) &&
2729 * (sub->vftbl->interfacetable[-super->index] != NULL));
2731 * superclass is a class:
2733 * OK if ((sub == NULL) || (0
2734 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2735 * super->vftbl->diffval));
2738 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2739 /* object type cast-check */
2742 vftbl_t *supervftbl;
2745 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2751 super = iptr->sx.s23.s3.c.cls;
2752 superindex = super->index;
2753 supervftbl = super->vftbl;
2756 #if defined(ENABLE_THREADS)
2757 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2761 /* if class is not resolved, check which code to call */
2763 if (super == NULL) {
2764 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2766 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2768 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2769 iptr->sx.s23.s3.c.ref,
2772 M_ILD(REG_ITMP2, REG_PV, disp);
2773 disp = dseg_add_s4(cd, ACC_INTERFACE);
2774 M_ILD(REG_ITMP3, REG_PV, disp);
2775 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2776 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2779 /* interface checkcast code */
2781 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2782 if (super == NULL) {
2783 codegen_add_patch_ref(cd,
2784 PATCHER_checkcast_interface,
2785 iptr->sx.s23.s3.c.ref,
2789 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2791 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2792 M_ILD(REG_ITMP3, REG_ITMP2,
2793 OFFSET(vftbl_t, interfacetablelength));
2794 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2795 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2797 M_ALD(REG_ITMP3, REG_ITMP2,
2798 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2799 superindex * sizeof(methodptr*)));
2800 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2803 emit_label_br(cd, BRANCH_LABEL_4);
2805 emit_label(cd, BRANCH_LABEL_3);
2808 /* class checkcast code */
2810 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2811 if (super == NULL) {
2812 emit_label(cd, BRANCH_LABEL_2);
2814 disp = dseg_add_unique_address(cd, NULL);
2816 codegen_add_patch_ref(cd,
2817 PATCHER_resolve_classref_to_vftbl,
2818 iptr->sx.s23.s3.c.ref,
2822 disp = dseg_add_address(cd, supervftbl);
2824 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2827 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2828 M_ALD(REG_ITMP3, REG_PV, disp);
2829 #if defined(ENABLE_THREADS)
2830 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2832 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2833 /* if (s1 != REG_ITMP1) { */
2834 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2835 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2836 /* #if defined(ENABLE_THREADS) */
2837 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2839 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2842 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2843 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2844 M_ALD(REG_ITMP3, REG_PV, disp);
2845 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2846 #if defined(ENABLE_THREADS)
2847 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2850 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2851 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2854 emit_label(cd, BRANCH_LABEL_5);
2857 if (super == NULL) {
2858 emit_label(cd, BRANCH_LABEL_1);
2859 emit_label(cd, BRANCH_LABEL_4);
2862 d = codegen_reg_of_dst(jd, iptr, s1);
2865 /* array type cast-check */
2867 s1 = emit_load_s1(jd, iptr, REG_A0);
2868 M_INTMOVE(s1, REG_A0);
2870 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2871 disp = dseg_add_unique_address(cd, NULL);
2873 codegen_add_patch_ref(cd,
2874 PATCHER_resolve_classref_to_classinfo,
2875 iptr->sx.s23.s3.c.ref,
2879 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2881 M_ALD(REG_A1, REG_PV, disp);
2882 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2883 M_ALD(REG_PV, REG_PV, disp);
2884 M_JSR(REG_RA, REG_PV);
2885 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2886 M_LDA(REG_PV, REG_RA, -disp);
2888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2889 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2891 d = codegen_reg_of_dst(jd, iptr, s1);
2895 emit_store_dst(jd, iptr, d);
2898 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2900 /* val.a: (classinfo*) superclass */
2902 /* superclass is an interface:
2904 * return (sub != NULL) &&
2905 * (sub->vftbl->interfacetablelength > super->index) &&
2906 * (sub->vftbl->interfacetable[-super->index] != NULL);
2908 * superclass is a class:
2910 * return ((sub != NULL) && (0
2911 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2912 * super->vftbl->diffvall));
2917 vftbl_t *supervftbl;
2920 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2926 super = iptr->sx.s23.s3.c.cls;
2927 superindex = super->index;
2928 supervftbl = super->vftbl;
2931 #if defined(ENABLE_THREADS)
2932 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2935 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2938 M_MOV(s1, REG_ITMP1);
2942 /* if class is not resolved, check which code to call */
2944 if (super == NULL) {
2946 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2948 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2950 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2951 iptr->sx.s23.s3.c.ref, disp);
2953 M_ILD(REG_ITMP3, REG_PV, disp);
2955 disp = dseg_add_s4(cd, ACC_INTERFACE);
2956 M_ILD(REG_ITMP2, REG_PV, disp);
2957 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2958 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2961 /* interface instanceof code */
2963 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2964 if (super == NULL) {
2965 /* If d == REG_ITMP2, then it's destroyed in check
2970 codegen_add_patch_ref(cd,
2971 PATCHER_instanceof_interface,
2972 iptr->sx.s23.s3.c.ref, 0);
2976 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2979 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2980 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2981 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2982 M_BLEZ(REG_ITMP3, 2);
2983 M_ALD(REG_ITMP1, REG_ITMP1,
2984 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2985 superindex * sizeof(methodptr*)));
2986 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2989 emit_label_br(cd, BRANCH_LABEL_4);
2991 emit_label(cd, BRANCH_LABEL_3);
2994 /* class instanceof code */
2996 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2997 if (super == NULL) {
2998 emit_label(cd, BRANCH_LABEL_2);
3000 disp = dseg_add_unique_address(cd, NULL);
3002 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3003 iptr->sx.s23.s3.c.ref,
3007 disp = dseg_add_address(cd, supervftbl);
3010 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3013 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3014 M_ALD(REG_ITMP2, REG_PV, disp);
3015 #if defined(ENABLE_THREADS)
3016 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3018 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3019 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3020 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3021 #if defined(ENABLE_THREADS)
3022 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3024 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3025 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3028 emit_label(cd, BRANCH_LABEL_5);
3031 if (super == NULL) {
3032 emit_label(cd, BRANCH_LABEL_1);
3033 emit_label(cd, BRANCH_LABEL_4);
3036 emit_store_dst(jd, iptr, d);
3040 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3042 /* check for negative sizes and copy sizes to stack if necessary */
3044 MCODECHECK((iptr->s1.argcount << 1) + 64);
3046 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3048 var = VAR(iptr->sx.s23.s2.args[s1]);
3050 /* copy SAVEDVAR sizes to stack */
3052 /* Already Preallocated? */
3054 if (!(var->flags & PREALLOC)) {
3055 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3056 M_LST(s2, REG_SP, s1 * 8);
3060 /* a0 = dimension count */
3062 ICONST(REG_A0, iptr->s1.argcount);
3064 /* is patcher function set? */
3066 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3067 disp = dseg_add_unique_address(cd, 0);
3069 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
3070 iptr->sx.s23.s3.c.ref,
3074 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3076 /* a1 = arraydescriptor */
3078 M_ALD(REG_A1, REG_PV, disp);
3080 /* a2 = pointer to dimensions = stack pointer */
3082 M_INTMOVE(REG_SP, REG_A2);
3084 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3085 M_ALD(REG_PV, REG_PV, disp);
3086 M_JSR(REG_RA, REG_PV);
3087 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3088 M_LDA(REG_PV, REG_RA, -disp);
3090 /* check for exception before result assignment */
3092 emit_exception_check(cd, iptr);
3094 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3095 M_INTMOVE(REG_RESULT, d);
3096 emit_store_dst(jd, iptr, d);
3100 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3105 } /* for instruction */
3107 } /* if (bptr -> flags >= BBREACHED) */
3108 } /* for basic block */
3110 dseg_createlinenumbertable(cd);
3112 /* generate stubs */
3114 emit_patcher_stubs(jd);
3115 REPLACEMENT_EMIT_STUBS(jd);
3117 /* everything's ok */
3123 /* createcompilerstub **********************************************************
3125 Creates a stub routine which calls the compiler.
3127 *******************************************************************************/
3129 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3130 #define COMPILERSTUB_CODESIZE 3 * 4
3132 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3135 u1 *createcompilerstub(methodinfo *m)
3137 u1 *s; /* memory to hold the stub */
3140 s4 dumpsize; /* code generation pointer */
3142 s = CNEW(u1, COMPILERSTUB_SIZE);
3144 /* set data pointer and code pointer */
3147 s = s + COMPILERSTUB_DATASIZE;
3149 /* mark start of dump memory area */
3151 dumpsize = dump_size();
3153 cd = DNEW(codegendata);
3156 /* The codeinfo pointer is actually a pointer to the
3157 methodinfo. This fakes a codeinfo structure. */
3159 d[0] = (ptrint) asm_call_jit_compiler;
3161 d[2] = (ptrint) &d[1]; /* fake code->m */
3163 /* code for the stub */
3165 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3166 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3167 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3169 #if defined(ENABLE_STATISTICS)
3171 count_cstub_len += COMPILERSTUB_SIZE;
3174 /* release dump area */
3176 dump_release(dumpsize);
3182 /* createnativestub ************************************************************
3184 Creates a stub routine which calls a native method.
3186 *******************************************************************************/
3188 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3196 s4 i, j; /* count variables */
3199 s4 funcdisp; /* displacement of the function */
3201 /* get required compiler data */
3208 /* initialize variables */
3211 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3213 /* calculate stack frame size */
3215 cd->stackframesize =
3216 1 + /* return address */
3217 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3218 sizeof(localref_table) / SIZEOF_VOID_P +
3219 1 + /* methodinfo for call trace */
3220 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3223 /* create method header */
3225 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3226 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3227 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3228 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3229 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3230 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3231 (void) dseg_addlinenumbertablesize(cd);
3232 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3234 /* generate stub code */
3236 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3237 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3239 /* call trace function */
3241 #if !defined(NDEBUG)
3242 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3243 emit_verbosecall_enter(jd);
3246 /* get function address (this must happen before the stackframeinfo) */
3248 funcdisp = dseg_add_functionptr(cd, f);
3250 #if !defined(WITH_STATIC_CLASSPATH)
3252 codegen_add_patch_ref(cd, PATCHER_resolve_native_function, m, funcdisp);
3255 #if defined(ENABLE_GC_CACAO)
3256 /* Save callee saved integer registers in stackframeinfo (GC may
3257 need to recover them during a collection). */
3259 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3260 OFFSET(stackframeinfo, intregs);
3262 for (i = 0; i < INT_SAV_CNT; i++)
3263 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3266 /* save integer and float argument registers */
3268 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3269 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3270 M_LST(rd->argintregs[i], REG_SP, j * 8);
3275 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3276 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3277 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3282 /* prepare data structures for native function call */
3284 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3285 M_MOV(REG_PV, REG_A1);
3286 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3287 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3288 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3289 M_ALD(REG_PV, REG_PV, disp);
3290 M_JSR(REG_RA, REG_PV);
3291 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3292 M_LDA(REG_PV, REG_RA, -disp);
3294 /* restore integer and float argument registers */
3296 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3297 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3298 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3303 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3304 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3305 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3310 /* copy or spill arguments to new locations */
3312 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3313 t = md->paramtypes[i].type;
3315 if (IS_INT_LNG_TYPE(t)) {
3316 if (!md->params[i].inmemory) {
3317 s1 = rd->argintregs[md->params[i].regoff];
3319 if (!nmd->params[j].inmemory) {
3320 s2 = rd->argintregs[nmd->params[j].regoff];
3324 s2 = nmd->params[j].regoff;
3325 M_LST(s1, REG_SP, s2 * 8);
3329 s1 = md->params[i].regoff + cd->stackframesize;
3330 s2 = nmd->params[j].regoff;
3331 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3332 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3336 if (!md->params[i].inmemory) {
3337 s1 = rd->argfltregs[md->params[i].regoff];
3339 if (!nmd->params[j].inmemory) {
3340 s2 = rd->argfltregs[nmd->params[j].regoff];
3344 s2 = nmd->params[j].regoff;
3345 if (IS_2_WORD_TYPE(t))
3346 M_DST(s1, REG_SP, s2 * 8);
3348 M_FST(s1, REG_SP, s2 * 8);
3352 s1 = md->params[i].regoff + cd->stackframesize;
3353 s2 = nmd->params[j].regoff;
3354 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3355 if (IS_2_WORD_TYPE(t))
3356 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3358 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3363 /* put class into second argument register */
3365 if (m->flags & ACC_STATIC) {
3366 disp = dseg_add_address(cd, m->class);
3367 M_ALD(REG_A1, REG_PV, disp);
3370 /* put env into first argument register */
3372 disp = dseg_add_address(cd, _Jv_env);
3373 M_ALD(REG_A0, REG_PV, disp);
3375 /* do the native function call */
3377 M_ALD(REG_PV, REG_PV, funcdisp);
3378 M_JSR(REG_RA, REG_PV); /* call native method */
3379 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3380 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3382 /* save return value */
3384 if (md->returntype.type != TYPE_VOID) {
3385 if (IS_INT_LNG_TYPE(md->returntype.type))
3386 M_LST(REG_RESULT, REG_SP, 0 * 8);
3388 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3391 /* call finished trace */
3393 #if !defined(NDEBUG)
3394 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3395 emit_verbosecall_exit(jd);
3398 /* remove native stackframe info */
3400 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3401 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3402 M_ALD(REG_PV, REG_PV, disp);
3403 M_JSR(REG_RA, REG_PV);
3404 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3405 M_LDA(REG_PV, REG_RA, -disp);
3406 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3408 /* restore return value */
3410 if (md->returntype.type != TYPE_VOID) {
3411 if (IS_INT_LNG_TYPE(md->returntype.type))
3412 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3414 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3417 #if defined(ENABLE_GC_CACAO)
3418 /* Restore callee saved integer registers from stackframeinfo (GC
3419 might have modified them during a collection). */
3421 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3422 OFFSET(stackframeinfo, intregs);
3424 for (i = 0; i < INT_SAV_CNT; i++)
3425 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3428 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3429 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3431 /* check for exception */
3433 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3434 M_RET(REG_ZERO, REG_RA); /* return to caller */
3436 /* handle exception */
3438 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3440 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3441 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3442 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3445 /* generate patcher stubs */
3447 emit_patcher_stubs(jd);
3451 return code->entrypoint;
3456 * These are local overrides for various environment variables in Emacs.
3457 * Please do not remove this and leave it at the end of the file, where
3458 * Emacs will automagically detect them.
3459 * ---------------------------------------------------------------------
3462 * indent-tabs-mode: t
3466 * vim:noexpandtab:sw=4:ts=4: