1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
35 $Id: codegen.c 5630 2006-10-02 13:16:20Z edwin $
50 #include "vm/jit/alpha/arch.h"
51 #include "vm/jit/alpha/codegen.h"
53 #include "native/jni.h"
54 #include "native/native.h"
56 #if defined(ENABLE_THREADS)
57 # include "threads/native/lock.h"
60 #include "vm/builtin.h"
61 #include "vm/exceptions.h"
62 #include "vm/global.h"
63 #include "vm/loader.h"
64 #include "vm/options.h"
65 #include "vm/stringlocal.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit-common.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
82 /* codegen *********************************************************************
84 Generates machine code.
86 *******************************************************************************/
88 bool codegen(jitdata *jd)
94 s4 len, s1, s2, s3, d, disp;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
104 rplpoint *replacementpoint;
108 /* get required compiler data */
115 /* prevent compiler warnings */
126 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
128 /* space to save used callee saved registers */
130 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
131 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
133 cd->stackframesize = rd->memuse + savedregs_num;
135 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
136 if (checksync && (m->flags & ACC_SYNCHRONIZED))
137 cd->stackframesize++;
140 /* create method header */
143 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
146 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
147 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
149 #if defined(ENABLE_THREADS)
150 /* IsSync contains the offset relative to the stack pointer for the
151 argument of monitor_exit used in the exception handler. Since the
152 offset could be zero and give a wrong meaning of the flag it is
156 if (checksync && (m->flags & ACC_SYNCHRONIZED))
157 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
160 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
162 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
163 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
164 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
166 dseg_addlinenumbertablesize(cd);
168 (void) dseg_add_unique_s4(cd, cd->exceptiontablelength); /* ExTableSize */
170 /* create exception table */
172 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
173 dseg_add_target(cd, ex->start);
174 dseg_add_target(cd, ex->end);
175 dseg_add_target(cd, ex->handler);
176 (void) dseg_add_unique_address(cd, ex->catchtype.any);
179 /* create stack frame (if necessary) */
181 if (cd->stackframesize)
182 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
184 /* save return address and used callee saved registers */
186 p = cd->stackframesize;
187 if (!jd->isleafmethod) {
188 p--; M_AST(REG_RA, REG_SP, p * 8);
190 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
191 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
193 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
194 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
197 /* take arguments out of register or stack frame */
201 for (p = 0, l = 0; p < md->paramcount; p++) {
202 t = md->paramtypes[p].type;
204 varindex = jd->local_map[l * 5 + t];
207 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
210 if (varindex == UNUSED)
215 s1 = md->params[p].regoff;
217 if (IS_INT_LNG_TYPE(t)) { /* integer args */
218 if (!md->params[p].inmemory) { /* register arguments */
219 s2 = rd->argintregs[s1];
220 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
221 M_INTMOVE(s2, var->vv.regoff);
223 } else { /* reg arg -> spilled */
224 M_LST(s2, REG_SP, var->vv.regoff * 8);
227 } else { /* stack arguments */
228 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
229 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
231 } else { /* stack arg -> spilled */
232 var->vv.regoff = cd->stackframesize + s1;
236 } else { /* floating args */
237 if (!md->params[p].inmemory) { /* register arguments */
238 s2 = rd->argfltregs[s1];
239 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
240 M_FLTMOVE(s2, var->vv.regoff);
242 } else { /* reg arg -> spilled */
243 M_DST(s2, REG_SP, var->vv.regoff * 8);
246 } else { /* stack arguments */
247 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
248 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
250 } else { /* stack-arg -> spilled */
251 var->vv.regoff = cd->stackframesize + s1;
257 /* call monitorenter function */
259 #if defined(ENABLE_THREADS)
260 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
261 /* stack offset for monitor argument */
266 if (opt_verbosecall) {
267 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
269 for (p = 0; p < INT_ARG_CNT; p++)
270 M_LST(rd->argintregs[p], REG_SP, p * 8);
272 for (p = 0; p < FLT_ARG_CNT; p++)
273 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
275 s1 += INT_ARG_CNT + FLT_ARG_CNT;
277 #endif /* !defined(NDEBUG) */
279 /* decide which monitor enter function to call */
281 if (m->flags & ACC_STATIC) {
282 disp = dseg_add_address(cd, &m->class->object.header);
283 M_ALD(REG_A0, REG_PV, disp);
287 codegen_add_nullpointerexception_ref(cd);
290 M_AST(REG_A0, REG_SP, s1 * 8);
291 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
292 M_ALD(REG_PV, REG_PV, disp);
293 M_JSR(REG_RA, REG_PV);
294 disp = (s4) (cd->mcodeptr - cd->mcodebase);
295 M_LDA(REG_PV, REG_RA, -disp);
298 if (opt_verbosecall) {
299 for (p = 0; p < INT_ARG_CNT; p++)
300 M_LLD(rd->argintregs[p], REG_SP, p * 8);
302 for (p = 0; p < FLT_ARG_CNT; p++)
303 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
305 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
307 #endif /* !defined(NDEBUG) */
311 /* call trace function */
314 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
315 emit_verbosecall_enter(jd);
320 /* end of header generation */
322 replacementpoint = jd->code->rplpoints;
324 /* walk through all basic blocks */
326 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
328 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
330 if (bptr->flags >= BBREACHED) {
332 /* branch resolving */
336 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
337 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
338 brefs->branchpos, bptr->mpc);
342 /* handle replacement points */
345 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
346 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
352 /* copy interface registers to their destination */
356 #if defined(ENABLE_LSRA)
360 src = bptr->invars[len];
361 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
362 /* d = reg_of_var(m, src, REG_ITMP1); */
363 if (!(src->flags & INMEMORY))
367 M_INTMOVE(REG_ITMP1, d);
368 emit_store(jd, NULL, src, d);
375 var = VAR(bptr->invars[len]);
376 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
377 d = codegen_reg_of_var(0, var, REG_ITMP1);
378 M_INTMOVE(REG_ITMP1, d);
379 emit_store(jd, NULL, var, d);
383 assert((var->flags & OUTVAR));
386 #if defined(ENABLE_LSRA)
390 /* walk through all instructions */
394 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
395 if (iptr->line != currentline) {
396 dseg_addlinenumber(cd, iptr->line);
397 currentline = iptr->line;
400 MCODECHECK(64); /* an instruction usually needs < 64 words */
403 case ICMD_INLINE_START:
404 case ICMD_INLINE_END:
407 case ICMD_NOP: /* ... ==> ... */
410 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
412 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
414 codegen_add_nullpointerexception_ref(cd);
417 /* constant operations ************************************************/
419 case ICMD_ICONST: /* ... ==> ..., constant */
421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
422 ICONST(d, iptr->sx.val.i);
423 emit_store_dst(jd, iptr, d);
426 case ICMD_LCONST: /* ... ==> ..., constant */
428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
429 LCONST(d, iptr->sx.val.l);
430 emit_store_dst(jd, iptr, d);
433 case ICMD_FCONST: /* ... ==> ..., constant */
435 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
436 disp = dseg_add_float(cd, iptr->sx.val.f);
437 M_FLD(d, REG_PV, disp);
438 emit_store_dst(jd, iptr, d);
441 case ICMD_DCONST: /* ... ==> ..., constant */
443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
444 disp = dseg_add_double(cd, iptr->sx.val.d);
445 M_DLD(d, REG_PV, disp);
446 emit_store_dst(jd, iptr, d);
449 case ICMD_ACONST: /* ... ==> ..., constant */
451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
453 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
454 constant_classref *cr = iptr->sx.val.c.ref;
456 disp = dseg_add_unique_address(cd, cr);
458 /* XXX Only add the patcher, if this position needs to
459 be patched. If there was a previous position which
460 resolved the same class, the returned displacement
461 of dseg_addaddress is ok to use. */
463 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
466 if (opt_showdisassemble)
469 M_ALD(d, REG_PV, disp);
472 if (iptr->sx.val.anyptr == NULL)
473 M_INTMOVE(REG_ZERO, d);
475 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
476 M_ALD(d, REG_PV, disp);
479 emit_store_dst(jd, iptr, d);
483 /* load/store/move/copy operations ************************************/
485 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
486 case ICMD_ALOAD: /* s1 = local variable */
490 case ICMD_ISTORE: /* ..., value ==> ... */
491 case ICMD_ASTORE: /* dst = local variable */
498 M_COPY(iptr->s1.varindex, iptr->dst.varindex);
502 /* pop operations *****************************************************/
504 /* attention: double and longs are only one entry in CACAO ICMDs */
506 case ICMD_POP: /* ..., value ==> ... */
507 case ICMD_POP2: /* ..., value, value ==> ... */
512 /* integer operations *************************************************/
514 case ICMD_INEG: /* ..., value ==> ..., - value */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
518 M_ISUB(REG_ZERO, s1, d);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_LNEG: /* ..., value ==> ..., - value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
526 M_LSUB(REG_ZERO, s1, d);
527 emit_store_dst(jd, iptr, d);
530 case ICMD_I2L: /* ..., value ==> ..., value */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
535 emit_store_dst(jd, iptr, d);
538 case ICMD_L2I: /* ..., value ==> ..., value */
540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
542 M_IADD(s1, REG_ZERO, d);
543 emit_store_dst(jd, iptr, d);
546 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550 if (has_ext_instr_set) {
553 M_SLL_IMM(s1, 56, d);
554 M_SRA_IMM( d, 56, d);
556 emit_store_dst(jd, iptr, d);
559 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 emit_store_dst(jd, iptr, d);
567 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
571 if (has_ext_instr_set) {
574 M_SLL_IMM(s1, 48, d);
575 M_SRA_IMM( d, 48, d);
577 emit_store_dst(jd, iptr, d);
581 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
587 emit_store_dst(jd, iptr, d);
590 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
591 /* sx.val.i = constant */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
595 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
596 M_IADD_IMM(s1, iptr->sx.val.i, d);
598 ICONST(REG_ITMP2, iptr->sx.val.i);
599 M_IADD(s1, REG_ITMP2, d);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
608 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
610 emit_store_dst(jd, iptr, d);
613 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
614 /* sx.val.l = constant */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
619 M_LADD_IMM(s1, iptr->sx.val.l, d);
621 LCONST(REG_ITMP2, iptr->sx.val.l);
622 M_LADD(s1, REG_ITMP2, d);
624 emit_store_dst(jd, iptr, d);
627 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
631 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
637 /* sx.val.i = constant */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
642 M_ISUB_IMM(s1, iptr->sx.val.i, d);
644 ICONST(REG_ITMP2, iptr->sx.val.i);
645 M_ISUB(s1, REG_ITMP2, d);
647 emit_store_dst(jd, iptr, d);
650 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
654 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
656 emit_store_dst(jd, iptr, d);
659 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
660 /* sx.val.l = constant */
662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
665 M_LSUB_IMM(s1, iptr->sx.val.l, d);
667 LCONST(REG_ITMP2, iptr->sx.val.l);
668 M_LSUB(s1, REG_ITMP2, d);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
683 /* sx.val.i = constant */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
687 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
688 M_IMUL_IMM(s1, iptr->sx.val.i, d);
690 ICONST(REG_ITMP2, iptr->sx.val.i);
691 M_IMUL(s1, REG_ITMP2, d);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
706 /* sx.val.l = constant */
708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
711 M_LMUL_IMM(s1, iptr->sx.val.l, d);
713 LCONST(REG_ITMP2, iptr->sx.val.l);
714 M_LMUL(s1, REG_ITMP2, d);
716 emit_store_dst(jd, iptr, d);
719 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
720 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
724 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
726 codegen_add_arithmeticexception_ref(cd);
730 bte = iptr->sx.s23.s3.bte;
731 disp = dseg_add_functionptr(cd, bte->fp);
732 M_ALD(REG_PV, REG_PV, disp);
733 M_JSR(REG_RA, REG_PV);
734 disp = (s4) (cd->mcodeptr - cd->mcodebase);
735 M_LDA(REG_PV, REG_RA, -disp);
737 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
738 emit_store_dst(jd, iptr, d);
741 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
742 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
744 bte = iptr->sx.s23.s3.bte;
746 s1 = emit_load_s1(jd, iptr, REG_A0);
747 s2 = emit_load_s2(jd, iptr, REG_A1);
748 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
750 codegen_add_arithmeticexception_ref(cd);
752 M_INTMOVE(s1, REG_A0);
753 M_INTMOVE(s2, REG_A1);
754 disp = dseg_add_functionptr(cd, bte->fp);
755 M_ALD(REG_PV, REG_PV, disp);
756 M_JSR(REG_RA, REG_PV);
757 disp = (s4) (cd->mcodeptr - cd->mcodebase);
758 M_LDA(REG_PV, REG_RA, -disp);
760 M_INTMOVE(REG_RESULT, d);
761 emit_store_dst(jd, iptr, d);
764 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
765 case ICMD_LDIVPOW2: /* val.i = constant */
767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
768 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
769 if (iptr->sx.val.i <= 15) {
770 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
771 M_CMOVGE(s1, s1, REG_ITMP2);
773 M_SRA_IMM(s1, 63, REG_ITMP2);
774 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
775 M_LADD(s1, REG_ITMP2, REG_ITMP2);
777 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
778 emit_store_dst(jd, iptr, d);
781 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
786 M_AND_IMM(s2, 0x1f, REG_ITMP3);
787 M_SLL(s1, REG_ITMP3, d);
788 M_IADD(d, REG_ZERO, d);
789 emit_store_dst(jd, iptr, d);
792 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
793 /* sx.val.i = constant */
795 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
797 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
798 M_IADD(d, REG_ZERO, d);
799 emit_store_dst(jd, iptr, d);
802 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
807 M_AND_IMM(s2, 0x1f, REG_ITMP3);
808 M_SRA(s1, REG_ITMP3, d);
809 emit_store_dst(jd, iptr, d);
812 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
813 /* sx.val.i = constant */
815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
818 emit_store_dst(jd, iptr, d);
821 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
826 M_AND_IMM(s2, 0x1f, REG_ITMP2);
828 M_SRL(d, REG_ITMP2, d);
829 M_IADD(d, REG_ZERO, d);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
834 /* sx.val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
839 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
840 M_IADD(d, REG_ZERO, d);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 emit_store_dst(jd, iptr, d);
853 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
854 /* sx.val.i = constant */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
858 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
859 emit_store_dst(jd, iptr, d);
862 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 emit_store_dst(jd, iptr, d);
871 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
872 /* sx.val.i = constant */
874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
877 emit_store_dst(jd, iptr, d);
880 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
883 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
886 emit_store_dst(jd, iptr, d);
889 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
890 /* sx.val.i = constant */
892 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
893 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
894 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
895 emit_store_dst(jd, iptr, d);
898 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
902 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
903 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
909 /* sx.val.i = constant */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
913 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
914 M_AND_IMM(s1, iptr->sx.val.i, d);
915 } else if (iptr->sx.val.i == 0xffff) {
917 } else if (iptr->sx.val.i == 0xffffff) {
918 M_ZAPNOT_IMM(s1, 0x07, d);
920 ICONST(REG_ITMP2, iptr->sx.val.i);
921 M_AND(s1, REG_ITMP2, d);
923 emit_store_dst(jd, iptr, d);
926 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
927 /* sx.val.i = constant */
929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
930 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932 M_MOV(s1, REG_ITMP1);
935 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
936 M_AND_IMM(s1, iptr->sx.val.i, d);
938 M_ISUB(REG_ZERO, s1, d);
939 M_AND_IMM(d, iptr->sx.val.i, d);
940 } else if (iptr->sx.val.i == 0xffff) {
943 M_ISUB(REG_ZERO, s1, d);
945 } else if (iptr->sx.val.i == 0xffffff) {
946 M_ZAPNOT_IMM(s1, 0x07, d);
948 M_ISUB(REG_ZERO, s1, d);
949 M_ZAPNOT_IMM(d, 0x07, d);
951 ICONST(REG_ITMP2, iptr->sx.val.i);
952 M_AND(s1, REG_ITMP2, d);
954 M_ISUB(REG_ZERO, s1, d);
955 M_AND(d, REG_ITMP2, d);
957 M_ISUB(REG_ZERO, d, d);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
962 /* sx.val.l = constant */
964 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
965 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
966 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
967 M_AND_IMM(s1, iptr->sx.val.l, d);
968 } else if (iptr->sx.val.l == 0xffffL) {
970 } else if (iptr->sx.val.l == 0xffffffL) {
971 M_ZAPNOT_IMM(s1, 0x07, d);
972 } else if (iptr->sx.val.l == 0xffffffffL) {
974 } else if (iptr->sx.val.l == 0xffffffffffL) {
975 M_ZAPNOT_IMM(s1, 0x1f, d);
976 } else if (iptr->sx.val.l == 0xffffffffffffL) {
977 M_ZAPNOT_IMM(s1, 0x3f, d);
978 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
979 M_ZAPNOT_IMM(s1, 0x7f, d);
981 LCONST(REG_ITMP2, iptr->sx.val.l);
982 M_AND(s1, REG_ITMP2, d);
984 emit_store_dst(jd, iptr, d);
987 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
988 /* sx.val.l = constant */
990 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
991 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
993 M_MOV(s1, REG_ITMP1);
996 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
997 M_AND_IMM(s1, iptr->sx.val.l, d);
999 M_LSUB(REG_ZERO, s1, d);
1000 M_AND_IMM(d, iptr->sx.val.l, d);
1001 } else if (iptr->sx.val.l == 0xffffL) {
1004 M_LSUB(REG_ZERO, s1, d);
1006 } else if (iptr->sx.val.l == 0xffffffL) {
1007 M_ZAPNOT_IMM(s1, 0x07, d);
1009 M_LSUB(REG_ZERO, s1, d);
1010 M_ZAPNOT_IMM(d, 0x07, d);
1011 } else if (iptr->sx.val.l == 0xffffffffL) {
1014 M_LSUB(REG_ZERO, s1, d);
1016 } else if (iptr->sx.val.l == 0xffffffffffL) {
1017 M_ZAPNOT_IMM(s1, 0x1f, d);
1019 M_LSUB(REG_ZERO, s1, d);
1020 M_ZAPNOT_IMM(d, 0x1f, d);
1021 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1022 M_ZAPNOT_IMM(s1, 0x3f, d);
1024 M_LSUB(REG_ZERO, s1, d);
1025 M_ZAPNOT_IMM(d, 0x3f, d);
1026 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1027 M_ZAPNOT_IMM(s1, 0x7f, d);
1029 M_LSUB(REG_ZERO, s1, d);
1030 M_ZAPNOT_IMM(d, 0x7f, d);
1032 LCONST(REG_ITMP2, iptr->sx.val.l);
1033 M_AND(s1, REG_ITMP2, d);
1035 M_LSUB(REG_ZERO, s1, d);
1036 M_AND(d, REG_ITMP2, d);
1038 M_LSUB(REG_ZERO, d, d);
1039 emit_store_dst(jd, iptr, d);
1042 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1046 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1049 emit_store_dst(jd, iptr, d);
1052 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1053 /* sx.val.i = constant */
1055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1056 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1057 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1058 M_OR_IMM(s1, iptr->sx.val.i, d);
1060 ICONST(REG_ITMP2, iptr->sx.val.i);
1061 M_OR(s1, REG_ITMP2, d);
1063 emit_store_dst(jd, iptr, d);
1066 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1067 /* sx.val.l = constant */
1069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1070 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1072 M_OR_IMM(s1, iptr->sx.val.l, d);
1074 LCONST(REG_ITMP2, iptr->sx.val.l);
1075 M_OR(s1, REG_ITMP2, d);
1077 emit_store_dst(jd, iptr, d);
1080 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1084 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1085 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1091 /* sx.val.i = constant */
1093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1094 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1095 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1096 M_XOR_IMM(s1, iptr->sx.val.i, d);
1098 ICONST(REG_ITMP2, iptr->sx.val.i);
1099 M_XOR(s1, REG_ITMP2, d);
1101 emit_store_dst(jd, iptr, d);
1104 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1105 /* sx.val.l = constant */
1107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1108 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1109 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1110 M_XOR_IMM(s1, iptr->sx.val.l, d);
1112 LCONST(REG_ITMP2, iptr->sx.val.l);
1113 M_XOR(s1, REG_ITMP2, d);
1115 emit_store_dst(jd, iptr, d);
1119 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1122 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1123 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1124 M_CMPLT(s1, s2, REG_ITMP3);
1125 M_CMPLT(s2, s1, REG_ITMP1);
1126 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1127 emit_store_dst(jd, iptr, d);
1131 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1132 /* s1.localindex = variable, sx.val.i = constant*/
1134 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1137 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1138 M_IADD_IMM(s1, iptr->sx.val.i, d);
1139 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
1140 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
1142 M_LDA (s1, s1, iptr->sx.val.i);
1143 M_IADD(s1, REG_ZERO, d);
1146 emit_store_dst(jd, iptr, d);
1150 /* floating operations ************************************************/
1152 case ICMD_FNEG: /* ..., value ==> ..., - value */
1154 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1157 emit_store_dst(jd, iptr, d);
1160 case ICMD_DNEG: /* ..., value ==> ..., - value */
1162 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1163 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1165 emit_store_dst(jd, iptr, d);
1168 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1170 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1171 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1172 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1176 if (d == s1 || d == s2) {
1177 M_FADDS(s1, s2, REG_FTMP3);
1179 M_FMOV(REG_FTMP3, d);
1185 emit_store_dst(jd, iptr, d);
1188 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1190 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1191 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1196 if (d == s1 || d == s2) {
1197 M_DADDS(s1, s2, REG_FTMP3);
1199 M_FMOV(REG_FTMP3, d);
1205 emit_store_dst(jd, iptr, d);
1208 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1210 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1211 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1212 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1216 if (d == s1 || d == s2) {
1217 M_FSUBS(s1, s2, REG_FTMP3);
1219 M_FMOV(REG_FTMP3, d);
1225 emit_store_dst(jd, iptr, d);
1228 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1230 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1231 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1232 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1236 if (d == s1 || d == s2) {
1237 M_DSUBS(s1, s2, REG_FTMP3);
1239 M_FMOV(REG_FTMP3, d);
1245 emit_store_dst(jd, iptr, d);
1248 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1250 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1251 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1252 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1256 if (d == s1 || d == s2) {
1257 M_FMULS(s1, s2, REG_FTMP3);
1259 M_FMOV(REG_FTMP3, d);
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1270 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1271 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1272 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1276 if (d == s1 || d == s2) {
1277 M_DMULS(s1, s2, REG_FTMP3);
1279 M_FMOV(REG_FTMP3, d);
1285 emit_store_dst(jd, iptr, d);
1288 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1290 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1291 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1292 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1296 if (d == s1 || d == s2) {
1297 M_FDIVS(s1, s2, REG_FTMP3);
1299 M_FMOV(REG_FTMP3, d);
1305 emit_store_dst(jd, iptr, d);
1308 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1310 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1311 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1312 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1316 if (d == s1 || d == s2) {
1317 M_DDIVS(s1, s2, REG_FTMP3);
1319 M_FMOV(REG_FTMP3, d);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1330 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1332 disp = dseg_add_unique_double(cd, 0.0);
1333 M_LST(s1, REG_PV, disp);
1334 M_DLD(d, REG_PV, disp);
1336 emit_store_dst(jd, iptr, d);
1339 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1341 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1342 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1343 disp = dseg_add_unique_double(cd, 0.0);
1344 M_LST(s1, REG_PV, disp);
1345 M_DLD(d, REG_PV, disp);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1352 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1354 disp = dseg_add_unique_double(cd, 0.0);
1355 M_CVTDL_C(s1, REG_FTMP2);
1356 M_CVTLI(REG_FTMP2, REG_FTMP3);
1357 M_DST(REG_FTMP3, REG_PV, disp);
1358 M_ILD(d, REG_PV, disp);
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1364 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1366 disp = dseg_add_unique_double(cd, 0.0);
1367 M_CVTDL_C(s1, REG_FTMP2);
1368 M_DST(REG_FTMP2, REG_PV, disp);
1369 M_LLD(d, REG_PV, disp);
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1375 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1376 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1384 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1385 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1392 emit_store_dst(jd, iptr, d);
1395 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1397 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1398 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1401 M_LSUB_IMM(REG_ZERO, 1, d);
1402 M_FCMPEQ(s1, s2, REG_FTMP3);
1403 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1405 M_FCMPLT(s2, s1, REG_FTMP3);
1406 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1407 M_LADD_IMM(REG_ZERO, 1, d);
1409 M_LSUB_IMM(REG_ZERO, 1, d);
1410 M_FCMPEQS(s1, s2, REG_FTMP3);
1412 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1414 M_FCMPLTS(s2, s1, REG_FTMP3);
1416 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1417 M_LADD_IMM(REG_ZERO, 1, d);
1419 emit_store_dst(jd, iptr, d);
1422 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1424 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1425 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1428 M_LADD_IMM(REG_ZERO, 1, d);
1429 M_FCMPEQ(s1, s2, REG_FTMP3);
1430 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1432 M_FCMPLT(s1, s2, REG_FTMP3);
1433 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1434 M_LSUB_IMM(REG_ZERO, 1, d);
1436 M_LADD_IMM(REG_ZERO, 1, d);
1437 M_FCMPEQS(s1, s2, REG_FTMP3);
1439 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1441 M_FCMPLTS(s1, s2, REG_FTMP3);
1443 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1444 M_LSUB_IMM(REG_ZERO, 1, d);
1446 emit_store_dst(jd, iptr, d);
1450 /* memory operations **************************************************/
1452 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1454 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1456 gen_nullptr_check(s1);
1457 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1458 emit_store_dst(jd, iptr, d);
1461 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1464 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1465 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1466 if (INSTRUCTION_MUST_CHECK(iptr)) {
1467 gen_nullptr_check(s1);
1470 if (has_ext_instr_set) {
1471 M_LADD (s2, s1, REG_ITMP1);
1472 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1475 M_LADD(s2, s1, REG_ITMP1);
1476 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1477 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1478 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1479 M_SRA_IMM(d, 56, d);
1481 emit_store_dst(jd, iptr, d);
1484 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1488 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1489 if (INSTRUCTION_MUST_CHECK(iptr)) {
1490 gen_nullptr_check(s1);
1493 if (has_ext_instr_set) {
1494 M_LADD(s2, s1, REG_ITMP1);
1495 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1496 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1498 M_LADD (s2, s1, REG_ITMP1);
1499 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1500 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1501 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1502 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1504 emit_store_dst(jd, iptr, d);
1507 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1510 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1512 if (INSTRUCTION_MUST_CHECK(iptr)) {
1513 gen_nullptr_check(s1);
1516 if (has_ext_instr_set) {
1517 M_LADD(s2, s1, REG_ITMP1);
1518 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1519 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1522 M_LADD(s2, s1, REG_ITMP1);
1523 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1524 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1525 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1526 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1527 M_SRA_IMM(d, 48, d);
1529 emit_store_dst(jd, iptr, d);
1532 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1535 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1536 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1537 if (INSTRUCTION_MUST_CHECK(iptr)) {
1538 gen_nullptr_check(s1);
1541 M_S4ADDQ(s2, s1, REG_ITMP1);
1542 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1543 emit_store_dst(jd, iptr, d);
1546 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1551 if (INSTRUCTION_MUST_CHECK(iptr)) {
1552 gen_nullptr_check(s1);
1555 M_S8ADDQ(s2, s1, REG_ITMP1);
1556 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1557 emit_store_dst(jd, iptr, d);
1560 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1563 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1564 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1565 if (INSTRUCTION_MUST_CHECK(iptr)) {
1566 gen_nullptr_check(s1);
1569 M_S4ADDQ(s2, s1, REG_ITMP1);
1570 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1571 emit_store_dst(jd, iptr, d);
1574 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1578 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1579 if (INSTRUCTION_MUST_CHECK(iptr)) {
1580 gen_nullptr_check(s1);
1583 M_S8ADDQ(s2, s1, REG_ITMP1);
1584 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1585 emit_store_dst(jd, iptr, d);
1588 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1591 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1593 if (INSTRUCTION_MUST_CHECK(iptr)) {
1594 gen_nullptr_check(s1);
1597 M_SAADDQ(s2, s1, REG_ITMP1);
1598 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1599 emit_store_dst(jd, iptr, d);
1603 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1607 if (INSTRUCTION_MUST_CHECK(iptr)) {
1608 gen_nullptr_check(s1);
1611 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1612 if (has_ext_instr_set) {
1613 M_LADD(s2, s1, REG_ITMP1);
1614 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1616 M_LADD(s2, s1, REG_ITMP1);
1617 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1618 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1619 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1620 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1621 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1622 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1626 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1629 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1630 if (INSTRUCTION_MUST_CHECK(iptr)) {
1631 gen_nullptr_check(s1);
1634 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1635 if (has_ext_instr_set) {
1636 M_LADD(s2, s1, REG_ITMP1);
1637 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1638 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1640 M_LADD(s2, s1, REG_ITMP1);
1641 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1642 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1643 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1644 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1645 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1646 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1647 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1651 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1655 if (INSTRUCTION_MUST_CHECK(iptr)) {
1656 gen_nullptr_check(s1);
1659 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1660 if (has_ext_instr_set) {
1661 M_LADD(s2, s1, REG_ITMP1);
1662 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1663 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1665 M_LADD(s2, s1, REG_ITMP1);
1666 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1667 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1668 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1669 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1670 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1671 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1672 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1676 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1680 if (INSTRUCTION_MUST_CHECK(iptr)) {
1681 gen_nullptr_check(s1);
1684 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1685 M_S4ADDQ(s2, s1, REG_ITMP1);
1686 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1689 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1692 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1693 if (INSTRUCTION_MUST_CHECK(iptr)) {
1694 gen_nullptr_check(s1);
1697 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1698 M_S8ADDQ(s2, s1, REG_ITMP1);
1699 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1702 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1706 if (INSTRUCTION_MUST_CHECK(iptr)) {
1707 gen_nullptr_check(s1);
1710 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1711 M_S4ADDQ(s2, s1, REG_ITMP1);
1712 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1715 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1719 if (INSTRUCTION_MUST_CHECK(iptr)) {
1720 gen_nullptr_check(s1);
1723 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1724 M_S8ADDQ(s2, s1, REG_ITMP1);
1725 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1728 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1730 s1 = emit_load_s1(jd, iptr, REG_A0);
1731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1732 if (INSTRUCTION_MUST_CHECK(iptr)) {
1733 gen_nullptr_check(s1);
1736 s3 = emit_load_s3(jd, iptr, REG_A1);
1738 M_INTMOVE(s1, REG_A0);
1739 M_INTMOVE(s3, REG_A1);
1741 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1742 M_ALD(REG_PV, REG_PV, disp);
1743 M_JSR(REG_RA, REG_PV);
1744 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1745 M_LDA(REG_PV, REG_RA, -disp);
1747 M_BEQZ(REG_RESULT, 0);
1748 codegen_add_arraystoreexception_ref(cd);
1750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1752 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1753 M_SAADDQ(s2, s1, REG_ITMP1);
1754 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1758 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1761 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1762 if (INSTRUCTION_MUST_CHECK(iptr)) {
1763 gen_nullptr_check(s1);
1766 M_S4ADDQ(s2, s1, REG_ITMP1);
1767 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1770 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1774 if (INSTRUCTION_MUST_CHECK(iptr)) {
1775 gen_nullptr_check(s1);
1778 M_S8ADDQ(s2, s1, REG_ITMP1);
1779 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1782 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1786 if (INSTRUCTION_MUST_CHECK(iptr)) {
1787 gen_nullptr_check(s1);
1790 M_SAADDQ(s2, s1, REG_ITMP1);
1791 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1794 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1797 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1798 if (INSTRUCTION_MUST_CHECK(iptr)) {
1799 gen_nullptr_check(s1);
1802 if (has_ext_instr_set) {
1803 M_LADD(s2, s1, REG_ITMP1);
1804 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1807 M_LADD(s2, s1, REG_ITMP1);
1808 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1809 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1810 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1811 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1812 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1813 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1817 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1820 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1821 if (INSTRUCTION_MUST_CHECK(iptr)) {
1822 gen_nullptr_check(s1);
1825 if (has_ext_instr_set) {
1826 M_LADD(s2, s1, REG_ITMP1);
1827 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1828 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1831 M_LADD(s2, s1, REG_ITMP1);
1832 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1833 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1834 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1835 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1836 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1837 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1838 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1842 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1844 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1845 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1846 if (INSTRUCTION_MUST_CHECK(iptr)) {
1847 gen_nullptr_check(s1);
1850 if (has_ext_instr_set) {
1851 M_LADD(s2, s1, REG_ITMP1);
1852 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1853 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1856 M_LADD(s2, s1, REG_ITMP1);
1857 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1858 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1859 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1860 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1861 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1862 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1863 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1868 case ICMD_GETSTATIC: /* ... ==> ..., value */
1870 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1871 unresolved_field *uf = iptr->sx.s23.s3.uf;
1873 fieldtype = uf->fieldref->parseddesc.fd->type;
1875 disp = dseg_add_unique_address(cd, uf);
1877 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1879 if (opt_showdisassemble)
1883 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1885 fieldtype = fi->type;
1886 disp = dseg_add_address(cd, &(fi->value));
1888 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1889 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1892 if (opt_showdisassemble)
1897 M_ALD(REG_ITMP1, REG_PV, disp);
1898 switch (fieldtype) {
1900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1901 M_ILD(d, REG_ITMP1, 0);
1904 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1905 M_LLD(d, REG_ITMP1, 0);
1908 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1909 M_ALD(d, REG_ITMP1, 0);
1912 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1913 M_FLD(d, REG_ITMP1, 0);
1916 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1917 M_DLD(d, REG_ITMP1, 0);
1920 emit_store_dst(jd, iptr, d);
1923 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1925 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1926 unresolved_field *uf = iptr->sx.s23.s3.uf;
1928 fieldtype = uf->fieldref->parseddesc.fd->type;
1930 disp = dseg_add_unique_address(cd, uf);
1932 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1934 if (opt_showdisassemble)
1938 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1940 fieldtype = fi->type;
1941 disp = dseg_add_address(cd, &(fi->value));
1943 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1944 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1947 if (opt_showdisassemble)
1952 M_ALD(REG_ITMP1, REG_PV, disp);
1953 switch (fieldtype) {
1955 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1956 M_IST(s1, REG_ITMP1, 0);
1959 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1960 M_LST(s1, REG_ITMP1, 0);
1963 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1964 M_AST(s1, REG_ITMP1, 0);
1967 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1968 M_FST(s1, REG_ITMP1, 0);
1971 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1972 M_DST(s1, REG_ITMP1, 0);
1977 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1978 /* val = value (in current instruction) */
1979 /* following NOP) */
1981 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1982 unresolved_field *uf = iptr->sx.s23.s3.uf;
1984 fieldtype = uf->fieldref->parseddesc.fd->type;
1986 disp = dseg_add_unique_address(cd, uf);
1988 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1990 if (opt_showdisassemble)
1994 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1996 fieldtype = fi->type;
1997 disp = dseg_add_address(cd, &(fi->value));
1999 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2000 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
2003 if (opt_showdisassemble)
2008 M_ALD(REG_ITMP1, REG_PV, disp);
2009 switch (fieldtype) {
2011 M_IST(REG_ZERO, REG_ITMP1, 0);
2014 M_LST(REG_ZERO, REG_ITMP1, 0);
2017 M_AST(REG_ZERO, REG_ITMP1, 0);
2020 M_FST(REG_ZERO, REG_ITMP1, 0);
2023 M_DST(REG_ZERO, REG_ITMP1, 0);
2029 case ICMD_GETFIELD: /* ... ==> ..., value */
2031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2032 gen_nullptr_check(s1);
2034 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2035 unresolved_field *uf = iptr->sx.s23.s3.uf;
2037 fieldtype = uf->fieldref->parseddesc.fd->type;
2039 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2041 if (opt_showdisassemble)
2047 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2049 fieldtype = fi->type;
2053 switch (fieldtype) {
2055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2059 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2063 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2067 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2071 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2075 emit_store_dst(jd, iptr, d);
2078 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2081 gen_nullptr_check(s1);
2083 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2084 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2086 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2089 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2090 unresolved_field *uf = iptr->sx.s23.s3.uf;
2092 fieldtype = uf->fieldref->parseddesc.fd->type;
2094 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2096 if (opt_showdisassemble)
2102 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2104 fieldtype = fi->type;
2108 switch (fieldtype) {
2110 M_IST(s2, s1, disp);
2113 M_LST(s2, s1, disp);
2116 M_AST(s2, s1, disp);
2119 M_FST(s2, s1, disp);
2122 M_DST(s2, s1, disp);
2127 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2128 /* val = value (in current instruction) */
2129 /* following NOP) */
2131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2132 gen_nullptr_check(s1);
2134 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2135 unresolved_field *uf = iptr->sx.s23.s3.uf;
2137 fieldtype = uf->fieldref->parseddesc.fd->type;
2139 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2141 if (opt_showdisassemble)
2147 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2149 fieldtype = fi->type;
2153 switch (fieldtype) {
2155 M_IST(REG_ZERO, s1, disp);
2158 M_LST(REG_ZERO, s1, disp);
2161 M_AST(REG_ZERO, s1, disp);
2164 M_FST(REG_ZERO, s1, disp);
2167 M_DST(REG_ZERO, s1, disp);
2173 /* branch operations **************************************************/
2175 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2177 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2178 M_INTMOVE(s1, REG_ITMP1_XPTR);
2180 #ifdef ENABLE_VERIFIER
2181 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2182 unresolved_class *uc = iptr->sx.s23.s2.uc;
2184 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2186 if (opt_showdisassemble)
2189 #endif /* ENABLE_VERIFIER */
2191 disp = dseg_add_functionptr(cd, asm_handle_exception);
2192 M_ALD(REG_ITMP2, REG_PV, disp);
2193 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2194 M_NOP; /* nop ensures that XPC is less than the end */
2195 /* of basic block */
2199 case ICMD_GOTO: /* ... ==> ... */
2201 codegen_addreference(cd, iptr->dst.block);
2205 case ICMD_JSR: /* ... ==> ... */
2207 M_BSR(REG_ITMP1, 0);
2208 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2211 case ICMD_RET: /* ... ==> ... */
2212 /* s1.localindex = local variable */
2215 codegen_addreference(cd, iptr->dst.block);
2216 /* var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]); */
2217 /* if (var->flags & INMEMORY) { */
2218 /* M_ALD(REG_ITMP1, REG_SP, 8 * var->vv.regoff); */
2219 /* M_RET(REG_ZERO, REG_ITMP1); */
2222 /* M_RET(REG_ZERO, var->vv.regoff); */
2226 case ICMD_IFNULL: /* ..., value ==> ... */
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2230 codegen_addreference(cd, iptr->dst.block);
2233 case ICMD_IFNONNULL: /* ..., value ==> ... */
2235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2237 codegen_addreference(cd, iptr->dst.block);
2240 case ICMD_IFEQ: /* ..., value ==> ... */
2242 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2243 if (iptr->sx.val.i == 0) {
2247 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2248 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2251 ICONST(REG_ITMP2, iptr->sx.val.i);
2252 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2254 M_BNEZ(REG_ITMP1, 0);
2256 codegen_addreference(cd, iptr->dst.block);
2259 case ICMD_IFLT: /* ..., value ==> ... */
2261 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2262 if (iptr->sx.val.i == 0) {
2266 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2267 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2270 ICONST(REG_ITMP2, iptr->sx.val.i);
2271 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2273 M_BNEZ(REG_ITMP1, 0);
2275 codegen_addreference(cd, iptr->dst.block);
2278 case ICMD_IFLE: /* ..., value ==> ... */
2280 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2281 if (iptr->sx.val.i == 0) {
2285 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2286 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2289 ICONST(REG_ITMP2, iptr->sx.val.i);
2290 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2292 M_BNEZ(REG_ITMP1, 0);
2294 codegen_addreference(cd, iptr->dst.block);
2297 case ICMD_IFNE: /* ..., value ==> ... */
2299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2300 if (iptr->sx.val.i == 0) {
2304 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2305 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2308 ICONST(REG_ITMP2, iptr->sx.val.i);
2309 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2311 M_BEQZ(REG_ITMP1, 0);
2313 codegen_addreference(cd, iptr->dst.block);
2316 case ICMD_IFGT: /* ..., value ==> ... */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 if (iptr->sx.val.i == 0) {
2323 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2324 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2327 ICONST(REG_ITMP2, iptr->sx.val.i);
2328 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2330 M_BEQZ(REG_ITMP1, 0);
2332 codegen_addreference(cd, iptr->dst.block);
2335 case ICMD_IFGE: /* ..., value ==> ... */
2337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2338 if (iptr->sx.val.i == 0) {
2342 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2343 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2346 ICONST(REG_ITMP2, iptr->sx.val.i);
2347 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2349 M_BEQZ(REG_ITMP1, 0);
2351 codegen_addreference(cd, iptr->dst.block);
2354 case ICMD_IF_LEQ: /* ..., value ==> ... */
2356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2357 if (iptr->sx.val.l == 0) {
2361 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2362 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2365 LCONST(REG_ITMP2, iptr->sx.val.l);
2366 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2368 M_BNEZ(REG_ITMP1, 0);
2370 codegen_addreference(cd, iptr->dst.block);
2373 case ICMD_IF_LLT: /* ..., value ==> ... */
2375 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2376 if (iptr->sx.val.l == 0) {
2380 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2381 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2384 LCONST(REG_ITMP2, iptr->sx.val.l);
2385 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2387 M_BNEZ(REG_ITMP1, 0);
2389 codegen_addreference(cd, iptr->dst.block);
2392 case ICMD_IF_LLE: /* ..., value ==> ... */
2394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2395 if (iptr->sx.val.l == 0) {
2399 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2400 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2403 LCONST(REG_ITMP2, iptr->sx.val.l);
2404 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2406 M_BNEZ(REG_ITMP1, 0);
2408 codegen_addreference(cd, iptr->dst.block);
2411 case ICMD_IF_LNE: /* ..., value ==> ... */
2413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2414 if (iptr->sx.val.l == 0) {
2418 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2419 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2422 LCONST(REG_ITMP2, iptr->sx.val.l);
2423 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2425 M_BEQZ(REG_ITMP1, 0);
2427 codegen_addreference(cd, iptr->dst.block);
2430 case ICMD_IF_LGT: /* ..., value ==> ... */
2432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2433 if (iptr->sx.val.l == 0) {
2437 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2438 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2441 LCONST(REG_ITMP2, iptr->sx.val.l);
2442 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2444 M_BEQZ(REG_ITMP1, 0);
2446 codegen_addreference(cd, iptr->dst.block);
2449 case ICMD_IF_LGE: /* ..., value ==> ... */
2451 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2452 if (iptr->sx.val.l == 0) {
2456 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2457 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2460 LCONST(REG_ITMP2, iptr->sx.val.l);
2461 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2463 M_BEQZ(REG_ITMP1, 0);
2465 codegen_addreference(cd, iptr->dst.block);
2468 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2469 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2470 case ICMD_IF_ACMPEQ:
2472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2473 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2474 M_CMPEQ(s1, s2, REG_ITMP1);
2475 M_BNEZ(REG_ITMP1, 0);
2476 codegen_addreference(cd, iptr->dst.block);
2479 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2480 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2481 case ICMD_IF_ACMPNE:
2483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2484 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2485 M_CMPEQ(s1, s2, REG_ITMP1);
2486 M_BEQZ(REG_ITMP1, 0);
2487 codegen_addreference(cd, iptr->dst.block);
2490 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2491 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2494 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2495 M_CMPLT(s1, s2, REG_ITMP1);
2496 M_BNEZ(REG_ITMP1, 0);
2497 codegen_addreference(cd, iptr->dst.block);
2500 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2501 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2504 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2505 M_CMPLE(s1, s2, REG_ITMP1);
2506 M_BEQZ(REG_ITMP1, 0);
2507 codegen_addreference(cd, iptr->dst.block);
2510 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2511 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2515 M_CMPLE(s1, s2, REG_ITMP1);
2516 M_BNEZ(REG_ITMP1, 0);
2517 codegen_addreference(cd, iptr->dst.block);
2520 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2521 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2524 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2525 M_CMPLT(s1, s2, REG_ITMP1);
2526 M_BEQZ(REG_ITMP1, 0);
2527 codegen_addreference(cd, iptr->dst.block);
2531 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2534 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2535 M_INTMOVE(s1, REG_RESULT);
2536 goto nowperformreturn;
2538 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2540 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2541 M_INTMOVE(s1, REG_RESULT);
2543 #ifdef ENABLE_VERIFIER
2544 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2545 unresolved_class *uc = iptr->sx.s23.s2.uc;
2547 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2549 if (opt_showdisassemble)
2552 #endif /* ENABLE_VERIFIER */
2553 goto nowperformreturn;
2555 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2558 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2559 M_FLTMOVE(s1, REG_FRESULT);
2560 goto nowperformreturn;
2562 case ICMD_RETURN: /* ... ==> ... */
2568 p = cd->stackframesize;
2570 /* call trace function */
2572 #if !defined(NDEBUG)
2573 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2574 emit_verbosecall_exit(jd);
2577 #if defined(ENABLE_THREADS)
2578 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2579 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2581 switch (iptr->opc) {
2585 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2589 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2593 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2594 M_ALD(REG_PV, REG_PV, disp);
2595 M_JSR(REG_RA, REG_PV);
2596 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2597 M_LDA(REG_PV, REG_RA, disp);
2599 switch (iptr->opc) {
2603 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2607 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2613 /* restore return address */
2615 if (!jd->isleafmethod) {
2616 p--; M_LLD(REG_RA, REG_SP, p * 8);
2619 /* restore saved registers */
2621 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2622 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2624 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2625 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2628 /* deallocate stack */
2630 if (cd->stackframesize)
2631 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2633 M_RET(REG_ZERO, REG_RA);
2639 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2642 branch_target_t *table;
2644 table = iptr->dst.table;
2646 l = iptr->sx.s23.s2.tablelow;
2647 i = iptr->sx.s23.s3.tablehigh;
2649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2651 M_INTMOVE(s1, REG_ITMP1);
2652 } else if (l <= 32768) {
2653 M_LDA(REG_ITMP1, s1, -l);
2655 ICONST(REG_ITMP2, l);
2656 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2659 /* number of targets */
2665 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2667 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2668 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2670 M_BEQZ(REG_ITMP2, 0);
2671 codegen_addreference(cd, table[0].block);
2673 /* build jump table top down and use address of lowest entry */
2678 dseg_add_target(cd, table->block);
2683 /* length of dataseg after last dseg_add_target is used by load */
2685 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2686 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2687 M_JMP(REG_ZERO, REG_ITMP2);
2692 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2695 lookup_target_t *lookup;
2697 lookup = iptr->dst.lookup;
2699 i = iptr->sx.s23.s2.lookupcount;
2701 MCODECHECK((i<<2)+8);
2702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2705 val = lookup->value;
2706 if ((val >= 0) && (val <= 255)) {
2707 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2709 if ((val >= -32768) && (val <= 32767)) {
2710 M_LDA(REG_ITMP2, REG_ZERO, val);
2712 disp = dseg_add_s4(cd, val);
2713 M_ILD(REG_ITMP2, REG_PV, disp);
2715 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2717 M_BNEZ(REG_ITMP2, 0);
2718 codegen_addreference(cd, lookup->target.block);
2724 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2731 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2733 bte = iptr->sx.s23.s3.bte;
2737 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2739 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2740 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2741 case ICMD_INVOKEINTERFACE:
2743 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2745 um = iptr->sx.s23.s3.um;
2746 md = um->methodref->parseddesc.md;
2749 lm = iptr->sx.s23.s3.fmiref->p.method;
2751 md = lm->parseddesc;
2755 s3 = md->paramcount;
2757 MCODECHECK((s3 << 1) + 64);
2759 /* copy arguments to registers or stack location */
2761 for (s3 = s3 - 1; s3 >= 0; s3--) {
2762 var = VAR(iptr->sx.s23.s2.args[s3]);
2764 /* Already Preallocated (ARGVAR) ? */
2765 if (var->flags & PREALLOC)
2768 if (IS_INT_LNG_TYPE(var->type)) {
2769 if (!md->params[s3].inmemory) {
2770 s1 = rd->argintregs[md->params[s3].regoff];
2771 d = emit_load(jd, iptr, var, s1);
2775 d = emit_load(jd, iptr, var, REG_ITMP1);
2776 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2780 if (!md->params[s3].inmemory) {
2781 s1 = rd->argfltregs[md->params[s3].regoff];
2782 d = emit_load(jd, iptr, var, s1);
2786 d = emit_load(jd, iptr, var, REG_FTMP1);
2787 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2792 switch (iptr->opc) {
2794 disp = dseg_add_functionptr(cd, bte->fp);
2796 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2799 case ICMD_INVOKESPECIAL:
2801 codegen_add_nullpointerexception_ref(cd);
2804 case ICMD_INVOKESTATIC:
2806 disp = dseg_add_unique_address(cd, um);
2808 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2811 if (opt_showdisassemble)
2815 disp = dseg_add_address(cd, lm->stubroutine);
2817 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2820 case ICMD_INVOKEVIRTUAL:
2821 gen_nullptr_check(REG_A0);
2824 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2826 if (opt_showdisassemble)
2832 s1 = OFFSET(vftbl_t, table[0]) +
2833 sizeof(methodptr) * lm->vftblindex;
2835 M_ALD(REG_METHODPTR, REG_A0,
2836 OFFSET(java_objectheader, vftbl));
2837 M_ALD(REG_PV, REG_METHODPTR, s1);
2840 case ICMD_INVOKEINTERFACE:
2841 gen_nullptr_check(REG_A0);
2844 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2846 if (opt_showdisassemble)
2853 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2854 sizeof(methodptr*) * lm->class->index;
2856 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2859 M_ALD(REG_METHODPTR, REG_A0,
2860 OFFSET(java_objectheader, vftbl));
2861 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2862 M_ALD(REG_PV, REG_METHODPTR, s2);
2866 /* generate the actual call */
2868 M_JSR(REG_RA, REG_PV);
2869 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2870 M_LDA(REG_PV, REG_RA, -disp);
2872 /* actually only used for ICMD_BUILTIN */
2874 if (INSTRUCTION_MUST_CHECK(iptr)) {
2875 M_BEQZ(REG_RESULT, 0);
2876 codegen_add_fillinstacktrace_ref(cd);
2879 /* store the return value */
2881 d = md->returntype.type;
2883 if (d != TYPE_VOID) {
2884 if (IS_INT_LNG_TYPE(d)) {
2885 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2886 M_INTMOVE(REG_RESULT, s1);
2889 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2890 M_FLTMOVE(REG_FRESULT, s1);
2892 emit_store_dst(jd, iptr, s1);
2897 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2899 /* val.a: (classinfo*) superclass */
2901 /* superclass is an interface:
2903 * OK if ((sub == NULL) ||
2904 * (sub->vftbl->interfacetablelength > super->index) &&
2905 * (sub->vftbl->interfacetable[-super->index] != NULL));
2907 * superclass is a class:
2909 * OK if ((sub == NULL) || (0
2910 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2911 * super->vftbl->diffval));
2914 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2915 /* object type cast-check */
2918 vftbl_t *supervftbl;
2921 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2927 super = iptr->sx.s23.s3.c.cls;
2928 superindex = super->index;
2929 supervftbl = super->vftbl;
2932 #if defined(ENABLE_THREADS)
2933 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2937 /* calculate interface checkcast code size */
2941 s2 += opt_showdisassemble ? 1 : 0;
2943 /* calculate class checkcast code size */
2945 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
2947 s3 += opt_showdisassemble ? 1 : 0;
2949 /* if class is not resolved, check which code to call */
2951 if (super == NULL) {
2952 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
2954 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2956 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
2957 iptr->sx.s23.s3.c.ref,
2960 if (opt_showdisassemble)
2963 M_ILD(REG_ITMP2, REG_PV, disp);
2964 disp = dseg_add_s4(cd, ACC_INTERFACE);
2965 M_ILD(REG_ITMP3, REG_PV, disp);
2966 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2967 M_BEQZ(REG_ITMP2, s2 + 1);
2970 /* interface checkcast code */
2972 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2973 if (super == NULL) {
2974 codegen_addpatchref(cd,
2975 PATCHER_checkcast_instanceof_interface,
2976 iptr->sx.s23.s3.c.ref,
2979 if (opt_showdisassemble)
2985 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2986 M_ILD(REG_ITMP3, REG_ITMP2,
2987 OFFSET(vftbl_t, interfacetablelength));
2988 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2989 M_BLEZ(REG_ITMP3, 0);
2990 codegen_add_classcastexception_ref(cd, s1);
2991 M_ALD(REG_ITMP3, REG_ITMP2,
2992 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2993 superindex * sizeof(methodptr*)));
2994 M_BEQZ(REG_ITMP3, 0);
2995 codegen_add_classcastexception_ref(cd, s1);
3001 /* class checkcast code */
3003 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3004 if (super == NULL) {
3005 disp = dseg_add_unique_address(cd, NULL);
3007 codegen_addpatchref(cd,
3008 PATCHER_resolve_classref_to_vftbl,
3009 iptr->sx.s23.s3.c.ref,
3012 if (opt_showdisassemble)
3016 disp = dseg_add_address(cd, supervftbl);
3021 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3022 M_ALD(REG_ITMP3, REG_PV, disp);
3023 #if defined(ENABLE_THREADS)
3024 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3026 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3027 /* if (s1 != REG_ITMP1) { */
3028 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3029 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3030 /* #if defined(ENABLE_THREADS) */
3031 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3033 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3036 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3037 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3038 M_ALD(REG_ITMP3, REG_PV, disp);
3039 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3040 #if defined(ENABLE_THREADS)
3041 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3044 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3045 M_BEQZ(REG_ITMP3, 0);
3046 codegen_add_classcastexception_ref(cd, s1);
3049 d = codegen_reg_of_dst(jd, iptr, s1);
3052 /* array type cast-check */
3054 s1 = emit_load_s1(jd, iptr, REG_A0);
3055 M_INTMOVE(s1, REG_A0);
3057 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3059 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3060 codegen_addpatchref(cd,
3061 PATCHER_resolve_classref_to_classinfo,
3062 iptr->sx.s23.s3.c.ref,
3065 if (opt_showdisassemble)
3069 M_ALD(REG_A1, REG_PV, disp);
3070 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3071 M_ALD(REG_PV, REG_PV, disp);
3072 M_JSR(REG_RA, REG_PV);
3073 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3074 M_LDA(REG_PV, REG_RA, -disp);
3076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3077 M_BEQZ(REG_RESULT, 0);
3078 codegen_add_classcastexception_ref(cd, s1);
3080 d = codegen_reg_of_dst(jd, iptr, s1);
3084 emit_store_dst(jd, iptr, d);
3087 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3089 /* val.a: (classinfo*) superclass */
3091 /* superclass is an interface:
3093 * return (sub != NULL) &&
3094 * (sub->vftbl->interfacetablelength > super->index) &&
3095 * (sub->vftbl->interfacetable[-super->index] != NULL);
3097 * superclass is a class:
3099 * return ((sub != NULL) && (0
3100 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3101 * super->vftbl->diffvall));
3106 vftbl_t *supervftbl;
3109 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3115 super = iptr->sx.s23.s3.c.cls;
3116 superindex = super->index;
3117 supervftbl = super->vftbl;
3120 #if defined(ENABLE_THREADS)
3121 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3126 M_MOV(s1, REG_ITMP1);
3130 /* calculate interface instanceof code size */
3134 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3136 /* calculate class instanceof code size */
3140 s3 += (opt_showdisassemble ? 1 : 0);
3142 /* if class is not resolved, check which code to call */
3144 if (super == NULL) {
3146 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3148 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3150 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
3151 iptr->sx.s23.s3.c.ref, disp);
3153 if (opt_showdisassemble)
3156 M_ILD(REG_ITMP3, REG_PV, disp);
3158 disp = dseg_add_s4(cd, ACC_INTERFACE);
3159 M_ILD(REG_ITMP2, REG_PV, disp);
3160 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3161 M_BEQZ(REG_ITMP3, s2 + 1);
3164 /* interface instanceof code */
3166 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3167 if (super == NULL) {
3168 /* If d == REG_ITMP2, then it's destroyed in check
3173 codegen_addpatchref(cd,
3174 PATCHER_checkcast_instanceof_interface,
3175 iptr->sx.s23.s3.c.ref, 0);
3177 if (opt_showdisassemble)
3185 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3186 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3187 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3188 M_BLEZ(REG_ITMP3, 2);
3189 M_ALD(REG_ITMP1, REG_ITMP1,
3190 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3191 superindex * sizeof(methodptr*)));
3192 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3198 /* class instanceof code */
3200 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3201 if (super == NULL) {
3202 disp = dseg_add_unique_address(cd, NULL);
3204 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3205 iptr->sx.s23.s3.c.ref,
3208 if (opt_showdisassemble)
3212 disp = dseg_add_address(cd, supervftbl);
3218 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3219 M_ALD(REG_ITMP2, REG_PV, disp);
3220 #if defined(ENABLE_THREADS)
3221 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3223 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3224 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3225 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3226 #if defined(ENABLE_THREADS)
3227 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3229 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3230 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3232 emit_store_dst(jd, iptr, d);
3236 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3238 /* check for negative sizes and copy sizes to stack if necessary */
3240 MCODECHECK((iptr->s1.argcount << 1) + 64);
3242 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3244 var = VAR(iptr->sx.s23.s2.args[s1]);
3246 /* copy SAVEDVAR sizes to stack */
3248 /* Already Preallocated? */
3250 if (!(var->flags & PREALLOC)) {
3251 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3252 M_LST(s2, REG_SP, s1 * 8);
3256 /* a0 = dimension count */
3258 ICONST(REG_A0, iptr->s1.argcount);
3260 /* is patcher function set? */
3262 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3263 disp = dseg_add_unique_address(cd, 0);
3265 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3266 iptr->sx.s23.s3.c.ref,
3269 if (opt_showdisassemble)
3273 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3275 /* a1 = arraydescriptor */
3277 M_ALD(REG_A1, REG_PV, disp);
3279 /* a2 = pointer to dimensions = stack pointer */
3281 M_INTMOVE(REG_SP, REG_A2);
3283 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3284 M_ALD(REG_PV, REG_PV, disp);
3285 M_JSR(REG_RA, REG_PV);
3286 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3287 M_LDA(REG_PV, REG_RA, -disp);
3289 /* check for exception before result assignment */
3291 M_BEQZ(REG_RESULT, 0);
3292 codegen_add_fillinstacktrace_ref(cd);
3294 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3295 M_INTMOVE(REG_RESULT, d);
3296 emit_store_dst(jd, iptr, d);
3301 new_internalerror("Unknown ICMD %d", iptr->opc);
3305 } /* for instruction */
3307 } /* if (bptr -> flags >= BBREACHED) */
3308 } /* for basic block */
3310 dseg_createlinenumbertable(cd);
3312 /* generate stubs */
3314 emit_exception_stubs(jd);
3315 emit_patcher_stubs(jd);
3317 emit_replacement_stubs(jd);
3322 /* everything's ok */
3328 /* createcompilerstub **********************************************************
3330 Creates a stub routine which calls the compiler.
3332 *******************************************************************************/
3334 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3335 #define COMPILERSTUB_CODESIZE 3 * 4
3337 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3340 u1 *createcompilerstub(methodinfo *m)
3342 u1 *s; /* memory to hold the stub */
3346 s4 dumpsize; /* code generation pointer */
3348 s = CNEW(u1, COMPILERSTUB_SIZE);
3350 /* set data pointer and code pointer */
3353 s = s + COMPILERSTUB_DATASIZE;
3355 /* mark start of dump memory area */
3357 dumpsize = dump_size();
3359 cd = DNEW(codegendata);
3362 /* Store the codeinfo pointer in the same place as in the
3363 methodheader for compiled methods. */
3365 code = code_codeinfo_new(m);
3367 d[0] = (ptrint) asm_call_jit_compiler;
3369 d[2] = (ptrint) code;
3371 /* code for the stub */
3373 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3374 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3375 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3377 #if defined(ENABLE_STATISTICS)
3379 count_cstub_len += COMPILERSTUB_SIZE;
3382 /* release dump area */
3384 dump_release(dumpsize);
3390 /* createnativestub ************************************************************
3392 Creates a stub routine which calls a native method.
3394 *******************************************************************************/
3396 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3404 s4 i, j; /* count variables */
3407 s4 funcdisp; /* displacement of the function */
3409 /* get required compiler data */
3416 /* initialize variables */
3419 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3421 /* calculate stack frame size */
3423 cd->stackframesize =
3424 1 + /* return address */
3425 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3426 sizeof(localref_table) / SIZEOF_VOID_P +
3427 1 + /* methodinfo for call trace */
3428 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3431 /* create method header */
3433 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3434 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3435 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3436 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3437 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3438 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3439 (void) dseg_addlinenumbertablesize(cd);
3440 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3442 /* generate stub code */
3444 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3445 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3447 /* call trace function */
3449 #if !defined(NDEBUG)
3450 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3451 emit_verbosecall_enter(jd);
3454 /* get function address (this must happen before the stackframeinfo) */
3456 funcdisp = dseg_add_functionptr(cd, f);
3458 #if !defined(WITH_STATIC_CLASSPATH)
3460 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3462 if (opt_showdisassemble)
3467 /* save integer and float argument registers */
3469 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3470 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3471 M_LST(rd->argintregs[i], REG_SP, j * 8);
3476 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3477 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3478 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3483 /* prepare data structures for native function call */
3485 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3486 M_MOV(REG_PV, REG_A1);
3487 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3488 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3489 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3490 M_ALD(REG_PV, REG_PV, disp);
3491 M_JSR(REG_RA, REG_PV);
3492 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3493 M_LDA(REG_PV, REG_RA, -disp);
3495 /* restore integer and float argument registers */
3497 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3498 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3499 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3504 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3505 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3506 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3511 /* copy or spill arguments to new locations */
3513 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3514 t = md->paramtypes[i].type;
3516 if (IS_INT_LNG_TYPE(t)) {
3517 if (!md->params[i].inmemory) {
3518 s1 = rd->argintregs[md->params[i].regoff];
3520 if (!nmd->params[j].inmemory) {
3521 s2 = rd->argintregs[nmd->params[j].regoff];
3525 s2 = nmd->params[j].regoff;
3526 M_LST(s1, REG_SP, s2 * 8);
3530 s1 = md->params[i].regoff + cd->stackframesize;
3531 s2 = nmd->params[j].regoff;
3532 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3533 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3537 if (!md->params[i].inmemory) {
3538 s1 = rd->argfltregs[md->params[i].regoff];
3540 if (!nmd->params[j].inmemory) {
3541 s2 = rd->argfltregs[nmd->params[j].regoff];
3545 s2 = nmd->params[j].regoff;
3546 if (IS_2_WORD_TYPE(t))
3547 M_DST(s1, REG_SP, s2 * 8);
3549 M_FST(s1, REG_SP, s2 * 8);
3553 s1 = md->params[i].regoff + cd->stackframesize;
3554 s2 = nmd->params[j].regoff;
3555 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3556 if (IS_2_WORD_TYPE(t))
3557 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3559 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3564 /* put class into second argument register */
3566 if (m->flags & ACC_STATIC) {
3567 disp = dseg_add_address(cd, m->class);
3568 M_ALD(REG_A1, REG_PV, disp);
3571 /* put env into first argument register */
3573 disp = dseg_add_address(cd, _Jv_env);
3574 M_ALD(REG_A0, REG_PV, disp);
3576 /* do the native function call */
3578 M_ALD(REG_PV, REG_PV, funcdisp);
3579 M_JSR(REG_RA, REG_PV); /* call native method */
3580 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3581 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3583 /* save return value */
3585 if (md->returntype.type != TYPE_VOID) {
3586 if (IS_INT_LNG_TYPE(md->returntype.type))
3587 M_LST(REG_RESULT, REG_SP, 0 * 8);
3589 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3592 /* call finished trace */
3594 #if !defined(NDEBUG)
3595 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3596 emit_verbosecall_exit(jd);
3599 /* remove native stackframe info */
3601 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3602 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3603 M_ALD(REG_PV, REG_PV, disp);
3604 M_JSR(REG_RA, REG_PV);
3605 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3606 M_LDA(REG_PV, REG_RA, -disp);
3607 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3609 /* restore return value */
3611 if (md->returntype.type != TYPE_VOID) {
3612 if (IS_INT_LNG_TYPE(md->returntype.type))
3613 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3615 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3618 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3619 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3621 /* check for exception */
3623 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3624 M_RET(REG_ZERO, REG_RA); /* return to caller */
3626 /* handle exception */
3628 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3630 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3631 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3632 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3635 /* generate patcher stubs */
3637 emit_patcher_stubs(jd);
3641 return code->entrypoint;
3646 * These are local overrides for various environment variables in Emacs.
3647 * Please do not remove this and leave it at the end of the file, where
3648 * Emacs will automagically detect them.
3649 * ---------------------------------------------------------------------
3652 * indent-tabs-mode: t
3656 * vim:noexpandtab:sw=4:ts=4: