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 7596 2007-03-28 21:05:53Z 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/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.h"
66 #include "vm/jit/stacktrace.h"
68 #if defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
72 #include "vmcore/loader.h"
73 #include "vmcore/options.h"
76 /* codegen_emit ****************************************************************
78 Generates machine code.
80 *******************************************************************************/
82 bool codegen_emit(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
94 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
95 unresolved_method *um;
96 builtintable_entry *bte;
103 /* get required compiler data */
110 /* prevent compiler warnings */
123 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
125 /* space to save used callee saved registers */
127 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
130 cd->stackframesize = rd->memuse + savedregs_num;
132 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED))
134 cd->stackframesize++;
137 /* create method header */
140 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
143 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
144 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
146 #if defined(ENABLE_THREADS)
147 /* IsSync contains the offset relative to the stack pointer for the
148 argument of monitor_exit used in the exception handler. Since the
149 offset could be zero and give a wrong meaning of the flag it is
153 if (checksync && (m->flags & ACC_SYNCHRONIZED))
154 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
157 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
159 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
160 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
161 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
163 dseg_addlinenumbertablesize(cd);
165 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
167 /* create exception table */
169 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
170 dseg_add_target(cd, ex->start);
171 dseg_add_target(cd, ex->end);
172 dseg_add_target(cd, ex->handler);
173 (void) dseg_add_unique_address(cd, ex->catchtype.any);
176 /* create stack frame (if necessary) */
178 if (cd->stackframesize)
179 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
181 /* save return address and used callee saved registers */
183 p = cd->stackframesize;
184 if (!jd->isleafmethod) {
185 p--; M_AST(REG_RA, REG_SP, p * 8);
187 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
188 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
190 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
191 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
194 /* take arguments out of register or stack frame */
198 for (p = 0, l = 0; p < md->paramcount; p++) {
199 t = md->paramtypes[p].type;
201 varindex = jd->local_map[l * 5 + t];
204 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
207 if (varindex == UNUSED)
212 s1 = md->params[p].regoff;
214 if (IS_INT_LNG_TYPE(t)) { /* integer args */
215 if (!md->params[p].inmemory) { /* register arguments */
216 s2 = rd->argintregs[s1];
217 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
218 M_INTMOVE(s2, var->vv.regoff);
220 } else { /* reg arg -> spilled */
221 M_LST(s2, REG_SP, var->vv.regoff * 8);
224 } else { /* stack arguments */
225 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
226 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
228 } else { /* stack arg -> spilled */
229 var->vv.regoff = cd->stackframesize + s1;
233 } else { /* floating args */
234 if (!md->params[p].inmemory) { /* register arguments */
235 s2 = rd->argfltregs[s1];
236 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
237 M_FLTMOVE(s2, var->vv.regoff);
239 } else { /* reg arg -> spilled */
240 M_DST(s2, REG_SP, var->vv.regoff * 8);
243 } else { /* stack arguments */
244 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
245 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
247 } else { /* stack-arg -> spilled */
248 var->vv.regoff = cd->stackframesize + s1;
254 /* call monitorenter function */
256 #if defined(ENABLE_THREADS)
257 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
258 /* stack offset for monitor argument */
263 if (opt_verbosecall) {
264 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
266 for (p = 0; p < INT_ARG_CNT; p++)
267 M_LST(rd->argintregs[p], REG_SP, p * 8);
269 for (p = 0; p < FLT_ARG_CNT; p++)
270 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
272 s1 += INT_ARG_CNT + FLT_ARG_CNT;
274 #endif /* !defined(NDEBUG) */
276 /* decide which monitor enter function to call */
278 if (m->flags & ACC_STATIC) {
279 disp = dseg_add_address(cd, &m->class->object.header);
280 M_ALD(REG_A0, REG_PV, disp);
284 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
287 M_AST(REG_A0, REG_SP, s1 * 8);
288 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
289 M_ALD(REG_PV, REG_PV, disp);
290 M_JSR(REG_RA, REG_PV);
291 disp = (s4) (cd->mcodeptr - cd->mcodebase);
292 M_LDA(REG_PV, REG_RA, -disp);
295 if (opt_verbosecall) {
296 for (p = 0; p < INT_ARG_CNT; p++)
297 M_LLD(rd->argintregs[p], REG_SP, p * 8);
299 for (p = 0; p < FLT_ARG_CNT; p++)
300 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
302 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
304 #endif /* !defined(NDEBUG) */
308 /* call trace function */
311 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
312 emit_verbosecall_enter(jd);
317 /* end of header generation */
319 /* create replacement points */
321 REPLACEMENT_POINTS_INIT(cd, jd);
323 /* walk through all basic blocks */
325 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
327 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
329 if (bptr->flags >= BBREACHED) {
331 /* branch resolving */
333 codegen_resolve_branchrefs(cd, bptr);
335 /* handle replacement points */
337 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
339 /* copy interface registers to their destination */
343 #if defined(ENABLE_LSRA)
347 src = bptr->invars[len];
348 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
349 /* d = reg_of_var(m, src, REG_ITMP1); */
350 if (!(src->flags & INMEMORY))
354 M_INTMOVE(REG_ITMP1, d);
355 emit_store(jd, NULL, src, d);
362 var = VAR(bptr->invars[len]);
363 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
364 d = codegen_reg_of_var(0, var, REG_ITMP1);
365 M_INTMOVE(REG_ITMP1, d);
366 emit_store(jd, NULL, var, d);
369 assert((var->flags & INOUT));
372 #if defined(ENABLE_LSRA)
376 /* walk through all instructions */
380 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
381 if (iptr->line != currentline) {
382 dseg_addlinenumber(cd, iptr->line);
383 currentline = iptr->line;
386 MCODECHECK(64); /* an instruction usually needs < 64 words */
389 case ICMD_NOP: /* ... ==> ... */
390 case ICMD_POP: /* ..., value ==> ... */
391 case ICMD_POP2: /* ..., value, value ==> ... */
394 case ICMD_INLINE_START:
396 REPLACEMENT_POINT_INLINE_START(cd, iptr);
399 case ICMD_INLINE_BODY:
401 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
402 dseg_addlinenumber_inline_start(cd, iptr);
403 dseg_addlinenumber(cd, iptr->line);
406 case ICMD_INLINE_END:
408 dseg_addlinenumber_inline_end(cd, iptr);
409 dseg_addlinenumber(cd, iptr->line);
412 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
415 emit_nullpointer_check(cd, iptr, s1);
418 /* constant operations ************************************************/
420 case ICMD_ICONST: /* ... ==> ..., constant */
422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
423 ICONST(d, iptr->sx.val.i);
424 emit_store_dst(jd, iptr, d);
427 case ICMD_LCONST: /* ... ==> ..., constant */
429 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
430 LCONST(d, iptr->sx.val.l);
431 emit_store_dst(jd, iptr, d);
434 case ICMD_FCONST: /* ... ==> ..., constant */
436 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
437 disp = dseg_add_float(cd, iptr->sx.val.f);
438 M_FLD(d, REG_PV, disp);
439 emit_store_dst(jd, iptr, d);
442 case ICMD_DCONST: /* ... ==> ..., constant */
444 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
445 disp = dseg_add_double(cd, iptr->sx.val.d);
446 M_DLD(d, REG_PV, disp);
447 emit_store_dst(jd, iptr, d);
450 case ICMD_ACONST: /* ... ==> ..., constant */
452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
455 constant_classref *cr = iptr->sx.val.c.ref;
457 disp = dseg_add_unique_address(cd, cr);
459 /* XXX Only add the patcher, if this position needs to
460 be patched. If there was a previous position which
461 resolved the same class, the returned displacement
462 of dseg_add_address is ok to use. */
464 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
467 M_ALD(d, REG_PV, disp);
470 if (iptr->sx.val.anyptr == NULL)
471 M_INTMOVE(REG_ZERO, d);
473 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
474 M_ALD(d, REG_PV, disp);
477 emit_store_dst(jd, iptr, d);
481 /* load/store/move/copy operations ************************************/
483 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
484 case ICMD_ALOAD: /* s1 = local variable */
488 case ICMD_ISTORE: /* ..., value ==> ... */
495 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
500 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
501 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
505 /* integer operations *************************************************/
507 case ICMD_INEG: /* ..., value ==> ..., - value */
509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
511 M_ISUB(REG_ZERO, s1, d);
512 emit_store_dst(jd, iptr, d);
515 case ICMD_LNEG: /* ..., value ==> ..., - value */
517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
519 M_LSUB(REG_ZERO, s1, d);
520 emit_store_dst(jd, iptr, d);
523 case ICMD_I2L: /* ..., value ==> ..., value */
525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528 emit_store_dst(jd, iptr, d);
531 case ICMD_L2I: /* ..., value ==> ..., value */
533 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
535 M_IADD(s1, REG_ZERO, d);
536 emit_store_dst(jd, iptr, d);
539 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543 if (has_ext_instr_set) {
546 M_SLL_IMM(s1, 56, d);
547 M_SRA_IMM( d, 56, d);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557 emit_store_dst(jd, iptr, d);
560 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 if (has_ext_instr_set) {
567 M_SLL_IMM(s1, 48, d);
568 M_SRA_IMM( d, 48, d);
570 emit_store_dst(jd, iptr, d);
574 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580 emit_store_dst(jd, iptr, d);
584 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
585 /* sx.val.i = constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
590 M_IADD_IMM(s1, iptr->sx.val.i, d);
591 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
592 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
594 /* XXX maybe use M_LDA? */
595 ICONST(REG_ITMP2, iptr->sx.val.i);
596 M_IADD(s1, REG_ITMP2, d);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
611 /* sx.val.l = constant */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
616 M_LADD_IMM(s1, iptr->sx.val.l, d);
618 LCONST(REG_ITMP2, iptr->sx.val.l);
619 M_LADD(s1, REG_ITMP2, d);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630 emit_store_dst(jd, iptr, d);
633 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
634 /* sx.val.i = constant */
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
639 M_ISUB_IMM(s1, iptr->sx.val.i, d);
641 ICONST(REG_ITMP2, iptr->sx.val.i);
642 M_ISUB(s1, REG_ITMP2, d);
644 emit_store_dst(jd, iptr, d);
647 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
653 emit_store_dst(jd, iptr, d);
656 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
657 /* sx.val.l = constant */
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
662 M_LSUB_IMM(s1, iptr->sx.val.l, d);
664 LCONST(REG_ITMP2, iptr->sx.val.l);
665 M_LSUB(s1, REG_ITMP2, d);
667 emit_store_dst(jd, iptr, d);
670 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
676 emit_store_dst(jd, iptr, d);
679 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
680 /* sx.val.i = constant */
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
685 M_IMUL_IMM(s1, iptr->sx.val.i, d);
687 ICONST(REG_ITMP2, iptr->sx.val.i);
688 M_IMUL(s1, REG_ITMP2, d);
690 emit_store_dst(jd, iptr, d);
693 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
699 emit_store_dst(jd, iptr, d);
702 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
703 /* sx.val.l = constant */
705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
707 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
708 M_LMUL_IMM(s1, iptr->sx.val.l, d);
710 LCONST(REG_ITMP2, iptr->sx.val.l);
711 M_LMUL(s1, REG_ITMP2, d);
713 emit_store_dst(jd, iptr, d);
716 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
717 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
719 s1 = emit_load_s1(jd, iptr, REG_A0);
720 s2 = emit_load_s2(jd, iptr, REG_A1);
721 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
722 emit_arithmetic_check(cd, iptr, s2);
724 M_INTMOVE(s1, REG_A0);
725 M_INTMOVE(s2, REG_A1);
726 bte = iptr->sx.s23.s3.bte;
727 disp = dseg_add_functionptr(cd, bte->fp);
728 M_ALD(REG_PV, REG_PV, disp);
729 M_JSR(REG_RA, REG_PV);
730 disp = (s4) (cd->mcodeptr - cd->mcodebase);
731 M_LDA(REG_PV, REG_RA, -disp);
733 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
734 emit_store_dst(jd, iptr, d);
737 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
738 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
740 s1 = emit_load_s1(jd, iptr, REG_A0);
741 s2 = emit_load_s2(jd, iptr, REG_A1);
742 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
743 emit_arithmetic_check(cd, iptr, s2);
745 M_INTMOVE(s1, REG_A0);
746 M_INTMOVE(s2, REG_A1);
747 bte = iptr->sx.s23.s3.bte;
748 disp = dseg_add_functionptr(cd, bte->fp);
749 M_ALD(REG_PV, REG_PV, disp);
750 M_JSR(REG_RA, REG_PV);
751 disp = (s4) (cd->mcodeptr - cd->mcodebase);
752 M_LDA(REG_PV, REG_RA, -disp);
754 M_INTMOVE(REG_RESULT, d);
755 emit_store_dst(jd, iptr, d);
758 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
759 case ICMD_LDIVPOW2: /* val.i = constant */
761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
763 if (iptr->sx.val.i <= 15) {
764 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
765 M_CMOVGE(s1, s1, REG_ITMP2);
767 M_SRA_IMM(s1, 63, REG_ITMP2);
768 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
769 M_LADD(s1, REG_ITMP2, REG_ITMP2);
771 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
772 emit_store_dst(jd, iptr, d);
775 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
780 M_AND_IMM(s2, 0x1f, REG_ITMP3);
781 M_SLL(s1, REG_ITMP3, d);
782 M_IADD(d, REG_ZERO, d);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
787 /* sx.val.i = constant */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
792 M_IADD(d, REG_ZERO, d);
793 emit_store_dst(jd, iptr, d);
796 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
799 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
800 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
801 M_AND_IMM(s2, 0x1f, REG_ITMP3);
802 M_SRA(s1, REG_ITMP3, d);
803 emit_store_dst(jd, iptr, d);
806 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
807 /* sx.val.i = constant */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
811 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
820 M_AND_IMM(s2, 0x1f, REG_ITMP2);
822 M_SRL(d, REG_ITMP2, d);
823 M_IADD(d, REG_ZERO, d);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
828 /* sx.val.i = constant */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
833 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
834 M_IADD(d, REG_ZERO, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
844 emit_store_dst(jd, iptr, d);
847 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
848 /* sx.val.i = constant */
850 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
853 emit_store_dst(jd, iptr, d);
856 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
860 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
862 emit_store_dst(jd, iptr, d);
865 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
866 /* sx.val.i = constant */
868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
884 /* sx.val.i = constant */
886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
888 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
889 emit_store_dst(jd, iptr, d);
892 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
896 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
899 emit_store_dst(jd, iptr, d);
902 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
903 /* sx.val.i = constant */
905 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
906 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
908 M_AND_IMM(s1, iptr->sx.val.i, d);
909 } else if (iptr->sx.val.i == 0xffff) {
911 } else if (iptr->sx.val.i == 0xffffff) {
912 M_ZAPNOT_IMM(s1, 0x07, d);
914 ICONST(REG_ITMP2, iptr->sx.val.i);
915 M_AND(s1, REG_ITMP2, d);
917 emit_store_dst(jd, iptr, d);
920 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
921 /* sx.val.i = constant */
923 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
924 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
926 M_MOV(s1, REG_ITMP1);
929 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
930 M_AND_IMM(s1, iptr->sx.val.i, d);
932 M_ISUB(REG_ZERO, s1, d);
933 M_AND_IMM(d, iptr->sx.val.i, d);
934 } else if (iptr->sx.val.i == 0xffff) {
937 M_ISUB(REG_ZERO, s1, d);
939 } else if (iptr->sx.val.i == 0xffffff) {
940 M_ZAPNOT_IMM(s1, 0x07, d);
942 M_ISUB(REG_ZERO, s1, d);
943 M_ZAPNOT_IMM(d, 0x07, d);
945 ICONST(REG_ITMP2, iptr->sx.val.i);
946 M_AND(s1, REG_ITMP2, d);
948 M_ISUB(REG_ZERO, s1, d);
949 M_AND(d, REG_ITMP2, d);
951 M_ISUB(REG_ZERO, d, d);
952 emit_store_dst(jd, iptr, d);
955 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
956 /* sx.val.l = constant */
958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
959 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
960 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
961 M_AND_IMM(s1, iptr->sx.val.l, d);
962 } else if (iptr->sx.val.l == 0xffffL) {
964 } else if (iptr->sx.val.l == 0xffffffL) {
965 M_ZAPNOT_IMM(s1, 0x07, d);
966 } else if (iptr->sx.val.l == 0xffffffffL) {
968 } else if (iptr->sx.val.l == 0xffffffffffL) {
969 M_ZAPNOT_IMM(s1, 0x1f, d);
970 } else if (iptr->sx.val.l == 0xffffffffffffL) {
971 M_ZAPNOT_IMM(s1, 0x3f, d);
972 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
973 M_ZAPNOT_IMM(s1, 0x7f, d);
975 LCONST(REG_ITMP2, iptr->sx.val.l);
976 M_AND(s1, REG_ITMP2, d);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
982 /* sx.val.l = constant */
984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
985 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
987 M_MOV(s1, REG_ITMP1);
990 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
991 M_AND_IMM(s1, iptr->sx.val.l, d);
993 M_LSUB(REG_ZERO, s1, d);
994 M_AND_IMM(d, iptr->sx.val.l, d);
995 } else if (iptr->sx.val.l == 0xffffL) {
998 M_LSUB(REG_ZERO, s1, d);
1000 } else if (iptr->sx.val.l == 0xffffffL) {
1001 M_ZAPNOT_IMM(s1, 0x07, d);
1003 M_LSUB(REG_ZERO, s1, d);
1004 M_ZAPNOT_IMM(d, 0x07, d);
1005 } else if (iptr->sx.val.l == 0xffffffffL) {
1008 M_LSUB(REG_ZERO, s1, d);
1010 } else if (iptr->sx.val.l == 0xffffffffffL) {
1011 M_ZAPNOT_IMM(s1, 0x1f, d);
1013 M_LSUB(REG_ZERO, s1, d);
1014 M_ZAPNOT_IMM(d, 0x1f, d);
1015 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1016 M_ZAPNOT_IMM(s1, 0x3f, d);
1018 M_LSUB(REG_ZERO, s1, d);
1019 M_ZAPNOT_IMM(d, 0x3f, d);
1020 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1021 M_ZAPNOT_IMM(s1, 0x7f, d);
1023 M_LSUB(REG_ZERO, s1, d);
1024 M_ZAPNOT_IMM(d, 0x7f, d);
1026 LCONST(REG_ITMP2, iptr->sx.val.l);
1027 M_AND(s1, REG_ITMP2, d);
1029 M_LSUB(REG_ZERO, s1, d);
1030 M_AND(d, REG_ITMP2, d);
1032 M_LSUB(REG_ZERO, d, d);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1041 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1047 /* sx.val.i = constant */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1051 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1052 M_OR_IMM(s1, iptr->sx.val.i, d);
1054 ICONST(REG_ITMP2, iptr->sx.val.i);
1055 M_OR(s1, REG_ITMP2, d);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1061 /* sx.val.l = constant */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1066 M_OR_IMM(s1, iptr->sx.val.l, d);
1068 LCONST(REG_ITMP2, iptr->sx.val.l);
1069 M_OR(s1, REG_ITMP2, d);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1081 emit_store_dst(jd, iptr, d);
1084 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1085 /* sx.val.i = constant */
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1090 M_XOR_IMM(s1, iptr->sx.val.i, d);
1092 ICONST(REG_ITMP2, iptr->sx.val.i);
1093 M_XOR(s1, REG_ITMP2, d);
1095 emit_store_dst(jd, iptr, d);
1098 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1099 /* sx.val.l = constant */
1101 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1103 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1104 M_XOR_IMM(s1, iptr->sx.val.l, d);
1106 LCONST(REG_ITMP2, iptr->sx.val.l);
1107 M_XOR(s1, REG_ITMP2, d);
1109 emit_store_dst(jd, iptr, d);
1113 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1118 M_CMPLT(s1, s2, REG_ITMP3);
1119 M_CMPLT(s2, s1, REG_ITMP1);
1120 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1121 emit_store_dst(jd, iptr, d);
1125 /* floating operations ************************************************/
1127 case ICMD_FNEG: /* ..., value ==> ..., - value */
1129 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1130 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1132 emit_store_dst(jd, iptr, d);
1135 case ICMD_DNEG: /* ..., value ==> ..., - value */
1137 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1146 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1147 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1151 if (d == s1 || d == s2) {
1152 M_FADDS(s1, s2, REG_FTMP3);
1154 M_FMOV(REG_FTMP3, d);
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1165 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1166 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1167 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1171 if (d == s1 || d == s2) {
1172 M_DADDS(s1, s2, REG_FTMP3);
1174 M_FMOV(REG_FTMP3, d);
1180 emit_store_dst(jd, iptr, d);
1183 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1185 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1186 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1187 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1191 if (d == s1 || d == s2) {
1192 M_FSUBS(s1, s2, REG_FTMP3);
1194 M_FMOV(REG_FTMP3, d);
1200 emit_store_dst(jd, iptr, d);
1203 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1205 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1206 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1207 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1211 if (d == s1 || d == s2) {
1212 M_DSUBS(s1, s2, REG_FTMP3);
1214 M_FMOV(REG_FTMP3, d);
1220 emit_store_dst(jd, iptr, d);
1223 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1225 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1226 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1227 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1231 if (d == s1 || d == s2) {
1232 M_FMULS(s1, s2, REG_FTMP3);
1234 M_FMOV(REG_FTMP3, d);
1240 emit_store_dst(jd, iptr, d);
1243 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1245 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1246 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1247 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1251 if (d == s1 || d == s2) {
1252 M_DMULS(s1, s2, REG_FTMP3);
1254 M_FMOV(REG_FTMP3, d);
1260 emit_store_dst(jd, iptr, d);
1263 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1267 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1271 if (d == s1 || d == s2) {
1272 M_FDIVS(s1, s2, REG_FTMP3);
1274 M_FMOV(REG_FTMP3, d);
1280 emit_store_dst(jd, iptr, d);
1283 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1285 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1286 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1287 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1291 if (d == s1 || d == s2) {
1292 M_DDIVS(s1, s2, REG_FTMP3);
1294 M_FMOV(REG_FTMP3, d);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_I2F: /* ..., value ==> ..., (float) 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_I2D: /* ..., value ==> ..., (double) value */
1316 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1317 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1318 disp = dseg_add_unique_double(cd, 0.0);
1319 M_LST(s1, REG_PV, disp);
1320 M_DLD(d, REG_PV, disp);
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1327 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1328 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1329 disp = dseg_add_unique_double(cd, 0.0);
1330 M_CVTDL_C(s1, REG_FTMP2);
1331 M_CVTLI(REG_FTMP2, REG_FTMP3);
1332 M_DST(REG_FTMP3, REG_PV, disp);
1333 M_ILD(d, REG_PV, disp);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1339 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1341 disp = dseg_add_unique_double(cd, 0.0);
1342 M_CVTDL_C(s1, REG_FTMP2);
1343 M_DST(REG_FTMP2, REG_PV, disp);
1344 M_LLD(d, REG_PV, disp);
1345 emit_store_dst(jd, iptr, d);
1348 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1350 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1351 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1354 emit_store_dst(jd, iptr, d);
1357 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1359 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1360 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1367 emit_store_dst(jd, iptr, d);
1370 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1372 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1373 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1376 M_LSUB_IMM(REG_ZERO, 1, d);
1377 M_FCMPEQ(s1, s2, REG_FTMP3);
1378 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1380 M_FCMPLT(s2, s1, REG_FTMP3);
1381 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1382 M_LADD_IMM(REG_ZERO, 1, d);
1384 M_LSUB_IMM(REG_ZERO, 1, d);
1385 M_FCMPEQS(s1, s2, REG_FTMP3);
1387 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1389 M_FCMPLTS(s2, s1, REG_FTMP3);
1391 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1392 M_LADD_IMM(REG_ZERO, 1, d);
1394 emit_store_dst(jd, iptr, d);
1397 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1399 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1400 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1403 M_LADD_IMM(REG_ZERO, 1, d);
1404 M_FCMPEQ(s1, s2, REG_FTMP3);
1405 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1407 M_FCMPLT(s1, s2, REG_FTMP3);
1408 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1409 M_LSUB_IMM(REG_ZERO, 1, d);
1411 M_LADD_IMM(REG_ZERO, 1, d);
1412 M_FCMPEQS(s1, s2, REG_FTMP3);
1414 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1416 M_FCMPLTS(s1, s2, REG_FTMP3);
1418 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1419 M_LSUB_IMM(REG_ZERO, 1, d);
1421 emit_store_dst(jd, iptr, d);
1425 /* memory operations **************************************************/
1427 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1431 /* implicit null-pointer check */
1432 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1433 emit_store_dst(jd, iptr, d);
1436 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1440 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1441 /* implicit null-pointer check */
1442 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1443 if (has_ext_instr_set) {
1444 M_LADD(s2, s1, REG_ITMP1);
1445 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1449 M_LADD(s2, s1, REG_ITMP1);
1450 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1451 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1452 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1453 M_SRA_IMM(d, 56, d);
1455 emit_store_dst(jd, iptr, d);
1458 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1460 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1461 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1463 /* implicit null-pointer check */
1464 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1465 if (has_ext_instr_set) {
1466 M_LADD(s2, s1, REG_ITMP1);
1467 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1468 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1471 M_LADD (s2, s1, REG_ITMP1);
1472 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1473 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1474 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1475 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1477 emit_store_dst(jd, iptr, d);
1480 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1484 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1485 /* implicit null-pointer check */
1486 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487 if (has_ext_instr_set) {
1488 M_LADD(s2, s1, REG_ITMP1);
1489 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1490 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1493 M_LADD(s2, s1, REG_ITMP1);
1494 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1495 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1496 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1497 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1498 M_SRA_IMM(d, 48, d);
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1508 /* implicit null-pointer check */
1509 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1510 M_S4ADDQ(s2, s1, REG_ITMP1);
1511 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1512 emit_store_dst(jd, iptr, d);
1515 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1520 /* implicit null-pointer check */
1521 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1522 M_S8ADDQ(s2, s1, REG_ITMP1);
1523 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1524 emit_store_dst(jd, iptr, d);
1527 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1532 /* implicit null-pointer check */
1533 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1534 M_S4ADDQ(s2, s1, REG_ITMP1);
1535 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1536 emit_store_dst(jd, iptr, d);
1539 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1544 /* implicit null-pointer check */
1545 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1546 M_S8ADDQ(s2, s1, REG_ITMP1);
1547 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1548 emit_store_dst(jd, iptr, d);
1551 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1554 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1556 /* implicit null-pointer check */
1557 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1558 M_SAADDQ(s2, s1, REG_ITMP1);
1559 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1560 emit_store_dst(jd, iptr, d);
1564 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1568 /* implicit null-pointer check */
1569 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1570 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1571 if (has_ext_instr_set) {
1572 M_LADD(s2, s1, REG_ITMP1);
1573 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1576 M_LADD(s2, s1, REG_ITMP1);
1577 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1578 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1579 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1580 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1581 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1582 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1586 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1589 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1590 /* implicit null-pointer check */
1591 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1592 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1593 if (has_ext_instr_set) {
1594 M_LADD(s2, s1, REG_ITMP1);
1595 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1596 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1599 M_LADD(s2, s1, REG_ITMP1);
1600 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1601 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1602 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1603 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1604 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1605 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1606 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1610 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1614 /* implicit null-pointer check */
1615 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1616 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1617 if (has_ext_instr_set) {
1618 M_LADD(s2, s1, REG_ITMP1);
1619 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1620 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1623 M_LADD(s2, s1, REG_ITMP1);
1624 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1625 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1626 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1627 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1628 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1629 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1630 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1634 case ICMD_IASTORE: /* ..., 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_S4ADDQ(s2, s1, REG_ITMP1);
1642 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1645 case ICMD_LASTORE: /* ..., 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_ITMP3);
1652 M_S8ADDQ(s2, s1, REG_ITMP1);
1653 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1656 case ICMD_FASTORE: /* ..., 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_S4ADDQ(s2, s1, REG_ITMP1);
1664 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1667 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
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_FTMP3);
1674 M_S8ADDQ(s2, s1, REG_ITMP1);
1675 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1678 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1680 s1 = emit_load_s1(jd, iptr, REG_A0);
1681 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1682 /* implicit null-pointer check */
1683 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1684 s3 = emit_load_s3(jd, iptr, REG_A1);
1686 M_INTMOVE(s1, REG_A0);
1687 M_INTMOVE(s3, REG_A1);
1689 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1690 M_ALD(REG_PV, REG_PV, disp);
1691 M_JSR(REG_RA, REG_PV);
1692 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1693 M_LDA(REG_PV, REG_RA, -disp);
1694 emit_exception_check(cd, iptr);
1696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1698 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1699 M_SAADDQ(s2, s1, REG_ITMP1);
1700 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1704 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1707 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1708 /* implicit null-pointer check */
1709 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1710 if (has_ext_instr_set) {
1711 M_LADD(s2, s1, REG_ITMP1);
1712 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1715 M_LADD(s2, s1, REG_ITMP1);
1716 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1717 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1718 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1719 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1720 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1721 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1725 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1727 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1728 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1729 /* implicit null-pointer check */
1730 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1731 if (has_ext_instr_set) {
1732 M_LADD(s2, s1, REG_ITMP1);
1733 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1734 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1737 M_LADD(s2, s1, REG_ITMP1);
1738 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1739 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1740 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1741 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1742 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1743 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1744 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1748 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1752 /* implicit null-pointer check */
1753 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1754 if (has_ext_instr_set) {
1755 M_LADD(s2, s1, REG_ITMP1);
1756 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1757 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1760 M_LADD(s2, s1, REG_ITMP1);
1761 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1762 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1763 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1764 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1765 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1766 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1767 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1771 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1775 /* implicit null-pointer check */
1776 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1777 M_S4ADDQ(s2, s1, REG_ITMP1);
1778 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1781 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1785 /* implicit null-pointer check */
1786 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1787 M_S8ADDQ(s2, s1, REG_ITMP1);
1788 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1791 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795 /* implicit null-pointer check */
1796 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1797 M_SAADDQ(s2, s1, REG_ITMP1);
1798 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1802 case ICMD_GETSTATIC: /* ... ==> ..., value */
1804 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1805 uf = iptr->sx.s23.s3.uf;
1806 fieldtype = uf->fieldref->parseddesc.fd->type;
1807 disp = dseg_add_unique_address(cd, uf);
1809 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1812 fi = iptr->sx.s23.s3.fmiref->p.field;
1813 fieldtype = fi->type;
1814 disp = dseg_add_address(cd, &(fi->value));
1816 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1817 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1821 M_ALD(REG_ITMP1, REG_PV, disp);
1822 switch (fieldtype) {
1824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1825 M_ILD(d, REG_ITMP1, 0);
1828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1829 M_LLD(d, REG_ITMP1, 0);
1832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1833 M_ALD(d, REG_ITMP1, 0);
1836 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1837 M_FLD(d, REG_ITMP1, 0);
1840 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1841 M_DLD(d, REG_ITMP1, 0);
1844 emit_store_dst(jd, iptr, d);
1847 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1849 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1850 uf = iptr->sx.s23.s3.uf;
1851 fieldtype = uf->fieldref->parseddesc.fd->type;
1852 disp = dseg_add_unique_address(cd, uf);
1854 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1857 fi = iptr->sx.s23.s3.fmiref->p.field;
1858 fieldtype = fi->type;
1859 disp = dseg_add_address(cd, &(fi->value));
1861 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1862 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1866 M_ALD(REG_ITMP1, REG_PV, disp);
1867 switch (fieldtype) {
1869 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1870 M_IST(s1, REG_ITMP1, 0);
1873 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1874 M_LST(s1, REG_ITMP1, 0);
1877 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1878 M_AST(s1, REG_ITMP1, 0);
1881 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1882 M_FST(s1, REG_ITMP1, 0);
1885 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1886 M_DST(s1, REG_ITMP1, 0);
1891 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1892 /* val = value (in current instruction) */
1893 /* following NOP) */
1895 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1896 uf = iptr->sx.s23.s3.uf;
1897 fieldtype = uf->fieldref->parseddesc.fd->type;
1898 disp = dseg_add_unique_address(cd, uf);
1900 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1903 fi = iptr->sx.s23.s3.fmiref->p.field;
1904 fieldtype = fi->type;
1905 disp = dseg_add_address(cd, &(fi->value));
1907 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1908 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1912 M_ALD(REG_ITMP1, REG_PV, disp);
1913 switch (fieldtype) {
1915 M_IST(REG_ZERO, REG_ITMP1, 0);
1918 M_LST(REG_ZERO, REG_ITMP1, 0);
1921 M_AST(REG_ZERO, REG_ITMP1, 0);
1924 M_FST(REG_ZERO, REG_ITMP1, 0);
1927 M_DST(REG_ZERO, REG_ITMP1, 0);
1933 case ICMD_GETFIELD: /* ... ==> ..., value */
1935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1937 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1938 uf = iptr->sx.s23.s3.uf;
1939 fieldtype = uf->fieldref->parseddesc.fd->type;
1942 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1945 fi = iptr->sx.s23.s3.fmiref->p.field;
1946 fieldtype = fi->type;
1950 /* implicit null-pointer check */
1951 switch (fieldtype) {
1953 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1961 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1965 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1969 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1973 emit_store_dst(jd, iptr, d);
1976 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1980 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1981 uf = iptr->sx.s23.s3.uf;
1982 fieldtype = uf->fieldref->parseddesc.fd->type;
1987 fi = iptr->sx.s23.s3.fmiref->p.field;
1988 fieldtype = fi->type;
1992 if (IS_INT_LNG_TYPE(fieldtype))
1993 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1995 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1997 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1998 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2000 /* implicit null-pointer check */
2001 switch (fieldtype) {
2003 M_IST(s2, s1, disp);
2006 M_LST(s2, s1, disp);
2009 M_AST(s2, s1, disp);
2012 M_FST(s2, s1, disp);
2015 M_DST(s2, s1, disp);
2020 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2021 /* val = value (in current instruction) */
2022 /* following NOP) */
2024 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2026 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2027 uf = iptr->sx.s23.s3.uf;
2028 fieldtype = uf->fieldref->parseddesc.fd->type;
2031 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2034 fi = iptr->sx.s23.s3.fmiref->p.field;
2035 fieldtype = fi->type;
2039 /* implicit null-pointer check */
2040 switch (fieldtype) {
2042 M_IST(REG_ZERO, s1, disp);
2045 M_LST(REG_ZERO, s1, disp);
2048 M_AST(REG_ZERO, s1, disp);
2051 M_FST(REG_ZERO, s1, disp);
2054 M_DST(REG_ZERO, s1, disp);
2060 /* branch operations **************************************************/
2062 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2064 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2065 M_INTMOVE(s1, REG_ITMP1_XPTR);
2067 #ifdef ENABLE_VERIFIER
2068 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2069 unresolved_class *uc = iptr->sx.s23.s2.uc;
2071 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2073 #endif /* ENABLE_VERIFIER */
2075 disp = dseg_add_functionptr(cd, asm_handle_exception);
2076 M_ALD(REG_ITMP2, REG_PV, disp);
2077 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2078 M_NOP; /* nop ensures that XPC is less than the end */
2079 /* of basic block */
2083 case ICMD_GOTO: /* ... ==> ... */
2084 case ICMD_RET: /* ... ==> ... */
2086 emit_br(cd, iptr->dst.block);
2090 case ICMD_JSR: /* ... ==> ... */
2092 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2096 case ICMD_IFNULL: /* ..., value ==> ... */
2097 case ICMD_IFNONNULL:
2099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2100 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2103 case ICMD_IFEQ: /* ..., value ==> ... */
2105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2106 if (iptr->sx.val.i == 0)
2107 emit_beqz(cd, iptr->dst.block, s1);
2109 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2110 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2112 ICONST(REG_ITMP2, iptr->sx.val.i);
2113 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2115 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2119 case ICMD_IFLT: /* ..., value ==> ... */
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 if (iptr->sx.val.i == 0)
2123 emit_bltz(cd, iptr->dst.block, s1);
2125 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2126 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2128 ICONST(REG_ITMP2, iptr->sx.val.i);
2129 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2131 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2135 case ICMD_IFLE: /* ..., value ==> ... */
2137 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2138 if (iptr->sx.val.i == 0)
2139 emit_blez(cd, iptr->dst.block, s1);
2141 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2142 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2144 ICONST(REG_ITMP2, iptr->sx.val.i);
2145 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2147 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2151 case ICMD_IFNE: /* ..., value ==> ... */
2153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2154 if (iptr->sx.val.i == 0)
2155 emit_bnez(cd, iptr->dst.block, s1);
2157 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2158 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2160 ICONST(REG_ITMP2, iptr->sx.val.i);
2161 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2163 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2167 case ICMD_IFGT: /* ..., value ==> ... */
2169 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2170 if (iptr->sx.val.i == 0)
2171 emit_bgtz(cd, iptr->dst.block, s1);
2173 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2174 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2176 ICONST(REG_ITMP2, iptr->sx.val.i);
2177 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2179 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2183 case ICMD_IFGE: /* ..., value ==> ... */
2185 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2186 if (iptr->sx.val.i == 0)
2187 emit_bgez(cd, iptr->dst.block, s1);
2189 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2190 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2192 ICONST(REG_ITMP2, iptr->sx.val.i);
2193 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2195 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2199 case ICMD_IF_LEQ: /* ..., value ==> ... */
2201 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2202 if (iptr->sx.val.l == 0)
2203 emit_beqz(cd, iptr->dst.block, s1);
2205 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2206 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2208 LCONST(REG_ITMP2, iptr->sx.val.l);
2209 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2211 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2215 case ICMD_IF_LLT: /* ..., value ==> ... */
2217 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2218 if (iptr->sx.val.l == 0)
2219 emit_bltz(cd, iptr->dst.block, s1);
2221 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2222 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2224 LCONST(REG_ITMP2, iptr->sx.val.l);
2225 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2227 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2231 case ICMD_IF_LLE: /* ..., value ==> ... */
2233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2234 if (iptr->sx.val.l == 0)
2235 emit_blez(cd, iptr->dst.block, s1);
2237 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2238 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2240 LCONST(REG_ITMP2, iptr->sx.val.l);
2241 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2243 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2247 case ICMD_IF_LNE: /* ..., value ==> ... */
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 if (iptr->sx.val.l == 0)
2251 emit_bnez(cd, iptr->dst.block, s1);
2253 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2254 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2256 LCONST(REG_ITMP2, iptr->sx.val.l);
2257 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2259 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2263 case ICMD_IF_LGT: /* ..., value ==> ... */
2265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2266 if (iptr->sx.val.l == 0)
2267 emit_bgtz(cd, iptr->dst.block, s1);
2269 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2270 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2272 LCONST(REG_ITMP2, iptr->sx.val.l);
2273 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2275 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2279 case ICMD_IF_LGE: /* ..., value ==> ... */
2281 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2282 if (iptr->sx.val.l == 0)
2283 emit_bgez(cd, iptr->dst.block, s1);
2285 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2286 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2288 LCONST(REG_ITMP2, iptr->sx.val.l);
2289 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2291 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2295 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2296 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2297 case ICMD_IF_ACMPEQ:
2299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2300 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2301 M_CMPEQ(s1, s2, REG_ITMP1);
2302 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2305 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2306 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2307 case ICMD_IF_ACMPNE:
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2311 M_CMPEQ(s1, s2, REG_ITMP1);
2312 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2315 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2316 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2320 M_CMPLT(s1, s2, REG_ITMP1);
2321 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2324 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2325 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2329 M_CMPLE(s1, s2, REG_ITMP1);
2330 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2333 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2334 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2338 M_CMPLE(s1, s2, REG_ITMP1);
2339 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2342 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2343 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2345 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2346 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2347 M_CMPLT(s1, s2, REG_ITMP1);
2348 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2352 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2355 REPLACEMENT_POINT_RETURN(cd, iptr);
2356 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2357 M_INTMOVE(s1, REG_RESULT);
2358 goto nowperformreturn;
2360 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2362 REPLACEMENT_POINT_RETURN(cd, iptr);
2363 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2364 M_INTMOVE(s1, REG_RESULT);
2366 #ifdef ENABLE_VERIFIER
2367 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2368 unresolved_class *uc = iptr->sx.s23.s2.uc;
2370 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2372 #endif /* ENABLE_VERIFIER */
2373 goto nowperformreturn;
2375 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2378 REPLACEMENT_POINT_RETURN(cd, iptr);
2379 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2380 M_FLTMOVE(s1, REG_FRESULT);
2381 goto nowperformreturn;
2383 case ICMD_RETURN: /* ... ==> ... */
2385 REPLACEMENT_POINT_RETURN(cd, iptr);
2391 p = cd->stackframesize;
2393 /* call trace function */
2395 #if !defined(NDEBUG)
2396 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2397 emit_verbosecall_exit(jd);
2400 #if defined(ENABLE_THREADS)
2401 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2402 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2404 switch (iptr->opc) {
2408 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2412 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2416 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2417 M_ALD(REG_PV, REG_PV, disp);
2418 M_JSR(REG_RA, REG_PV);
2419 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2420 M_LDA(REG_PV, REG_RA, disp);
2422 switch (iptr->opc) {
2426 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2430 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2436 /* restore return address */
2438 if (!jd->isleafmethod) {
2439 p--; M_LLD(REG_RA, REG_SP, p * 8);
2442 /* restore saved registers */
2444 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2445 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2447 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2448 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2451 /* deallocate stack */
2453 if (cd->stackframesize)
2454 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2456 M_RET(REG_ZERO, REG_RA);
2462 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2465 branch_target_t *table;
2467 table = iptr->dst.table;
2469 l = iptr->sx.s23.s2.tablelow;
2470 i = iptr->sx.s23.s3.tablehigh;
2472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2474 M_INTMOVE(s1, REG_ITMP1);
2475 } else if (l <= 32768) {
2476 M_LDA(REG_ITMP1, s1, -l);
2478 ICONST(REG_ITMP2, l);
2479 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2482 /* number of targets */
2488 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2490 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2491 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2493 emit_beqz(cd, table[0].block, REG_ITMP2);
2495 /* build jump table top down and use address of lowest entry */
2500 dseg_add_target(cd, table->block);
2505 /* length of dataseg after last dseg_add_target is used by load */
2507 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2508 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2509 M_JMP(REG_ZERO, REG_ITMP2);
2514 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2517 lookup_target_t *lookup;
2519 lookup = iptr->dst.lookup;
2521 i = iptr->sx.s23.s2.lookupcount;
2523 MCODECHECK((i<<2)+8);
2524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2527 val = lookup->value;
2528 if ((val >= 0) && (val <= 255)) {
2529 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2531 if ((val >= -32768) && (val <= 32767)) {
2532 M_LDA(REG_ITMP2, REG_ZERO, val);
2534 disp = dseg_add_s4(cd, val);
2535 M_ILD(REG_ITMP2, REG_PV, disp);
2537 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2539 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2543 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2549 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2551 bte = iptr->sx.s23.s3.bte;
2555 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2557 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2558 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2559 case ICMD_INVOKEINTERFACE:
2561 REPLACEMENT_POINT_INVOKE(cd, iptr);
2563 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2565 um = iptr->sx.s23.s3.um;
2566 md = um->methodref->parseddesc.md;
2569 lm = iptr->sx.s23.s3.fmiref->p.method;
2571 md = lm->parseddesc;
2575 s3 = md->paramcount;
2577 MCODECHECK((s3 << 1) + 64);
2579 /* copy arguments to registers or stack location */
2581 for (s3 = s3 - 1; s3 >= 0; s3--) {
2582 var = VAR(iptr->sx.s23.s2.args[s3]);
2584 /* Already Preallocated (ARGVAR) ? */
2585 if (var->flags & PREALLOC)
2588 if (IS_INT_LNG_TYPE(var->type)) {
2589 if (!md->params[s3].inmemory) {
2590 s1 = rd->argintregs[md->params[s3].regoff];
2591 d = emit_load(jd, iptr, var, s1);
2595 d = emit_load(jd, iptr, var, REG_ITMP1);
2596 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2600 if (!md->params[s3].inmemory) {
2601 s1 = rd->argfltregs[md->params[s3].regoff];
2602 d = emit_load(jd, iptr, var, s1);
2606 d = emit_load(jd, iptr, var, REG_FTMP1);
2607 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2612 switch (iptr->opc) {
2614 disp = dseg_add_functionptr(cd, bte->fp);
2616 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2618 /* generate the actual call */
2620 M_JSR(REG_RA, REG_PV);
2621 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2622 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2623 M_LDA(REG_PV, REG_RA, -disp);
2625 emit_exception_check(cd, iptr);
2628 case ICMD_INVOKESPECIAL:
2629 emit_nullpointer_check(cd, iptr, REG_A0);
2632 case ICMD_INVOKESTATIC:
2634 disp = dseg_add_unique_address(cd, um);
2636 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2640 disp = dseg_add_address(cd, lm->stubroutine);
2642 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2644 /* generate the actual call */
2646 M_JSR(REG_RA, REG_PV);
2647 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2648 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2649 M_LDA(REG_PV, REG_RA, -disp);
2652 case ICMD_INVOKEVIRTUAL:
2654 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2659 s1 = OFFSET(vftbl_t, table[0]) +
2660 sizeof(methodptr) * lm->vftblindex;
2662 /* implicit null-pointer check */
2663 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2664 M_ALD(REG_PV, REG_METHODPTR, s1);
2666 /* generate the actual call */
2668 M_JSR(REG_RA, REG_PV);
2669 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2670 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2671 M_LDA(REG_PV, REG_RA, -disp);
2674 case ICMD_INVOKEINTERFACE:
2676 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2682 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2683 sizeof(methodptr*) * lm->class->index;
2685 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2688 /* implicit null-pointer check */
2689 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
2690 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2691 M_ALD(REG_PV, REG_METHODPTR, s2);
2693 /* generate the actual call */
2695 M_JSR(REG_RA, REG_PV);
2696 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2697 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2698 M_LDA(REG_PV, REG_RA, -disp);
2702 /* store the return value */
2704 d = md->returntype.type;
2706 if (d != TYPE_VOID) {
2707 if (IS_INT_LNG_TYPE(d)) {
2708 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2709 M_INTMOVE(REG_RESULT, s1);
2712 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2713 M_FLTMOVE(REG_FRESULT, s1);
2715 emit_store_dst(jd, iptr, s1);
2720 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2722 /* val.a: (classinfo*) superclass */
2724 /* superclass is an interface:
2726 * OK if ((sub == NULL) ||
2727 * (sub->vftbl->interfacetablelength > super->index) &&
2728 * (sub->vftbl->interfacetable[-super->index] != NULL));
2730 * superclass is a class:
2732 * OK if ((sub == NULL) || (0
2733 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2734 * super->vftbl->diffval));
2737 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2738 /* object type cast-check */
2741 vftbl_t *supervftbl;
2744 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2750 super = iptr->sx.s23.s3.c.cls;
2751 superindex = super->index;
2752 supervftbl = super->vftbl;
2755 #if defined(ENABLE_THREADS)
2756 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2760 /* if class is not resolved, check which code to call */
2762 if (super == NULL) {
2763 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2765 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2767 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2768 iptr->sx.s23.s3.c.ref,
2771 M_ILD(REG_ITMP2, REG_PV, disp);
2772 disp = dseg_add_s4(cd, ACC_INTERFACE);
2773 M_ILD(REG_ITMP3, REG_PV, disp);
2774 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2775 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2778 /* interface checkcast code */
2780 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2781 if (super == NULL) {
2782 codegen_add_patch_ref(cd,
2783 PATCHER_checkcast_interface,
2784 iptr->sx.s23.s3.c.ref,
2788 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2790 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2791 M_ILD(REG_ITMP3, REG_ITMP2,
2792 OFFSET(vftbl_t, interfacetablelength));
2793 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2794 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2796 M_ALD(REG_ITMP3, REG_ITMP2,
2797 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2798 superindex * sizeof(methodptr*)));
2799 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2802 emit_label_br(cd, BRANCH_LABEL_4);
2804 emit_label(cd, BRANCH_LABEL_3);
2807 /* class checkcast code */
2809 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2810 if (super == NULL) {
2811 emit_label(cd, BRANCH_LABEL_2);
2813 disp = dseg_add_unique_address(cd, NULL);
2815 codegen_add_patch_ref(cd,
2816 PATCHER_resolve_classref_to_vftbl,
2817 iptr->sx.s23.s3.c.ref,
2821 disp = dseg_add_address(cd, supervftbl);
2823 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2826 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2827 M_ALD(REG_ITMP3, REG_PV, disp);
2828 #if defined(ENABLE_THREADS)
2829 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2831 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2832 /* if (s1 != REG_ITMP1) { */
2833 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2834 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2835 /* #if defined(ENABLE_THREADS) */
2836 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2838 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2841 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2842 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2843 M_ALD(REG_ITMP3, REG_PV, disp);
2844 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2845 #if defined(ENABLE_THREADS)
2846 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2849 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2850 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2853 emit_label(cd, BRANCH_LABEL_5);
2856 if (super == NULL) {
2857 emit_label(cd, BRANCH_LABEL_1);
2858 emit_label(cd, BRANCH_LABEL_4);
2861 d = codegen_reg_of_dst(jd, iptr, s1);
2864 /* array type cast-check */
2866 s1 = emit_load_s1(jd, iptr, REG_A0);
2867 M_INTMOVE(s1, REG_A0);
2869 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2870 disp = dseg_add_unique_address(cd, NULL);
2872 codegen_add_patch_ref(cd,
2873 PATCHER_resolve_classref_to_classinfo,
2874 iptr->sx.s23.s3.c.ref,
2878 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2880 M_ALD(REG_A1, REG_PV, disp);
2881 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2882 M_ALD(REG_PV, REG_PV, disp);
2883 M_JSR(REG_RA, REG_PV);
2884 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2885 M_LDA(REG_PV, REG_RA, -disp);
2887 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2888 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2890 d = codegen_reg_of_dst(jd, iptr, s1);
2894 emit_store_dst(jd, iptr, d);
2897 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2899 /* val.a: (classinfo*) superclass */
2901 /* superclass is an interface:
2903 * return (sub != NULL) &&
2904 * (sub->vftbl->interfacetablelength > super->index) &&
2905 * (sub->vftbl->interfacetable[-super->index] != NULL);
2907 * superclass is a class:
2909 * return ((sub != NULL) && (0
2910 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2911 * super->vftbl->diffvall));
2916 vftbl_t *supervftbl;
2919 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2925 super = iptr->sx.s23.s3.c.cls;
2926 superindex = super->index;
2927 supervftbl = super->vftbl;
2930 #if defined(ENABLE_THREADS)
2931 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2933 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2934 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2937 M_MOV(s1, REG_ITMP1);
2941 /* if class is not resolved, check which code to call */
2943 if (super == NULL) {
2945 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2947 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2949 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2950 iptr->sx.s23.s3.c.ref, disp);
2952 M_ILD(REG_ITMP3, REG_PV, disp);
2954 disp = dseg_add_s4(cd, ACC_INTERFACE);
2955 M_ILD(REG_ITMP2, REG_PV, disp);
2956 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2957 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2960 /* interface instanceof code */
2962 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2963 if (super == NULL) {
2964 /* If d == REG_ITMP2, then it's destroyed in check
2969 codegen_add_patch_ref(cd,
2970 PATCHER_instanceof_interface,
2971 iptr->sx.s23.s3.c.ref, 0);
2975 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2978 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2979 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2980 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2981 M_BLEZ(REG_ITMP3, 2);
2982 M_ALD(REG_ITMP1, REG_ITMP1,
2983 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2984 superindex * sizeof(methodptr*)));
2985 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2988 emit_label_br(cd, BRANCH_LABEL_4);
2990 emit_label(cd, BRANCH_LABEL_3);
2993 /* class instanceof code */
2995 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2996 if (super == NULL) {
2997 emit_label(cd, BRANCH_LABEL_2);
2999 disp = dseg_add_unique_address(cd, NULL);
3001 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3002 iptr->sx.s23.s3.c.ref,
3006 disp = dseg_add_address(cd, supervftbl);
3009 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3012 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3013 M_ALD(REG_ITMP2, REG_PV, disp);
3014 #if defined(ENABLE_THREADS)
3015 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3017 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3018 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3019 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3020 #if defined(ENABLE_THREADS)
3021 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3023 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3024 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3027 emit_label(cd, BRANCH_LABEL_5);
3030 if (super == NULL) {
3031 emit_label(cd, BRANCH_LABEL_1);
3032 emit_label(cd, BRANCH_LABEL_4);
3035 emit_store_dst(jd, iptr, d);
3039 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3041 /* check for negative sizes and copy sizes to stack if necessary */
3043 MCODECHECK((iptr->s1.argcount << 1) + 64);
3045 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3047 var = VAR(iptr->sx.s23.s2.args[s1]);
3049 /* copy SAVEDVAR sizes to stack */
3051 /* Already Preallocated? */
3053 if (!(var->flags & PREALLOC)) {
3054 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3055 M_LST(s2, REG_SP, s1 * 8);
3059 /* a0 = dimension count */
3061 ICONST(REG_A0, iptr->s1.argcount);
3063 /* is patcher function set? */
3065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3066 disp = dseg_add_unique_address(cd, 0);
3068 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
3069 iptr->sx.s23.s3.c.ref,
3073 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3075 /* a1 = arraydescriptor */
3077 M_ALD(REG_A1, REG_PV, disp);
3079 /* a2 = pointer to dimensions = stack pointer */
3081 M_INTMOVE(REG_SP, REG_A2);
3083 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3084 M_ALD(REG_PV, REG_PV, disp);
3085 M_JSR(REG_RA, REG_PV);
3086 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3087 M_LDA(REG_PV, REG_RA, -disp);
3089 /* check for exception before result assignment */
3091 emit_exception_check(cd, iptr);
3093 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3094 M_INTMOVE(REG_RESULT, d);
3095 emit_store_dst(jd, iptr, d);
3099 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3104 } /* for instruction */
3106 } /* if (bptr -> flags >= BBREACHED) */
3107 } /* for basic block */
3109 dseg_createlinenumbertable(cd);
3111 /* generate stubs */
3113 emit_patcher_stubs(jd);
3114 REPLACEMENT_EMIT_STUBS(jd);
3116 /* everything's ok */
3122 /* createcompilerstub **********************************************************
3124 Creates a stub routine which calls the compiler.
3126 *******************************************************************************/
3128 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3129 #define COMPILERSTUB_CODESIZE 3 * 4
3131 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3134 u1 *createcompilerstub(methodinfo *m)
3136 u1 *s; /* memory to hold the stub */
3139 s4 dumpsize; /* code generation pointer */
3141 s = CNEW(u1, COMPILERSTUB_SIZE);
3143 /* set data pointer and code pointer */
3146 s = s + COMPILERSTUB_DATASIZE;
3148 /* mark start of dump memory area */
3150 dumpsize = dump_size();
3152 cd = DNEW(codegendata);
3155 /* The codeinfo pointer is actually a pointer to the
3156 methodinfo. This fakes a codeinfo structure. */
3158 d[0] = (ptrint) asm_call_jit_compiler;
3160 d[2] = (ptrint) &d[1]; /* fake code->m */
3162 /* code for the stub */
3164 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3165 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3166 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3168 #if defined(ENABLE_STATISTICS)
3170 count_cstub_len += COMPILERSTUB_SIZE;
3173 /* release dump area */
3175 dump_release(dumpsize);
3181 /* createnativestub ************************************************************
3183 Creates a stub routine which calls a native method.
3185 *******************************************************************************/
3187 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3195 s4 i, j; /* count variables */
3198 s4 funcdisp; /* displacement of the function */
3200 /* get required compiler data */
3207 /* initialize variables */
3210 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3212 /* calculate stack frame size */
3214 cd->stackframesize =
3215 1 + /* return address */
3216 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3217 sizeof(localref_table) / SIZEOF_VOID_P +
3218 1 + /* methodinfo for call trace */
3219 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3222 /* create method header */
3224 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3225 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3226 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3227 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3228 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3229 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3230 (void) dseg_addlinenumbertablesize(cd);
3231 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3233 /* generate stub code */
3235 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3236 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3238 /* call trace function */
3240 #if !defined(NDEBUG)
3241 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3242 emit_verbosecall_enter(jd);
3245 /* get function address (this must happen before the stackframeinfo) */
3247 funcdisp = dseg_add_functionptr(cd, f);
3249 #if !defined(WITH_STATIC_CLASSPATH)
3251 codegen_add_patch_ref(cd, PATCHER_resolve_native_function, m, funcdisp);
3254 /* save integer and float argument registers */
3256 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3257 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3258 M_LST(rd->argintregs[i], REG_SP, j * 8);
3263 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3264 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3265 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3270 /* prepare data structures for native function call */
3272 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3273 M_MOV(REG_PV, REG_A1);
3274 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3275 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3276 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3277 M_ALD(REG_PV, REG_PV, disp);
3278 M_JSR(REG_RA, REG_PV);
3279 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3280 M_LDA(REG_PV, REG_RA, -disp);
3282 /* restore integer and float argument registers */
3284 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3285 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3286 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3291 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3292 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3293 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3298 /* copy or spill arguments to new locations */
3300 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3301 t = md->paramtypes[i].type;
3303 if (IS_INT_LNG_TYPE(t)) {
3304 if (!md->params[i].inmemory) {
3305 s1 = rd->argintregs[md->params[i].regoff];
3307 if (!nmd->params[j].inmemory) {
3308 s2 = rd->argintregs[nmd->params[j].regoff];
3312 s2 = nmd->params[j].regoff;
3313 M_LST(s1, REG_SP, s2 * 8);
3317 s1 = md->params[i].regoff + cd->stackframesize;
3318 s2 = nmd->params[j].regoff;
3319 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3320 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3324 if (!md->params[i].inmemory) {
3325 s1 = rd->argfltregs[md->params[i].regoff];
3327 if (!nmd->params[j].inmemory) {
3328 s2 = rd->argfltregs[nmd->params[j].regoff];
3332 s2 = nmd->params[j].regoff;
3333 if (IS_2_WORD_TYPE(t))
3334 M_DST(s1, REG_SP, s2 * 8);
3336 M_FST(s1, REG_SP, s2 * 8);
3340 s1 = md->params[i].regoff + cd->stackframesize;
3341 s2 = nmd->params[j].regoff;
3342 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3343 if (IS_2_WORD_TYPE(t))
3344 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3346 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3351 /* put class into second argument register */
3353 if (m->flags & ACC_STATIC) {
3354 disp = dseg_add_address(cd, m->class);
3355 M_ALD(REG_A1, REG_PV, disp);
3358 /* put env into first argument register */
3360 disp = dseg_add_address(cd, _Jv_env);
3361 M_ALD(REG_A0, REG_PV, disp);
3363 /* do the native function call */
3365 M_ALD(REG_PV, REG_PV, funcdisp);
3366 M_JSR(REG_RA, REG_PV); /* call native method */
3367 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3368 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3370 /* save return value */
3372 if (md->returntype.type != TYPE_VOID) {
3373 if (IS_INT_LNG_TYPE(md->returntype.type))
3374 M_LST(REG_RESULT, REG_SP, 0 * 8);
3376 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3379 /* call finished trace */
3381 #if !defined(NDEBUG)
3382 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3383 emit_verbosecall_exit(jd);
3386 /* remove native stackframe info */
3388 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3389 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3390 M_ALD(REG_PV, REG_PV, disp);
3391 M_JSR(REG_RA, REG_PV);
3392 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3393 M_LDA(REG_PV, REG_RA, -disp);
3394 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3396 /* restore return value */
3398 if (md->returntype.type != TYPE_VOID) {
3399 if (IS_INT_LNG_TYPE(md->returntype.type))
3400 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3402 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3405 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3406 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3408 /* check for exception */
3410 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3411 M_RET(REG_ZERO, REG_RA); /* return to caller */
3413 /* handle exception */
3415 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3417 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3418 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3419 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3422 /* generate patcher stubs */
3424 emit_patcher_stubs(jd);
3428 return code->entrypoint;
3433 * These are local overrides for various environment variables in Emacs.
3434 * Please do not remove this and leave it at the end of the file, where
3435 * Emacs will automagically detect them.
3436 * ---------------------------------------------------------------------
3439 * indent-tabs-mode: t
3443 * vim:noexpandtab:sw=4:ts=4: