1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
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: Christian Thalinger
34 Contains the codegenerator for an MIPS (R4000 or higher) processor.
35 This module generates MIPS machine code for a sequence of
36 intermediate code commands (ICMDs).
38 $Id: codegen.c 4905 2006-05-11 13:43:55Z twisti $
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
56 #include "native/native.h"
57 #include "vm/builtin.h"
59 #include "vm/exceptions.h"
60 #include "vm/options.h"
61 #include "vm/stringlocal.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/dseg.h"
66 #include "vm/jit/emit.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/replace.h"
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
77 /* codegen *********************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
97 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
98 builtintable_entry *bte;
100 rplpoint *replacementpoint;
102 /* get required compiler data */
112 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
114 /* space to save used callee saved registers */
116 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
117 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
119 parentargs_base = rd->memuse + savedregs_num;
121 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
122 if (checksync && (m->flags & ACC_SYNCHRONIZED))
126 /* adjust frame size for 16 byte alignment */
128 if (parentargs_base & 1)
131 /* create method header */
133 #if SIZEOF_VOID_P == 4
134 (void) dseg_addaddress(cd, m); /* Filler */
136 (void) dseg_addaddress(cd, m); /* MethodPointer */
137 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
139 #if defined(USE_THREADS)
140 /* IsSync contains the offset relative to the stack pointer for the
141 argument of monitor_exit used in the exception handler. Since the
142 offset could be zero and give a wrong meaning of the flag it is
146 if (checksync && (m->flags & ACC_SYNCHRONIZED))
147 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
150 (void) dseg_adds4(cd, 0); /* IsSync */
152 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
153 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
154 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
155 dseg_addlinenumbertablesize(cd);
156 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
158 /* create exception table */
160 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
161 dseg_addtarget(cd, ex->start);
162 dseg_addtarget(cd, ex->end);
163 dseg_addtarget(cd, ex->handler);
164 (void) dseg_addaddress(cd, ex->catchtype.cls);
167 /* create stack frame (if necessary) */
170 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
172 /* save return address and used callee saved registers */
175 if (!m->isleafmethod) {
176 p--; M_AST(REG_RA, REG_SP, p * 8);
178 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
179 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
181 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
182 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
185 /* take arguments out of register or stack frame */
189 for (p = 0, l = 0; p < md->paramcount; p++) {
190 t = md->paramtypes[p].type;
191 var = &(rd->locals[l][t]);
193 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
197 s1 = md->params[p].regoff;
198 if (IS_INT_LNG_TYPE(t)) { /* integer args */
199 if (!md->params[p].inmemory) { /* register arguments */
200 s2 = rd->argintregs[s1];
201 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
202 M_INTMOVE(s2, var->regoff);
203 } else { /* reg arg -> spilled */
204 M_LST(s2, REG_SP, var->regoff * 8);
207 } else { /* stack arguments */
208 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
209 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
210 } else { /* stack arg -> spilled */
211 var->regoff = parentargs_base + s1;
215 } else { /* floating args */
216 if (!md->params[p].inmemory) { /* register arguments */
217 s2 = rd->argfltregs[s1];
218 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
219 if (IS_2_WORD_TYPE(t))
220 M_DMOV(s2, var->regoff);
222 M_FMOV(s2, var->regoff);
223 } else { /* reg arg -> spilled */
224 if (IS_2_WORD_TYPE(t))
225 M_DST(s2, REG_SP, var->regoff * 8);
227 M_FST(s2, REG_SP, var->regoff * 8);
230 } else { /* stack arguments */
231 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
232 if (IS_2_WORD_TYPE(t))
233 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
235 M_FLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
236 } else /* stack-arg -> spilled */
237 var->regoff = parentargs_base + s1;
242 /* call monitorenter function */
244 #if defined(USE_THREADS)
245 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
246 /* stack offset for monitor argument */
250 if (opt_verbosecall) {
251 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
253 for (p = 0; p < INT_ARG_CNT; p++)
254 M_LST(rd->argintregs[p], REG_SP, p * 8);
256 for (p = 0; p < FLT_ARG_CNT; p++)
257 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
259 s1 += INT_ARG_CNT + FLT_ARG_CNT;
262 /* decide which monitor enter function to call */
264 if (m->flags & ACC_STATIC) {
265 p = dseg_addaddress(cd, m->class);
266 M_ALD(rd->argintregs[0], REG_PV, p);
267 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
268 M_ALD(REG_ITMP3, REG_PV, p);
269 M_JSR(REG_RA, REG_ITMP3);
270 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
273 M_BEQZ(rd->argintregs[0], 0);
274 codegen_add_nullpointerexception_ref(cd);
275 p = dseg_addaddress(cd, BUILTIN_monitorenter);
276 M_ALD(REG_ITMP3, REG_PV, p);
277 M_JSR(REG_RA, REG_ITMP3);
278 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
281 if (opt_verbosecall) {
282 for (p = 0; p < INT_ARG_CNT; p++)
283 M_LLD(rd->argintregs[p], REG_SP, p * 8);
285 for (p = 0; p < FLT_ARG_CNT; p++)
286 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
289 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
294 /* copy argument registers to stack and call trace function */
296 if (opt_verbosecall) {
297 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
298 M_AST(REG_RA, REG_SP, 1 * 8);
300 /* save integer argument registers */
302 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
303 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
305 /* save and copy float arguments into integer registers */
307 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
308 t = md->paramtypes[p].type;
310 if (IS_FLT_DBL_TYPE(t)) {
311 if (IS_2_WORD_TYPE(t)) {
312 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
313 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
316 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
317 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
321 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
325 /* save temporary registers for leaf methods */
327 if (m->isleafmethod) {
328 for (p = 0; p < INT_TMP_CNT; p++)
329 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
331 for (p = 0; p < FLT_TMP_CNT; p++)
332 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
335 p = dseg_addaddress(cd, m);
336 M_ALD(REG_ITMP1, REG_PV, p);
337 M_AST(REG_ITMP1, REG_SP, 0 * 8);
338 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
339 M_ALD(REG_ITMP3, REG_PV, disp);
340 M_JSR(REG_RA, REG_ITMP3);
343 M_ALD(REG_RA, REG_SP, 1 * 8);
345 /* restore integer argument registers */
347 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
348 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
350 /* restore float argument registers */
352 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
353 t = md->paramtypes[p].type;
355 if (IS_FLT_DBL_TYPE(t)) {
356 if (IS_2_WORD_TYPE(t)) {
357 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
360 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
364 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
368 /* restore temporary registers for leaf methods */
370 if (m->isleafmethod) {
371 for (p = 0; p < INT_TMP_CNT; p++)
372 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
374 for (p = 0; p < FLT_TMP_CNT; p++)
375 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
378 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
383 /* end of header generation */
385 replacementpoint = jd->code->rplpoints;
387 /* walk through all basic blocks */
389 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
391 /* handle replacement points */
393 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
395 /* 8-byte align pc */
396 if ((ptrint) cd->mcodeptr & 4) {
400 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
403 assert(cd->lastmcodeptr <= cd->mcodeptr);
404 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
407 /* store relative start of block */
409 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
411 if (bptr->flags >= BBREACHED) {
413 /* branch resolving */
416 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
417 gen_resolvebranch(cd->mcodebase + bref->branchpos,
423 /* copy interface registers to their destination */
428 #if defined(ENABLE_LSRA)
430 while (src != NULL) {
432 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
433 /* d = reg_of_var(m, src, REG_ITMP1); */
434 if (!(src->flags & INMEMORY))
438 M_INTMOVE(REG_ITMP1, d);
439 emit_store(jd, NULL, src, d);
445 while (src != NULL) {
447 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
448 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
449 M_INTMOVE(REG_ITMP1, d);
450 emit_store(jd, NULL, src, d);
453 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
454 if ((src->varkind != STACKVAR)) {
456 s1 = rd->interfaces[len][s2].regoff;
457 if (IS_FLT_DBL_TYPE(s2)) {
458 if (rd->interfaces[len][s2].flags & INMEMORY) {
459 if (IS_2_WORD_TYPE(s2))
460 M_DLD(d, REG_SP, s1 * 8);
462 M_FLD(d, REG_SP, s1 * 8);
465 if (IS_2_WORD_TYPE(s2))
472 if (rd->interfaces[len][s2].flags & INMEMORY)
473 M_LLD(d, REG_SP, s1 * 8);
478 emit_store(jd, NULL, src, d);
483 #if defined(ENABLE_LSRA)
486 /* walk through all instructions */
492 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
493 if (iptr->line != currentline) {
494 dseg_addlinenumber(cd, iptr->line);
495 currentline = iptr->line;
498 MCODECHECK(64); /* an instruction usually needs < 64 words */
502 case ICMD_NOP: /* ... ==> ... */
505 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
507 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
509 codegen_add_nullpointerexception_ref(cd);
513 /* constant operations ************************************************/
515 case ICMD_ICONST: /* ... ==> ..., constant */
516 /* op1 = 0, val.i = constant */
518 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
519 ICONST(d, iptr->val.i);
520 emit_store(jd, iptr, iptr->dst, d);
523 case ICMD_LCONST: /* ... ==> ..., constant */
524 /* op1 = 0, val.l = constant */
526 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
527 LCONST(d, iptr->val.l);
528 emit_store(jd, iptr, iptr->dst, d);
531 case ICMD_FCONST: /* ... ==> ..., constant */
532 /* op1 = 0, val.f = constant */
534 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
535 disp = dseg_addfloat(cd, iptr->val.f);
536 M_FLD(d, REG_PV, disp);
537 emit_store(jd, iptr, iptr->dst, d);
540 case ICMD_DCONST: /* ... ==> ..., constant */
541 /* op1 = 0, val.d = constant */
543 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
544 disp = dseg_adddouble(cd, iptr->val.d);
545 M_DLD(d, REG_PV, disp);
546 emit_store(jd, iptr, iptr->dst, d);
549 case ICMD_ACONST: /* ... ==> ..., constant */
550 /* op1 = 0, val.a = constant */
552 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
554 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
555 disp = dseg_addaddress(cd, NULL);
557 codegen_addpatchref(cd, PATCHER_aconst,
558 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
561 if (opt_showdisassemble) {
565 M_ALD(d, REG_PV, disp);
568 if (iptr->val.a == NULL) {
569 M_INTMOVE(REG_ZERO, d);
571 disp = dseg_addaddress(cd, iptr->val.a);
572 M_ALD(d, REG_PV, disp);
575 emit_store(jd, iptr, iptr->dst, d);
579 /* load/store operations **********************************************/
581 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
582 /* op1 = local variable */
584 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
585 if ((iptr->dst->varkind == LOCALVAR) &&
586 (iptr->dst->varnum == iptr->op1))
588 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
589 if (var->flags & INMEMORY)
590 #if SIZEOF_VOID_P == 8
591 M_LLD(d, REG_SP, var->regoff * 8);
593 M_ILD(d, REG_SP, var->regoff * 8);
596 M_INTMOVE(var->regoff,d);
597 emit_store(jd, iptr, iptr->dst, d);
600 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
601 /* op1 = local variable */
603 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
604 if ((iptr->dst->varkind == LOCALVAR) &&
605 (iptr->dst->varnum == iptr->op1))
607 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
608 if (var->flags & INMEMORY)
609 M_LLD(d, REG_SP, var->regoff * 8);
611 M_INTMOVE(var->regoff,d);
612 emit_store(jd, iptr, iptr->dst, d);
615 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
616 /* op1 = local variable */
618 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
619 if ((iptr->dst->varkind == LOCALVAR) &&
620 (iptr->dst->varnum == iptr->op1))
622 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
623 if (var->flags & INMEMORY)
624 M_ALD(d, REG_SP, var->regoff * 8);
626 M_INTMOVE(var->regoff,d);
627 emit_store(jd, iptr, iptr->dst, d);
630 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
631 /* op1 = local variable */
633 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
634 if ((iptr->dst->varkind == LOCALVAR) &&
635 (iptr->dst->varnum == iptr->op1))
637 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
638 if (var->flags & INMEMORY)
639 M_FLD(d, REG_SP, var->regoff * 8);
641 M_FMOV(var->regoff, d);
642 emit_store(jd, iptr, iptr->dst, d);
645 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
646 /* op1 = local variable */
648 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
649 if ((iptr->dst->varkind == LOCALVAR) &&
650 (iptr->dst->varnum == iptr->op1))
652 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
653 if (var->flags & INMEMORY)
654 M_DLD(d, REG_SP, var->regoff * 8);
656 M_DMOV(var->regoff, d);
657 emit_store(jd, iptr, iptr->dst, d);
661 case ICMD_ISTORE: /* ..., value ==> ... */
662 /* op1 = local variable */
664 if ((src->varkind == LOCALVAR) &&
665 (src->varnum == iptr->op1))
667 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
668 if (var->flags & INMEMORY) {
669 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
670 #if SIZEOF_VOID_P == 8
671 M_LST(s1, REG_SP, var->regoff * 8);
673 M_IST(s1, REG_SP, var->regoff * 8);
676 s1 = emit_load_s1(jd, iptr, src, var->regoff);
677 M_INTMOVE(s1, var->regoff);
681 case ICMD_LSTORE: /* ..., value ==> ... */
682 /* op1 = local variable */
684 if ((src->varkind == LOCALVAR) &&
685 (src->varnum == iptr->op1))
687 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
688 if (var->flags & INMEMORY) {
689 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
690 M_LST(s1, REG_SP, var->regoff * 8);
692 s1 = emit_load_s1(jd, iptr, src, var->regoff);
693 M_INTMOVE(s1, var->regoff);
697 case ICMD_ASTORE: /* ..., value ==> ... */
698 /* op1 = local variable */
700 if ((src->varkind == LOCALVAR) &&
701 (src->varnum == iptr->op1))
703 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
704 if (var->flags & INMEMORY) {
705 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
706 M_AST(s1, REG_SP, var->regoff * 8);
708 s1 = emit_load_s1(jd, iptr, src, var->regoff);
709 M_INTMOVE(s1, var->regoff);
713 case ICMD_FSTORE: /* ..., value ==> ... */
714 /* op1 = local variable */
716 if ((src->varkind == LOCALVAR) &&
717 (src->varnum == iptr->op1))
719 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
720 if (var->flags & INMEMORY) {
721 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
722 M_FST(s1, REG_SP, var->regoff * 8);
724 s1 = emit_load_s1(jd, iptr, src, var->regoff);
725 M_FMOV(s1, var->regoff);
729 case ICMD_DSTORE: /* ..., value ==> ... */
730 /* op1 = local variable */
732 if ((src->varkind == LOCALVAR) &&
733 (src->varnum == iptr->op1))
735 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
736 if (var->flags & INMEMORY) {
737 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
738 M_DST(s1, REG_SP, var->regoff * 8);
740 s1 = emit_load_s1(jd, iptr, src, var->regoff);
741 M_DMOV(s1, var->regoff);
746 /* pop/dup/swap operations ********************************************/
748 /* attention: double and longs are only one entry in CACAO ICMDs */
750 case ICMD_POP: /* ..., value ==> ... */
751 case ICMD_POP2: /* ..., value, value ==> ... */
754 case ICMD_DUP: /* ..., a ==> ..., a, a */
755 M_COPY(src, iptr->dst);
758 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
760 M_COPY(src, iptr->dst);
761 M_COPY(src->prev, iptr->dst->prev);
762 M_COPY(iptr->dst, iptr->dst->prev->prev);
765 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
767 M_COPY(src, iptr->dst);
768 M_COPY(src->prev, iptr->dst->prev);
769 M_COPY(src->prev->prev, iptr->dst->prev->prev);
770 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
773 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
775 M_COPY(src, iptr->dst);
776 M_COPY(src->prev, iptr->dst->prev);
779 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
781 M_COPY(src, iptr->dst);
782 M_COPY(src->prev, iptr->dst->prev);
783 M_COPY(src->prev->prev, iptr->dst->prev->prev);
784 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
785 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
788 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
790 M_COPY(src, iptr->dst);
791 M_COPY(src->prev, iptr->dst->prev);
792 M_COPY(src->prev->prev, iptr->dst->prev->prev);
793 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
794 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
795 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
798 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
800 M_COPY(src, iptr->dst->prev);
801 M_COPY(src->prev, iptr->dst);
805 /* integer operations *************************************************/
807 case ICMD_INEG: /* ..., value ==> ..., - value */
809 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
810 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
811 M_ISUB(REG_ZERO, s1, d);
812 emit_store(jd, iptr, iptr->dst, d);
815 case ICMD_LNEG: /* ..., value ==> ..., - value */
817 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
818 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
819 M_LSUB(REG_ZERO, s1, d);
820 emit_store(jd, iptr, iptr->dst, d);
823 case ICMD_I2L: /* ..., value ==> ..., value */
825 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
826 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
828 emit_store(jd, iptr, iptr->dst, d);
831 case ICMD_L2I: /* ..., value ==> ..., value */
833 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
834 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
835 M_ISLL_IMM(s1, 0, d );
836 emit_store(jd, iptr, iptr->dst, d);
839 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
841 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
842 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
843 M_LSLL_IMM(s1, 56, d);
844 M_LSRA_IMM( d, 56, d);
845 emit_store(jd, iptr, iptr->dst, d);
848 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
850 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
851 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
853 emit_store(jd, iptr, iptr->dst, d);
856 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
858 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
859 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
860 M_LSLL_IMM(s1, 48, d);
861 M_LSRA_IMM( d, 48, d);
862 emit_store(jd, iptr, iptr->dst, d);
866 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
868 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
869 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
870 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
872 emit_store(jd, iptr, iptr->dst, d);
875 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
876 /* val.i = constant */
878 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
879 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
880 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
881 M_IADD_IMM(s1, iptr->val.i, d);
883 ICONST(REG_ITMP2, iptr->val.i);
884 M_IADD(s1, REG_ITMP2, d);
886 emit_store(jd, iptr, iptr->dst, d);
889 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
891 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
892 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
893 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
895 emit_store(jd, iptr, iptr->dst, d);
898 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
899 /* val.l = constant */
901 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
902 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
903 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
904 M_LADD_IMM(s1, iptr->val.l, d);
906 LCONST(REG_ITMP2, iptr->val.l);
907 M_LADD(s1, REG_ITMP2, d);
909 emit_store(jd, iptr, iptr->dst, d);
912 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
914 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
915 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
916 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
918 emit_store(jd, iptr, iptr->dst, d);
921 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
922 /* val.i = constant */
924 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
925 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
926 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
927 M_IADD_IMM(s1, -iptr->val.i, d);
929 ICONST(REG_ITMP2, iptr->val.i);
930 M_ISUB(s1, REG_ITMP2, d);
932 emit_store(jd, iptr, iptr->dst, d);
935 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
937 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
938 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
939 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
941 emit_store(jd, iptr, iptr->dst, d);
944 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
945 /* val.l = constant */
947 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
948 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
949 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
950 M_LADD_IMM(s1, -iptr->val.l, d);
952 LCONST(REG_ITMP2, iptr->val.l);
953 M_LSUB(s1, REG_ITMP2, d);
955 emit_store(jd, iptr, iptr->dst, d);
958 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
960 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
961 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
962 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
967 emit_store(jd, iptr, iptr->dst, d);
970 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
971 /* val.i = constant */
973 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
974 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
975 ICONST(REG_ITMP2, iptr->val.i);
976 M_IMUL(s1, REG_ITMP2);
980 emit_store(jd, iptr, iptr->dst, d);
983 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
985 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
986 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
987 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
992 emit_store(jd, iptr, iptr->dst, d);
995 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
996 /* val.l = constant */
998 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
999 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1000 LCONST(REG_ITMP2, iptr->val.l);
1001 M_LMUL(s1, REG_ITMP2);
1005 emit_store(jd, iptr, iptr->dst, d);
1008 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1010 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1011 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1012 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1018 emit_store(jd, iptr, iptr->dst, d);
1021 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1023 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1024 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1025 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1031 emit_store(jd, iptr, iptr->dst, d);
1034 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1036 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1037 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1038 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1044 emit_store(jd, iptr, iptr->dst, d);
1047 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1049 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1050 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1051 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1057 emit_store(jd, iptr, iptr->dst, d);
1060 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1061 case ICMD_LDIVPOW2: /* val.i = constant */
1063 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1064 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1065 M_LSRA_IMM(s1, 63, REG_ITMP2);
1066 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1067 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1068 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1069 emit_store(jd, iptr, iptr->dst, d);
1072 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1074 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1075 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1076 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1078 emit_store(jd, iptr, iptr->dst, d);
1081 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1082 /* val.i = constant */
1084 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1085 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1086 M_ISLL_IMM(s1, iptr->val.i, d);
1087 emit_store(jd, iptr, iptr->dst, d);
1090 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1092 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1093 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1094 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1096 emit_store(jd, iptr, iptr->dst, d);
1099 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1100 /* val.i = constant */
1102 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1103 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1104 M_ISRA_IMM(s1, iptr->val.i, d);
1105 emit_store(jd, iptr, iptr->dst, d);
1108 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1110 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1111 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1112 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1114 emit_store(jd, iptr, iptr->dst, d);
1117 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1118 /* val.i = constant */
1120 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1121 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1122 M_ISRL_IMM(s1, iptr->val.i, d);
1123 emit_store(jd, iptr, iptr->dst, d);
1126 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1128 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1129 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1130 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1132 emit_store(jd, iptr, iptr->dst, d);
1135 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1136 /* val.i = constant */
1138 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1139 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1140 M_LSLL_IMM(s1, iptr->val.i, d);
1141 emit_store(jd, iptr, iptr->dst, d);
1144 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1146 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1147 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1148 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1150 emit_store(jd, iptr, iptr->dst, d);
1153 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1154 /* val.i = constant */
1156 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1157 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1158 M_LSRA_IMM(s1, iptr->val.i, d);
1159 emit_store(jd, iptr, iptr->dst, d);
1162 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1164 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1165 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1166 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1168 emit_store(jd, iptr, iptr->dst, d);
1171 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1172 /* val.i = constant */
1174 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1175 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1176 M_LSRL_IMM(s1, iptr->val.i, d);
1177 emit_store(jd, iptr, iptr->dst, d);
1180 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1183 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1184 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1185 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1187 emit_store(jd, iptr, iptr->dst, d);
1190 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1191 /* val.i = constant */
1193 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1194 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1195 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1196 M_AND_IMM(s1, iptr->val.i, d);
1198 ICONST(REG_ITMP2, iptr->val.i);
1199 M_AND(s1, REG_ITMP2, d);
1201 emit_store(jd, iptr, iptr->dst, d);
1204 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1205 /* val.i = constant */
1207 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1208 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1210 M_MOV(s1, REG_ITMP1);
1213 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1214 M_AND_IMM(s1, iptr->val.i, d);
1217 M_ISUB(REG_ZERO, s1, d);
1218 M_AND_IMM(d, iptr->val.i, d);
1220 ICONST(REG_ITMP2, iptr->val.i);
1221 M_AND(s1, REG_ITMP2, d);
1224 M_ISUB(REG_ZERO, s1, d);
1225 M_AND(d, REG_ITMP2, d);
1227 M_ISUB(REG_ZERO, d, d);
1228 emit_store(jd, iptr, iptr->dst, d);
1231 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1232 /* val.l = constant */
1234 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1235 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1236 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1237 M_AND_IMM(s1, iptr->val.l, d);
1239 LCONST(REG_ITMP2, iptr->val.l);
1240 M_AND(s1, REG_ITMP2, d);
1242 emit_store(jd, iptr, iptr->dst, d);
1245 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1246 /* val.l = constant */
1248 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1249 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1251 M_MOV(s1, REG_ITMP1);
1254 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1255 M_AND_IMM(s1, iptr->val.l, d);
1258 M_LSUB(REG_ZERO, s1, d);
1259 M_AND_IMM(d, iptr->val.l, d);
1261 LCONST(REG_ITMP2, iptr->val.l);
1262 M_AND(s1, REG_ITMP2, d);
1265 M_LSUB(REG_ZERO, s1, d);
1266 M_AND(d, REG_ITMP2, d);
1268 M_LSUB(REG_ZERO, d, d);
1269 emit_store(jd, iptr, iptr->dst, d);
1272 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1275 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1276 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1277 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1279 emit_store(jd, iptr, iptr->dst, d);
1282 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1283 /* val.i = constant */
1285 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1286 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1287 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1288 M_OR_IMM(s1, iptr->val.i, d);
1290 ICONST(REG_ITMP2, iptr->val.i);
1291 M_OR(s1, REG_ITMP2, d);
1293 emit_store(jd, iptr, iptr->dst, d);
1296 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1297 /* val.l = constant */
1299 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1300 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1301 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1302 M_OR_IMM(s1, iptr->val.l, d);
1304 LCONST(REG_ITMP2, iptr->val.l);
1305 M_OR(s1, REG_ITMP2, d);
1307 emit_store(jd, iptr, iptr->dst, d);
1310 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1313 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1314 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1315 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1317 emit_store(jd, iptr, iptr->dst, d);
1320 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1321 /* val.i = constant */
1323 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1324 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1325 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1326 M_XOR_IMM(s1, iptr->val.i, d);
1328 ICONST(REG_ITMP2, iptr->val.i);
1329 M_XOR(s1, REG_ITMP2, d);
1331 emit_store(jd, iptr, iptr->dst, d);
1334 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1335 /* val.l = constant */
1337 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1338 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1339 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1340 M_XOR_IMM(s1, iptr->val.l, d);
1342 LCONST(REG_ITMP2, iptr->val.l);
1343 M_XOR(s1, REG_ITMP2, d);
1345 emit_store(jd, iptr, iptr->dst, d);
1349 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1351 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1353 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1354 M_CMPLT(s1, s2, REG_ITMP3);
1355 M_CMPLT(s2, s1, REG_ITMP1);
1356 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1357 emit_store(jd, iptr, iptr->dst, d);
1361 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1362 /* op1 = variable, val.i = constant */
1364 var = &(rd->locals[iptr->op1][TYPE_INT]);
1365 if (var->flags & INMEMORY) {
1367 M_LLD(s1, REG_SP, var->regoff * 8);
1370 M_IADD_IMM(s1, iptr->val.i, s1);
1371 if (var->flags & INMEMORY)
1372 M_LST(s1, REG_SP, var->regoff * 8);
1376 /* floating operations ************************************************/
1378 case ICMD_FNEG: /* ..., value ==> ..., - value */
1380 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1381 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1383 emit_store(jd, iptr, iptr->dst, d);
1386 case ICMD_DNEG: /* ..., value ==> ..., - value */
1388 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1389 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1391 emit_store(jd, iptr, iptr->dst, d);
1394 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1396 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1397 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1398 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1400 emit_store(jd, iptr, iptr->dst, d);
1403 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1405 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1406 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1407 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1409 emit_store(jd, iptr, iptr->dst, d);
1412 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1414 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1415 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1416 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1418 emit_store(jd, iptr, iptr->dst, d);
1421 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1423 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1424 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1425 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1427 emit_store(jd, iptr, iptr->dst, d);
1430 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1432 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1433 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1434 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1436 emit_store(jd, iptr, iptr->dst, d);
1439 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1441 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1442 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1443 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1445 emit_store(jd, iptr, iptr->dst, d);
1448 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1450 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1451 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1452 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1454 emit_store(jd, iptr, iptr->dst, d);
1457 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1459 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1460 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1461 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1463 emit_store(jd, iptr, iptr->dst, d);
1467 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1469 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1470 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1471 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1472 M_FDIV(s1,s2, REG_FTMP3);
1473 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1474 M_CVTLF(REG_FTMP3, REG_FTMP3);
1475 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1476 M_FSUB(s1, REG_FTMP3, d);
1477 emit_store(jd, iptr, iptr->dst, d);
1480 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1482 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1483 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1484 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1485 M_DDIV(s1,s2, REG_FTMP3);
1486 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1487 M_CVTLD(REG_FTMP3, REG_FTMP3);
1488 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1489 M_DSUB(s1, REG_FTMP3, d);
1490 emit_store(jd, iptr, iptr->dst, d);
1494 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1496 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1497 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1500 emit_store(jd, iptr, iptr->dst, d);
1503 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1505 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1506 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1509 emit_store(jd, iptr, iptr->dst, d);
1513 /* XXX these do not work correctly */
1515 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1517 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1518 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1519 M_TRUNCFI(s1, REG_FTMP1);
1520 M_MOVDI(REG_FTMP1, d);
1522 emit_store(jd, iptr, iptr->dst, d);
1525 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1527 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1529 M_TRUNCDI(s1, REG_FTMP1);
1530 M_MOVDI(REG_FTMP1, d);
1532 emit_store(jd, iptr, iptr->dst, d);
1535 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1537 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1538 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1539 M_TRUNCFL(s1, REG_FTMP1);
1540 M_MOVDL(REG_FTMP1, d);
1542 emit_store(jd, iptr, iptr->dst, d);
1545 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1547 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1548 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1549 M_TRUNCDL(s1, REG_FTMP1);
1550 M_MOVDL(REG_FTMP1, d);
1552 emit_store(jd, iptr, iptr->dst, d);
1556 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1558 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1559 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1561 emit_store(jd, iptr, iptr->dst, d);
1564 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1566 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1567 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1569 emit_store(jd, iptr, iptr->dst, d);
1572 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1574 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1575 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1576 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1579 M_LADD_IMM(REG_ZERO, 1, d);
1583 M_LSUB_IMM(REG_ZERO, 1, d);
1584 M_CMOVT(REG_ZERO, d);
1585 emit_store(jd, iptr, iptr->dst, d);
1588 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1590 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1591 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1592 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1595 M_LADD_IMM(REG_ZERO, 1, d);
1599 M_LSUB_IMM(REG_ZERO, 1, d);
1600 M_CMOVT(REG_ZERO, d);
1601 emit_store(jd, iptr, iptr->dst, d);
1604 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1606 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1607 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1608 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1611 M_LSUB_IMM(REG_ZERO, 1, d);
1615 M_LADD_IMM(REG_ZERO, 1, d);
1616 M_CMOVT(REG_ZERO, d);
1617 emit_store(jd, iptr, iptr->dst, d);
1620 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1622 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1623 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1624 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1627 M_LSUB_IMM(REG_ZERO, 1, d);
1631 M_LADD_IMM(REG_ZERO, 1, d);
1632 M_CMOVT(REG_ZERO, d);
1633 emit_store(jd, iptr, iptr->dst, d);
1637 /* memory operations **************************************************/
1639 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1641 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1642 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1643 gen_nullptr_check(s1);
1644 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1645 emit_store(jd, iptr, iptr->dst, d);
1648 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1650 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1651 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1652 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1653 if (iptr->op1 == 0) {
1654 gen_nullptr_check(s1);
1657 M_AADD(s2, s1, REG_ITMP3);
1658 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1659 emit_store(jd, iptr, iptr->dst, d);
1662 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1664 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1665 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1666 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1667 if (iptr->op1 == 0) {
1668 gen_nullptr_check(s1);
1671 M_AADD(s2, s1, REG_ITMP3);
1672 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1673 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1674 emit_store(jd, iptr, iptr->dst, d);
1677 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1679 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1680 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1681 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1682 if (iptr->op1 == 0) {
1683 gen_nullptr_check(s1);
1686 M_AADD(s2, s1, REG_ITMP3);
1687 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1688 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1689 emit_store(jd, iptr, iptr->dst, d);
1692 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1694 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1695 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1696 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1697 if (iptr->op1 == 0) {
1698 gen_nullptr_check(s1);
1701 M_ASLL_IMM(s2, 2, REG_ITMP3);
1702 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1703 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1704 emit_store(jd, iptr, iptr->dst, d);
1707 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1709 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1711 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1712 if (iptr->op1 == 0) {
1713 gen_nullptr_check(s1);
1716 M_ASLL_IMM(s2, 3, REG_ITMP3);
1717 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1718 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1719 emit_store(jd, iptr, iptr->dst, d);
1722 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1724 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1725 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1726 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1727 if (iptr->op1 == 0) {
1728 gen_nullptr_check(s1);
1731 M_ASLL_IMM(s2, 2, REG_ITMP3);
1732 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1733 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1734 emit_store(jd, iptr, iptr->dst, d);
1737 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1739 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1740 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1741 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1742 if (iptr->op1 == 0) {
1743 gen_nullptr_check(s1);
1746 M_ASLL_IMM(s2, 3, REG_ITMP3);
1747 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1748 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1749 emit_store(jd, iptr, iptr->dst, d);
1752 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1754 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1755 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1756 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1757 if (iptr->op1 == 0) {
1758 gen_nullptr_check(s1);
1761 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1762 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1763 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1764 emit_store(jd, iptr, iptr->dst, d);
1768 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1770 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1771 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1772 if (iptr->op1 == 0) {
1773 gen_nullptr_check(s1);
1776 M_AADD(s2, s1, REG_ITMP1);
1777 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1778 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1781 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1782 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1784 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1785 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1786 if (iptr->op1 == 0) {
1787 gen_nullptr_check(s1);
1790 M_AADD(s2, s1, REG_ITMP1);
1791 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1792 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1793 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1796 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1798 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1799 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1800 if (iptr->op1 == 0) {
1801 gen_nullptr_check(s1);
1804 M_ASLL_IMM(s2, 2, REG_ITMP2);
1805 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1806 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1807 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1810 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1812 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1813 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1814 if (iptr->op1 == 0) {
1815 gen_nullptr_check(s1);
1818 M_ASLL_IMM(s2, 3, REG_ITMP2);
1819 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1820 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1821 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1824 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1826 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1827 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1828 if (iptr->op1 == 0) {
1829 gen_nullptr_check(s1);
1832 M_ASLL_IMM(s2, 2, REG_ITMP2);
1833 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1834 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1835 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1838 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1840 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1841 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1842 if (iptr->op1 == 0) {
1843 gen_nullptr_check(s1);
1846 M_ASLL_IMM(s2, 3, REG_ITMP2);
1847 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1848 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1849 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1853 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1855 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1856 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1857 if (iptr->op1 == 0) {
1858 gen_nullptr_check(s1);
1861 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1863 M_MOV(s1, rd->argintregs[0]);
1864 M_MOV(s3, rd->argintregs[1]);
1865 disp = dseg_addaddress(cd, BUILTIN_canstore);
1866 M_ALD(REG_ITMP3, REG_PV, disp);
1867 M_JSR(REG_RA, REG_ITMP3);
1870 M_BEQZ(REG_RESULT, 0);
1871 codegen_add_arraystoreexception_ref(cd);
1874 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1875 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1876 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1877 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1878 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1879 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1883 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1885 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1886 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1887 if (iptr->op1 == 0) {
1888 gen_nullptr_check(s1);
1891 M_AADD(s2, s1, REG_ITMP1);
1892 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1895 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1896 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1898 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1899 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1900 if (iptr->op1 == 0) {
1901 gen_nullptr_check(s1);
1904 M_AADD(s2, s1, REG_ITMP1);
1905 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1906 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1909 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1911 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1912 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1913 if (iptr->op1 == 0) {
1914 gen_nullptr_check(s1);
1917 M_ASLL_IMM(s2, 2, REG_ITMP2);
1918 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1919 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1922 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1924 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1925 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1926 if (iptr->op1 == 0) {
1927 gen_nullptr_check(s1);
1930 M_ASLL_IMM(s2, 3, REG_ITMP2);
1931 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1932 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1935 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1937 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1938 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1939 if (iptr->op1 == 0) {
1940 gen_nullptr_check(s1);
1943 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1944 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1945 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1949 case ICMD_GETSTATIC: /* ... ==> ..., value */
1950 /* op1 = type, val.a = field address */
1952 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1953 disp = dseg_addaddress(cd, NULL);
1955 codegen_addpatchref(cd, PATCHER_get_putstatic,
1956 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1958 if (opt_showdisassemble) {
1963 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1965 disp = dseg_addaddress(cd, &(fi->value));
1967 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1968 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1970 if (opt_showdisassemble) {
1976 M_ALD(REG_ITMP1, REG_PV, disp);
1977 switch (iptr->op1) {
1979 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1980 M_ILD_INTERN(d, REG_ITMP1, 0);
1981 emit_store(jd, iptr, iptr->dst, d);
1984 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1985 M_LLD_INTERN(d, REG_ITMP1, 0);
1986 emit_store(jd, iptr, iptr->dst, d);
1989 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1990 M_ALD_INTERN(d, REG_ITMP1, 0);
1991 emit_store(jd, iptr, iptr->dst, d);
1994 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1995 M_FLD_INTERN(d, REG_ITMP1, 0);
1996 emit_store(jd, iptr, iptr->dst, d);
1999 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2000 M_DLD_INTERN(d, REG_ITMP1, 0);
2001 emit_store(jd, iptr, iptr->dst, d);
2006 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2007 /* op1 = type, val.a = field address */
2009 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2010 disp = dseg_addaddress(cd, NULL);
2012 codegen_addpatchref(cd, PATCHER_get_putstatic,
2013 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2015 if (opt_showdisassemble) {
2020 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2022 disp = dseg_addaddress(cd, &(fi->value));
2024 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2025 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2027 if (opt_showdisassemble) {
2033 M_ALD(REG_ITMP1, REG_PV, disp);
2034 switch (iptr->op1) {
2036 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2037 M_IST_INTERN(s2, REG_ITMP1, 0);
2040 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2041 M_LST_INTERN(s2, REG_ITMP1, 0);
2044 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2045 M_AST_INTERN(s2, REG_ITMP1, 0);
2048 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2049 M_FST_INTERN(s2, REG_ITMP1, 0);
2052 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2053 M_DST_INTERN(s2, REG_ITMP1, 0);
2058 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2059 /* val = value (in current instruction) */
2060 /* op1 = type, val.a = field address (in */
2061 /* following NOP) */
2063 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2064 disp = dseg_addaddress(cd, NULL);
2066 codegen_addpatchref(cd, PATCHER_get_putstatic,
2067 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2069 if (opt_showdisassemble) {
2074 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2076 disp = dseg_addaddress(cd, &(fi->value));
2078 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2079 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2081 if (opt_showdisassemble) {
2087 M_ALD(REG_ITMP1, REG_PV, disp);
2088 switch (iptr->op1) {
2090 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2093 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2096 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2099 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2102 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2108 case ICMD_GETFIELD: /* ... ==> ..., value */
2109 /* op1 = type, val.i = field offset */
2111 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2112 gen_nullptr_check(s1);
2114 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2115 codegen_addpatchref(cd, PATCHER_get_putfield,
2116 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2118 if (opt_showdisassemble) {
2125 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2128 switch (iptr->op1) {
2130 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2132 emit_store(jd, iptr, iptr->dst, d);
2135 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2137 emit_store(jd, iptr, iptr->dst, d);
2140 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2142 emit_store(jd, iptr, iptr->dst, d);
2145 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2147 emit_store(jd, iptr, iptr->dst, d);
2150 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2152 emit_store(jd, iptr, iptr->dst, d);
2157 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2158 /* op1 = type, val.a = field address */
2160 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2161 gen_nullptr_check(s1);
2163 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2164 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2166 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2169 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2170 codegen_addpatchref(cd, PATCHER_get_putfield,
2171 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2173 if (opt_showdisassemble) {
2180 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2183 switch (iptr->op1) {
2202 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2203 /* val = value (in current instruction) */
2204 /* op1 = type, val.a = field address (in */
2205 /* following NOP) */
2207 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2208 gen_nullptr_check(s1);
2210 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2211 codegen_addpatchref(cd, PATCHER_get_putfield,
2212 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2214 if (opt_showdisassemble) {
2221 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2224 switch (iptr[1].op1) {
2226 M_IST(REG_ZERO, s1, a);
2229 M_LST(REG_ZERO, s1, a);
2232 M_AST(REG_ZERO, s1, a);
2235 M_FST(REG_ZERO, s1, a);
2238 M_DST(REG_ZERO, s1, a);
2244 /* branch operations **************************************************/
2246 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2248 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2249 M_INTMOVE(s1, REG_ITMP1_XPTR);
2251 #ifdef ENABLE_VERIFIER
2253 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2254 (unresolved_class *) iptr->val.a, 0);
2256 if (opt_showdisassemble) {
2260 #endif /* ENABLE_VERIFIER */
2262 disp = dseg_addaddress(cd, asm_handle_exception);
2263 M_ALD(REG_ITMP2, REG_PV, disp);
2264 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2266 M_NOP; /* nop ensures that XPC is less than the end */
2267 /* of basic block */
2271 case ICMD_GOTO: /* ... ==> ... */
2272 /* op1 = target JavaVM pc */
2274 codegen_addreference(cd, (basicblock *) iptr->target);
2279 case ICMD_JSR: /* ... ==> ... */
2280 /* op1 = target JavaVM pc */
2282 dseg_addtarget(cd, (basicblock *) iptr->target);
2283 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2284 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2288 case ICMD_RET: /* ... ==> ... */
2289 /* op1 = local variable */
2290 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2291 if (var->flags & INMEMORY) {
2292 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2300 case ICMD_IFNULL: /* ..., value ==> ... */
2301 /* op1 = target JavaVM pc */
2303 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2305 codegen_addreference(cd, (basicblock *) iptr->target);
2309 case ICMD_IFNONNULL: /* ..., value ==> ... */
2310 /* op1 = target JavaVM pc */
2312 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2314 codegen_addreference(cd, (basicblock *) iptr->target);
2318 case ICMD_IFEQ: /* ..., value ==> ... */
2319 /* op1 = target JavaVM pc, val.i = constant */
2321 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2322 if (iptr->val.i == 0) {
2325 ICONST(REG_ITMP2, iptr->val.i);
2326 M_BEQ(s1, REG_ITMP2, 0);
2328 codegen_addreference(cd, (basicblock *) iptr->target);
2332 case ICMD_IFLT: /* ..., value ==> ... */
2333 /* op1 = target JavaVM pc, val.i = constant */
2335 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2336 if (iptr->val.i == 0) {
2339 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2340 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2342 ICONST(REG_ITMP2, iptr->val.i);
2343 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2345 M_BNEZ(REG_ITMP1, 0);
2347 codegen_addreference(cd, (basicblock *) iptr->target);
2351 case ICMD_IFLE: /* ..., value ==> ... */
2352 /* op1 = target JavaVM pc, val.i = constant */
2354 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2355 if (iptr->val.i == 0) {
2359 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2360 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2361 M_BNEZ(REG_ITMP1, 0);
2364 ICONST(REG_ITMP2, iptr->val.i);
2365 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2366 M_BEQZ(REG_ITMP1, 0);
2369 codegen_addreference(cd, (basicblock *) iptr->target);
2373 case ICMD_IFNE: /* ..., value ==> ... */
2374 /* op1 = target JavaVM pc, val.i = constant */
2376 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2377 if (iptr->val.i == 0) {
2381 ICONST(REG_ITMP2, iptr->val.i);
2382 M_BNE(s1, REG_ITMP2, 0);
2384 codegen_addreference(cd, (basicblock *) iptr->target);
2388 case ICMD_IFGT: /* ..., value ==> ... */
2389 /* op1 = target JavaVM pc, val.i = constant */
2391 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2392 if (iptr->val.i == 0) {
2396 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2397 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2398 M_BEQZ(REG_ITMP1, 0);
2401 ICONST(REG_ITMP2, iptr->val.i);
2402 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2403 M_BNEZ(REG_ITMP1, 0);
2406 codegen_addreference(cd, (basicblock *) iptr->target);
2410 case ICMD_IFGE: /* ..., value ==> ... */
2411 /* op1 = target JavaVM pc, val.i = constant */
2413 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2414 if (iptr->val.i == 0) {
2418 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2419 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2422 ICONST(REG_ITMP2, iptr->val.i);
2423 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2425 M_BEQZ(REG_ITMP1, 0);
2427 codegen_addreference(cd, (basicblock *) iptr->target);
2431 case ICMD_IF_LEQ: /* ..., value ==> ... */
2432 /* op1 = target JavaVM pc, val.l = constant */
2434 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2435 if (iptr->val.l == 0) {
2439 LCONST(REG_ITMP2, iptr->val.l);
2440 M_BEQ(s1, REG_ITMP2, 0);
2442 codegen_addreference(cd, (basicblock *) iptr->target);
2446 case ICMD_IF_LLT: /* ..., value ==> ... */
2447 /* op1 = target JavaVM pc, val.l = constant */
2449 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2450 if (iptr->val.l == 0) {
2454 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2455 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2458 LCONST(REG_ITMP2, iptr->val.l);
2459 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2461 M_BNEZ(REG_ITMP1, 0);
2463 codegen_addreference(cd, (basicblock *) iptr->target);
2467 case ICMD_IF_LLE: /* ..., value ==> ... */
2468 /* op1 = target JavaVM pc, val.l = constant */
2470 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2471 if (iptr->val.l == 0) {
2475 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2476 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2477 M_BNEZ(REG_ITMP1, 0);
2480 LCONST(REG_ITMP2, iptr->val.l);
2481 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2482 M_BEQZ(REG_ITMP1, 0);
2485 codegen_addreference(cd, (basicblock *) iptr->target);
2489 case ICMD_IF_LNE: /* ..., value ==> ... */
2490 /* op1 = target JavaVM pc, val.l = constant */
2492 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2493 if (iptr->val.l == 0) {
2497 LCONST(REG_ITMP2, iptr->val.l);
2498 M_BNE(s1, REG_ITMP2, 0);
2500 codegen_addreference(cd, (basicblock *) iptr->target);
2504 case ICMD_IF_LGT: /* ..., value ==> ... */
2505 /* op1 = target JavaVM pc, val.l = constant */
2507 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2508 if (iptr->val.l == 0) {
2512 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2513 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2514 M_BEQZ(REG_ITMP1, 0);
2517 LCONST(REG_ITMP2, iptr->val.l);
2518 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2519 M_BNEZ(REG_ITMP1, 0);
2522 codegen_addreference(cd, (basicblock *) iptr->target);
2526 case ICMD_IF_LGE: /* ..., value ==> ... */
2527 /* op1 = target JavaVM pc, val.l = constant */
2529 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2530 if (iptr->val.l == 0) {
2534 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2535 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2538 LCONST(REG_ITMP2, iptr->val.l);
2539 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2541 M_BEQZ(REG_ITMP1, 0);
2543 codegen_addreference(cd, (basicblock *) iptr->target);
2547 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2548 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2549 case ICMD_IF_ACMPEQ:
2551 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2552 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2554 codegen_addreference(cd, (basicblock *) iptr->target);
2558 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2559 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2560 case ICMD_IF_ACMPNE:
2562 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2563 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2565 codegen_addreference(cd, (basicblock *) iptr->target);
2569 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2570 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2572 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2573 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2574 M_CMPLT(s1, s2, REG_ITMP1);
2575 M_BNEZ(REG_ITMP1, 0);
2576 codegen_addreference(cd, (basicblock *) iptr->target);
2580 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2581 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2583 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2584 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2585 M_CMPGT(s1, s2, REG_ITMP1);
2586 M_BNEZ(REG_ITMP1, 0);
2587 codegen_addreference(cd, (basicblock *) iptr->target);
2591 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2592 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2594 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2595 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2596 M_CMPGT(s1, s2, REG_ITMP1);
2597 M_BEQZ(REG_ITMP1, 0);
2598 codegen_addreference(cd, (basicblock *) iptr->target);
2602 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2603 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2605 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2606 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2607 M_CMPLT(s1, s2, REG_ITMP1);
2608 M_BEQZ(REG_ITMP1, 0);
2609 codegen_addreference(cd, (basicblock *) iptr->target);
2613 #ifdef CONDITIONAL_LOADCONST
2614 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2616 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2619 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2620 /* val.i = constant */
2622 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2623 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2625 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2626 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2627 M_CMPEQ(s1, REG_ZERO, d);
2628 emit_store(jd, iptr, iptr->dst, d);
2631 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2632 M_CMPEQ(s1, REG_ZERO, d);
2634 emit_store(jd, iptr, iptr->dst, d);
2638 M_MOV(s1, REG_ITMP1);
2641 ICONST(d, iptr[1].val.i);
2643 if ((s3 >= 0) && (s3 <= 255)) {
2644 M_CMOVEQ_IMM(s1, s3, d);
2646 ICONST(REG_ITMP3, s3);
2647 M_CMOVEQ(s1, REG_ITMP3, d);
2649 emit_store(jd, iptr, iptr->dst, d);
2652 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2653 /* val.i = constant */
2655 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2656 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2658 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2659 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2660 M_CMPEQ(s1, REG_ZERO, d);
2661 emit_store(jd, iptr, iptr->dst, d);
2664 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2665 M_CMPEQ(s1, REG_ZERO, d);
2667 emit_store(jd, iptr, iptr->dst, d);
2671 M_MOV(s1, REG_ITMP1);
2674 ICONST(d, iptr[1].val.i);
2676 if ((s3 >= 0) && (s3 <= 255)) {
2677 M_CMOVNE_IMM(s1, s3, d);
2679 ICONST(REG_ITMP3, s3);
2680 M_CMOVNE(s1, REG_ITMP3, d);
2682 emit_store(jd, iptr, iptr->dst, d);
2685 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2686 /* val.i = constant */
2688 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2689 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2691 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2692 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2693 M_CMPLT(s1, REG_ZERO, d);
2694 emit_store(jd, iptr, iptr->dst, d);
2697 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2698 M_CMPLE(REG_ZERO, s1, d);
2699 emit_store(jd, iptr, iptr->dst, d);
2703 M_MOV(s1, REG_ITMP1);
2706 ICONST(d, iptr[1].val.i);
2708 if ((s3 >= 0) && (s3 <= 255)) {
2709 M_CMOVLT_IMM(s1, s3, d);
2711 ICONST(REG_ITMP3, s3);
2712 M_CMOVLT(s1, REG_ITMP3, d);
2714 emit_store(jd, iptr, iptr->dst, d);
2717 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2718 /* val.i = constant */
2720 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2721 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2723 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2724 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2725 M_CMPLE(REG_ZERO, s1, d);
2726 emit_store(jd, iptr, iptr->dst, d);
2729 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2730 M_CMPLT(s1, REG_ZERO, d);
2731 emit_store(jd, iptr, iptr->dst, d);
2735 M_MOV(s1, REG_ITMP1);
2738 ICONST(d, iptr[1].val.i);
2740 if ((s3 >= 0) && (s3 <= 255)) {
2741 M_CMOVGE_IMM(s1, s3, d);
2743 ICONST(REG_ITMP3, s3);
2744 M_CMOVGE(s1, REG_ITMP3, d);
2746 emit_store(jd, iptr, iptr->dst, d);
2749 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2750 /* val.i = constant */
2752 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2753 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2755 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2756 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2757 M_CMPLT(REG_ZERO, s1, d);
2758 emit_store(jd, iptr, iptr->dst, d);
2761 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2762 M_CMPLE(s1, REG_ZERO, d);
2763 emit_store(jd, iptr, iptr->dst, d);
2767 M_MOV(s1, REG_ITMP1);
2770 ICONST(d, iptr[1].val.i);
2772 if ((s3 >= 0) && (s3 <= 255)) {
2773 M_CMOVGT_IMM(s1, s3, d);
2775 ICONST(REG_ITMP3, s3);
2776 M_CMOVGT(s1, REG_ITMP3, d);
2778 emit_store(jd, iptr, iptr->dst, d);
2781 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2782 /* val.i = constant */
2784 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2785 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2787 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2788 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2789 M_CMPLE(s1, REG_ZERO, d);
2790 emit_store(jd, iptr, iptr->dst, d);
2793 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2794 M_CMPLT(REG_ZERO, s1, d);
2795 emit_store(jd, iptr, iptr->dst, d);
2799 M_MOV(s1, REG_ITMP1);
2802 ICONST(d, iptr[1].val.i);
2804 if ((s3 >= 0) && (s3 <= 255)) {
2805 M_CMOVLE_IMM(s1, s3, d);
2807 ICONST(REG_ITMP3, s3);
2808 M_CMOVLE(s1, REG_ITMP3, d);
2810 emit_store(jd, iptr, iptr->dst, d);
2815 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2818 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2819 M_INTMOVE(s1, REG_RESULT);
2820 goto nowperformreturn;
2822 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2824 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2825 M_INTMOVE(s1, REG_RESULT);
2827 #ifdef ENABLE_VERIFIER
2829 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2830 (unresolved_class *) iptr->val.a, 0);
2832 if (opt_showdisassemble) {
2836 #endif /* ENABLE_VERIFIER */
2837 goto nowperformreturn;
2839 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2841 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2842 M_FLTMOVE(s1, REG_FRESULT);
2843 goto nowperformreturn;
2845 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2847 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2848 M_DBLMOVE(s1, REG_FRESULT);
2849 goto nowperformreturn;
2851 case ICMD_RETURN: /* ... ==> ... */
2857 p = parentargs_base;
2859 /* call trace function */
2861 if (opt_verbosecall) {
2862 M_LDA(REG_SP, REG_SP, -3 * 8);
2863 M_LST(REG_RA, REG_SP, 0 * 8);
2864 M_LST(REG_RESULT, REG_SP, 1 * 8);
2865 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2867 disp = dseg_addaddress(cd, m);
2868 M_ALD(rd->argintregs[0], REG_PV, disp);
2869 M_MOV(REG_RESULT, rd->argintregs[1]);
2870 M_DMOV(REG_FRESULT, rd->argfltregs[2]);
2871 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2873 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2874 M_ALD(REG_ITMP3, REG_PV, disp);
2875 M_JSR(REG_RA, REG_ITMP3);
2878 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2879 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2880 M_LLD(REG_RA, REG_SP, 0 * 8);
2881 M_LDA(REG_SP, REG_SP, 3 * 8);
2884 #if defined(USE_THREADS)
2885 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2886 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2887 M_ALD(REG_ITMP3, REG_PV, disp);
2889 /* we need to save the proper return value */
2891 switch (iptr->opc) {
2895 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2896 M_JSR(REG_RA, REG_ITMP3);
2897 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2901 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2902 M_JSR(REG_RA, REG_ITMP3);
2903 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2906 M_JSR(REG_RA, REG_ITMP3);
2907 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2911 /* and now restore the proper return value */
2913 switch (iptr->opc) {
2917 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2921 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2927 /* restore return address */
2929 if (!m->isleafmethod) {
2930 p--; M_ALD(REG_RA, REG_SP, p * 8);
2933 /* restore saved registers */
2935 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2936 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2938 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2939 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2942 /* deallocate stack and return */
2944 if (parentargs_base) {
2947 disp = parentargs_base * 8;
2948 lo = (short) (disp);
2949 hi = (short) (((disp) - lo) >> 16);
2953 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2955 M_LUI(REG_ITMP3,hi);
2956 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2958 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2971 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2976 tptr = (void **) iptr->target;
2978 s4ptr = iptr->val.a;
2979 l = s4ptr[1]; /* low */
2980 i = s4ptr[2]; /* high */
2982 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2984 {M_INTMOVE(s1, REG_ITMP1);}
2985 else if (l <= 32768) {
2986 M_IADD_IMM(s1, -l, REG_ITMP1);
2989 ICONST(REG_ITMP2, l);
2990 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2996 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2997 M_BEQZ(REG_ITMP2, 0);
2998 codegen_addreference(cd, (basicblock *) tptr[0]);
2999 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
3001 /* build jump table top down and use address of lowest entry */
3003 /* s4ptr += 3 + i; */
3007 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3008 dseg_addtarget(cd, (basicblock *) tptr[0]);
3013 /* length of dataseg after last dseg_addtarget is used by load */
3015 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3016 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3023 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3025 s4 i, /*l, */val, *s4ptr;
3028 tptr = (void **) iptr->target;
3030 s4ptr = iptr->val.a;
3031 /*l = s4ptr[0];*/ /* default */
3032 i = s4ptr[1]; /* count */
3034 MCODECHECK((i<<2)+8);
3035 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3041 ICONST(REG_ITMP2, val);
3042 M_BEQ(s1, REG_ITMP2, 0);
3043 codegen_addreference(cd, (basicblock *) tptr[0]);
3048 tptr = (void **) iptr->target;
3049 codegen_addreference(cd, (basicblock *) tptr[0]);
3056 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3057 /* op1 = arg count val.a = builtintable entry */
3063 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3064 /* op1 = arg count, val.a = method pointer */
3066 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3067 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3068 case ICMD_INVOKEINTERFACE:
3070 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3071 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3075 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3076 md = lm->parseddesc;
3080 s3 = md->paramcount;
3082 MCODECHECK((s3 << 1) + 64);
3084 /* copy arguments to registers or stack location */
3086 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3087 if (src->varkind == ARGVAR)
3089 if (IS_INT_LNG_TYPE(src->type)) {
3090 if (!md->params[s3].inmemory) {
3091 s1 = rd->argintregs[md->params[s3].regoff];
3092 d = emit_load_s1(jd, iptr, src, s1);
3095 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3096 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3100 if (!md->params[s3].inmemory) {
3101 s1 = rd->argfltregs[md->params[s3].regoff];
3102 d = emit_load_s1(jd, iptr, src, s1);
3103 if (IS_2_WORD_TYPE(src->type))
3109 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3110 if (IS_2_WORD_TYPE(src->type))
3111 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3113 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3118 switch (iptr->opc) {
3120 disp = dseg_addaddress(cd, bte->fp);
3121 d = md->returntype.type;
3123 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3124 M_JSR(REG_RA, REG_ITMP3);
3126 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3127 M_LDA(REG_PV, REG_RA, -disp);
3129 /* if op1 == true, we need to check for an exception */
3131 if (iptr->op1 == true) {
3132 M_BEQZ(REG_RESULT, 0);
3133 codegen_add_fillinstacktrace_ref(cd);
3138 case ICMD_INVOKESPECIAL:
3139 M_BEQZ(rd->argintregs[0], 0);
3140 codegen_add_nullpointerexception_ref(cd);
3144 case ICMD_INVOKESTATIC:
3146 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3148 disp = dseg_addaddress(cd, NULL);
3150 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3153 if (opt_showdisassemble) {
3157 d = um->methodref->parseddesc.md->returntype.type;
3160 disp = dseg_addaddress(cd, lm->stubroutine);
3161 d = lm->parseddesc->returntype.type;
3164 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3165 M_JSR(REG_RA, REG_PV);
3167 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3168 M_LDA(REG_PV, REG_RA, -disp);
3171 case ICMD_INVOKEVIRTUAL:
3172 gen_nullptr_check(rd->argintregs[0]);
3175 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3177 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3179 if (opt_showdisassemble) {
3184 d = um->methodref->parseddesc.md->returntype.type;
3187 s1 = OFFSET(vftbl_t, table[0]) +
3188 sizeof(methodptr) * lm->vftblindex;
3189 d = lm->parseddesc->returntype.type;
3192 M_ALD(REG_METHODPTR, rd->argintregs[0],
3193 OFFSET(java_objectheader, vftbl));
3194 M_ALD(REG_PV, REG_METHODPTR, s1);
3195 M_JSR(REG_RA, REG_PV);
3197 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3198 M_LDA(REG_PV, REG_RA, -disp);
3201 case ICMD_INVOKEINTERFACE:
3202 gen_nullptr_check(rd->argintregs[0]);
3205 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3207 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3209 if (opt_showdisassemble) {
3215 d = um->methodref->parseddesc.md->returntype.type;
3218 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3219 sizeof(methodptr*) * lm->class->index;
3221 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3223 d = lm->parseddesc->returntype.type;
3226 M_ALD(REG_METHODPTR, rd->argintregs[0],
3227 OFFSET(java_objectheader, vftbl));
3228 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3229 M_ALD(REG_PV, REG_METHODPTR, s2);
3230 M_JSR(REG_RA, REG_PV);
3232 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3233 M_LDA(REG_PV, REG_RA, -disp);
3237 /* d contains return type */
3239 if (d != TYPE_VOID) {
3240 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3241 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3242 M_INTMOVE(REG_RESULT, s1);
3244 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3245 if (IS_2_WORD_TYPE(iptr->dst->type))
3246 M_DMOV(REG_FRESULT, s1);
3248 M_FMOV(REG_FRESULT, s1);
3250 emit_store(jd, iptr, iptr->dst, s1);
3255 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3256 /* op1: 0 == array, 1 == class */
3257 /* val.a: (classinfo*) superclass */
3259 /* superclass is an interface:
3261 * OK if ((sub == NULL) ||
3262 * (sub->vftbl->interfacetablelength > super->index) &&
3263 * (sub->vftbl->interfacetable[-super->index] != NULL));
3265 * superclass is a class:
3267 * OK if ((sub == NULL) || (0
3268 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3269 * super->vftbl->diffvall));
3272 if (iptr->op1 == 1) {
3274 vftbl_t *supervftbl;
3277 super = (classinfo *) iptr->val.a;
3284 superindex = super->index;
3285 supervftbl = super->vftbl;
3288 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3289 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3292 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3294 /* calculate interface checkcast code size */
3298 s2 += (opt_showdisassemble ? 2 : 0);
3300 /* calculate class checkcast code size */
3302 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3304 s3 += (opt_showdisassemble ? 2 : 0);
3306 /* if class is not resolved, check which code to call */
3309 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3312 disp = dseg_adds4(cd, 0); /* super->flags */
3314 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3315 (constant_classref *) iptr->target,
3318 if (opt_showdisassemble) {
3322 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3323 M_ILD(REG_ITMP2, REG_PV, disp);
3324 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3325 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3329 /* interface checkcast code */
3331 if (!super || super->flags & ACC_INTERFACE) {
3337 codegen_addpatchref(cd,
3338 PATCHER_checkcast_instanceof_interface,
3339 (constant_classref *) iptr->target,
3342 if (opt_showdisassemble) {
3347 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3348 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3349 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3350 M_BLEZ(REG_ITMP3, 0);
3351 codegen_add_classcastexception_ref(cd);
3353 M_ALD(REG_ITMP3, REG_ITMP2,
3354 OFFSET(vftbl_t, interfacetable[0]) -
3355 superindex * sizeof(methodptr*));
3356 M_BEQZ(REG_ITMP3, 0);
3357 codegen_add_classcastexception_ref(cd);
3366 /* class checkcast code */
3368 if (!super || !(super->flags & ACC_INTERFACE)) {
3369 disp = dseg_addaddress(cd, (void *) supervftbl);
3376 codegen_addpatchref(cd,
3377 PATCHER_checkcast_instanceof_class,
3378 (constant_classref *) iptr->target,
3381 if (opt_showdisassemble) {
3386 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3387 M_ALD(REG_ITMP3, REG_PV, disp);
3388 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3389 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3391 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3392 /* if (s1 != REG_ITMP1) { */
3393 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3394 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3395 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3396 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3398 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3400 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3401 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3402 M_ALD(REG_ITMP3, REG_PV, disp);
3403 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3404 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3405 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3408 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3409 M_BNEZ(REG_ITMP3, 0);
3410 codegen_add_classcastexception_ref(cd);
3413 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3416 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3417 M_INTMOVE(s1, rd->argintregs[0]);
3419 disp = dseg_addaddress(cd, iptr->val.a);
3421 if (iptr->val.a == NULL) {
3422 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3423 (constant_classref *) iptr->target,
3426 if (opt_showdisassemble) {
3431 M_ALD(rd->argintregs[1], REG_PV, disp);
3432 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3433 M_ALD(REG_ITMP3, REG_PV, disp);
3434 M_JSR(REG_RA, REG_ITMP3);
3437 M_BEQZ(REG_RESULT, 0);
3438 codegen_add_classcastexception_ref(cd);
3441 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3442 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3445 emit_store(jd, iptr, iptr->dst, d);
3448 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3449 /* op1: 0 == array, 1 == class */
3450 /* val.a: (classinfo*) superclass */
3452 /* superclass is an interface:
3454 * return (sub != NULL) &&
3455 * (sub->vftbl->interfacetablelength > super->index) &&
3456 * (sub->vftbl->interfacetable[-super->index] != NULL);
3458 * superclass is a class:
3460 * return ((sub != NULL) && (0
3461 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3462 * super->vftbl->diffvall));
3467 vftbl_t *supervftbl;
3470 super = (classinfo *) iptr->val.a;
3477 superindex = super->index;
3478 supervftbl = super->vftbl;
3481 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3482 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3485 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3486 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3488 M_MOV(s1, REG_ITMP1);
3492 /* calculate interface instanceof code size */
3496 s2 += (opt_showdisassemble ? 2 : 0);
3498 /* calculate class instanceof code size */
3502 s3 += (opt_showdisassemble ? 2 : 0);
3506 /* if class is not resolved, check which code to call */
3509 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3512 disp = dseg_adds4(cd, 0); /* super->flags */
3514 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3515 (constant_classref *) iptr->target, disp);
3517 if (opt_showdisassemble) {
3521 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3522 M_ILD(REG_ITMP3, REG_PV, disp);
3523 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3524 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3528 /* interface instanceof code */
3530 if (!super || (super->flags & ACC_INTERFACE)) {
3536 codegen_addpatchref(cd,
3537 PATCHER_checkcast_instanceof_interface,
3538 (constant_classref *) iptr->target, 0);
3540 if (opt_showdisassemble) {
3545 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3546 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3547 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3548 M_BLEZ(REG_ITMP3, 3);
3550 M_ALD(REG_ITMP1, REG_ITMP1,
3551 OFFSET(vftbl_t, interfacetable[0]) -
3552 superindex * sizeof(methodptr*));
3553 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3561 /* class instanceof code */
3563 if (!super || !(super->flags & ACC_INTERFACE)) {
3564 disp = dseg_addaddress(cd, supervftbl);
3571 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3572 (constant_classref *) iptr->target,
3575 if (opt_showdisassemble) {
3580 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3581 M_ALD(REG_ITMP2, REG_PV, disp);
3582 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3583 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3585 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3586 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3587 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3588 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3589 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3591 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3592 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3595 emit_store(jd, iptr, iptr->dst, d);
3599 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3600 /* op1 = dimension, val.a = class */
3602 /* check for negative sizes and copy sizes to stack if necessary */
3604 MCODECHECK((iptr->op1 << 1) + 64);
3606 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3607 /* copy SAVEDVAR sizes to stack */
3609 if (src->varkind != ARGVAR) {
3610 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3611 M_LST(s2, REG_SP, s1 * 8);
3615 /* a0 = dimension count */
3617 ICONST(rd->argintregs[0], iptr->op1);
3619 /* is patcher function set? */
3621 if (iptr->val.a == NULL) {
3622 disp = dseg_addaddress(cd, NULL);
3624 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3625 (constant_classref *) iptr->target, disp);
3627 if (opt_showdisassemble) {
3632 disp = dseg_addaddress(cd, iptr->val.a);
3635 /* a1 = arraydescriptor */
3637 M_ALD(rd->argintregs[1], REG_PV, disp);
3639 /* a2 = pointer to dimensions = stack pointer */
3641 M_INTMOVE(REG_SP, rd->argintregs[2]);
3643 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3644 M_ALD(REG_ITMP3, REG_PV, disp);
3645 M_JSR(REG_RA, REG_ITMP3);
3648 /* check for exception before result assignment */
3650 M_BEQZ(REG_RESULT, 0);
3651 codegen_add_fillinstacktrace_ref(cd);
3654 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3655 M_INTMOVE(REG_RESULT, d);
3656 emit_store(jd, iptr, iptr->dst, d);
3660 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3664 } /* for instruction */
3666 /* copy values to interface registers */
3668 src = bptr->outstack;
3669 len = bptr->outdepth;
3671 #if defined(ENABLE_LSRA)
3676 if ((src->varkind != STACKVAR)) {
3678 if (IS_FLT_DBL_TYPE(s2)) {
3679 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3680 if (rd->interfaces[len][s2].flags & INMEMORY) {
3681 if (IS_2_WORD_TYPE(s2))
3682 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3684 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3687 if (IS_2_WORD_TYPE(s2))
3688 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3690 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3694 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3695 if (rd->interfaces[len][s2].flags & INMEMORY)
3696 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3698 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3704 /* At the end of a basic block we may have to append some nops,
3705 because the patcher stub calling code might be longer than the
3706 actual instruction. So codepatching does not change the
3707 following block unintentionally. */
3709 if (cd->mcodeptr < cd->lastmcodeptr) {
3710 while (cd->mcodeptr < cd->lastmcodeptr)
3714 } /* if (bptr -> flags >= BBREACHED) */
3715 } /* for basic block */
3717 dseg_createlinenumbertable(cd);
3720 /* generate exception and patcher stubs */
3729 savedmcodeptr = NULL;
3731 /* generate exception stubs */
3733 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3734 gen_resolvebranch(cd->mcodebase + eref->branchpos,
3735 eref->branchpos, cd->mcodeptr - cd->mcodebase);
3739 /* Check if the exception is an
3740 ArrayIndexOutOfBoundsException. If so, move index register
3743 if (eref->reg != -1)
3744 M_MOV(eref->reg, REG_ITMP1);
3746 /* calcuate exception address */
3748 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3750 /* move function to call into REG_ITMP3 */
3752 disp = dseg_addaddress(cd, eref->function);
3753 M_ALD(REG_ITMP3, REG_PV, disp);
3755 if (savedmcodeptr != NULL) {
3756 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3761 savedmcodeptr = cd->mcodeptr;
3763 M_MOV(REG_PV, rd->argintregs[0]);
3764 M_MOV(REG_SP, rd->argintregs[1]);
3766 if (m->isleafmethod)
3767 M_MOV(REG_RA, rd->argintregs[2]);
3769 M_ALD(rd->argintregs[2],
3770 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3772 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3773 M_MOV(REG_ITMP1, rd->argintregs[4]);
3775 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3776 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3778 if (m->isleafmethod)
3779 M_AST(REG_RA, REG_SP, 1 * 8);
3781 M_JSR(REG_RA, REG_ITMP3);
3783 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3785 if (m->isleafmethod)
3786 M_ALD(REG_RA, REG_SP, 1 * 8);
3788 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3789 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3791 a = dseg_addaddress(cd, asm_handle_exception);
3792 M_ALD(REG_ITMP3, REG_PV, a);
3799 /* generate code patching stub call code */
3801 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3802 /* check code segment size */
3806 /* Get machine code which is patched back in later. The
3807 call is 2 instruction words long. */
3809 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3811 /* We need to split this, because an unaligned 8 byte read
3812 causes a SIGSEGV. */
3814 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
3815 ((u4 *) tmpmcodeptr)[0];
3817 /* Patch in the call to call the following code (done at
3820 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3821 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3823 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3825 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3827 new_internalerror("Jump offset is out of range: %d > +/-%d",
3835 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3837 /* create stack frame */
3839 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3841 /* calculate return address and move it onto the stack */
3843 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3844 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3846 /* move pointer to java_objectheader onto stack */
3848 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3849 /* create a virtual java_objectheader */
3851 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3852 disp = dseg_addaddress(cd, NULL); /* vftbl */
3854 M_LDA(REG_ITMP3, REG_PV, disp);
3855 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3860 /* move machine code onto stack */
3862 disp = dseg_adds8(cd, mcode);
3863 M_LLD(REG_ITMP3, REG_PV, disp);
3864 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3866 /* move class/method/field reference onto stack */
3868 disp = dseg_addaddress(cd, pref->ref);
3869 M_ALD(REG_ITMP3, REG_PV, disp);
3870 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3872 /* move data segment displacement onto stack */
3874 disp = dseg_adds4(cd, pref->disp);
3875 M_ILD(REG_ITMP3, REG_PV, disp);
3876 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3878 /* move patcher function pointer onto stack */
3880 disp = dseg_addaddress(cd, pref->patcher);
3881 M_ALD(REG_ITMP3, REG_PV, disp);
3882 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3884 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3885 M_ALD(REG_ITMP3, REG_PV, disp);
3890 /* generate replacement-out stubs */
3895 replacementpoint = jd->code->rplpoints;
3897 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3898 /* check code segment size */
3902 /* note start of stub code */
3904 replacementpoint->outcode = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
3906 /* make machine code for patching */
3908 savedmcodeptr = cd->mcodeptr;
3909 cd->mcodeptr = (u1 *) &(replacementpoint->mcode);
3911 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3912 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3914 new_internalerror("Jump offset is out of range: %d > +/-%d",
3919 M_NOP; /* delay slot */
3921 cd->mcodeptr = savedmcodeptr;
3923 /* create stack frame - 16-byte aligned */
3925 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3927 /* push address of `rplpoint` struct */
3929 disp = dseg_addaddress(cd, replacementpoint);
3930 M_ALD(REG_ITMP3, REG_PV, disp);
3931 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3933 /* jump to replacement function */
3935 disp = dseg_addaddress(cd, asm_replacement_out);
3936 M_ALD(REG_ITMP3, REG_PV, disp);
3938 M_NOP; /* delay slot */
3945 /* everything's ok */
3951 /* createcompilerstub **********************************************************
3953 Creates a stub routine which calls the compiler.
3955 *******************************************************************************/
3957 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3958 #define COMPILERSTUB_CODESIZE 4 * 4
3960 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3963 u1 *createcompilerstub(methodinfo *m)
3965 u1 *s; /* memory to hold the stub */
3970 s = CNEW(u1, COMPILERSTUB_SIZE);
3972 /* set data pointer and code pointer */
3975 s = s + COMPILERSTUB_DATASIZE;
3977 /* mark start of dump memory area */
3979 dumpsize = dump_size();
3981 cd = DNEW(codegendata);
3984 /* Store the methodinfo* in the same place as in the methodheader
3985 for compiled methods. */
3987 d[0] = (ptrint) asm_call_jit_compiler;
3990 M_ALD_INTERN(REG_ITMP1, REG_PV, -1 * SIZEOF_VOID_P); /* method pointer */
3991 M_ALD_INTERN(REG_PV, REG_PV, -2 * SIZEOF_VOID_P); /* pointer to compiler */
3995 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3997 #if defined(ENABLE_STATISTICS)
3999 count_cstub_len += COMPILERSTUB_SIZE;
4002 /* release dump area */
4004 dump_release(dumpsize);
4010 /* createnativestub ************************************************************
4012 Creates a stub routine which calls a native method.
4014 *******************************************************************************/
4016 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4021 s4 stackframesize; /* size of stackframe if needed */
4024 s4 i, j; /* count variables */
4027 s4 funcdisp; /* displacement of the function */
4029 /* get required compiler data */
4035 /* initialize variables */
4038 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4040 /* calculate stack frame size */
4043 1 + /* return address */
4044 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4045 sizeof(localref_table) / SIZEOF_VOID_P +
4046 md->paramcount + /* for saving arguments over calls */
4047 1 + /* for saving return address */
4050 /* create method header */
4052 #if SIZEOF_VOID_P == 4
4053 (void) dseg_addaddress(cd, m); /* MethodPointer */
4055 (void) dseg_addaddress(cd, m); /* MethodPointer */
4056 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4057 (void) dseg_adds4(cd, 0); /* IsSync */
4058 (void) dseg_adds4(cd, 0); /* IsLeaf */
4059 (void) dseg_adds4(cd, 0); /* IntSave */
4060 (void) dseg_adds4(cd, 0); /* FltSave */
4061 (void) dseg_addlinenumbertablesize(cd);
4062 (void) dseg_adds4(cd, 0); /* ExTableSize */
4064 /* generate stub code */
4066 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
4067 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
4069 /* call trace function */
4071 if (opt_verbosecall) {
4072 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4074 /* save integer argument registers */
4076 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4077 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4078 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4080 /* save and copy float arguments into integer registers */
4082 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4083 t = md->paramtypes[i].type;
4085 if (IS_FLT_DBL_TYPE(t)) {
4086 if (IS_2_WORD_TYPE(t)) {
4087 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4088 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4090 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4091 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4096 disp = dseg_addaddress(cd, m);
4097 M_ALD(REG_ITMP1, REG_PV, disp);
4098 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4099 disp = dseg_addaddress(cd, builtin_trace_args);
4100 M_ALD(REG_ITMP3, REG_PV, disp);
4101 M_JSR(REG_RA, REG_ITMP3);
4104 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4105 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4106 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4108 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4109 t = md->paramtypes[i].type;
4111 if (IS_FLT_DBL_TYPE(t)) {
4112 if (IS_2_WORD_TYPE(t))
4113 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4115 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4119 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4122 /* get function address (this must happen before the stackframeinfo) */
4124 funcdisp = dseg_addaddress(cd, f);
4126 #if !defined(WITH_STATIC_CLASSPATH)
4128 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4130 if (opt_showdisassemble) {
4136 /* save integer and float argument registers */
4138 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4139 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4140 M_LST(rd->argintregs[i], REG_SP, j * 8);
4145 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4146 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4147 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4152 /* prepare data structures for native function call */
4154 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4155 M_MOV(REG_PV, rd->argintregs[1]);
4156 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4157 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4158 disp = dseg_addaddress(cd, codegen_start_native_call);
4159 M_ALD(REG_ITMP3, REG_PV, disp);
4160 M_JSR(REG_RA, REG_ITMP3);
4161 M_NOP; /* XXX fill me! */
4163 /* restore integer and float argument registers */
4165 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4166 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4167 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4172 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4173 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4174 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4179 /* copy or spill arguments to new locations */
4181 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4182 t = md->paramtypes[i].type;
4184 if (IS_INT_LNG_TYPE(t)) {
4185 if (!md->params[i].inmemory) {
4186 s1 = rd->argintregs[md->params[i].regoff];
4188 if (!nmd->params[j].inmemory) {
4189 s2 = rd->argintregs[nmd->params[j].regoff];
4192 s2 = nmd->params[j].regoff;
4193 M_AST(s1, REG_SP, s2 * 8);
4197 s1 = md->params[i].regoff + stackframesize;
4198 s2 = nmd->params[j].regoff;
4199 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4200 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4204 if (!md->params[i].inmemory) {
4205 s1 = rd->argfltregs[md->params[i].regoff];
4207 if (!nmd->params[j].inmemory) {
4208 s2 = rd->argfltregs[nmd->params[j].regoff];
4209 if (IS_2_WORD_TYPE(t))
4215 s2 = nmd->params[j].regoff;
4216 if (IS_2_WORD_TYPE(t))
4217 M_DST(s1, REG_SP, s2 * 8);
4219 M_FST(s1, REG_SP, s2 * 8);
4223 s1 = md->params[i].regoff + stackframesize;
4224 s2 = nmd->params[j].regoff;
4225 if (IS_2_WORD_TYPE(t)) {
4226 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4227 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4229 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4230 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4236 /* put class into second argument register */
4238 if (m->flags & ACC_STATIC) {
4239 disp = dseg_addaddress(cd, m->class);
4240 M_ALD(rd->argintregs[1], REG_PV, disp);
4243 /* put env into first argument register */
4245 disp = dseg_addaddress(cd, _Jv_env);
4246 M_ALD(rd->argintregs[0], REG_PV, disp);
4248 /* do the native function call */
4250 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4251 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4252 M_NOP; /* delay slot */
4254 /* save return value */
4256 if (IS_INT_LNG_TYPE(md->returntype.type))
4257 M_LST(REG_RESULT, REG_SP, 0 * 8);
4259 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4261 /* remove native stackframe info */
4263 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4264 disp = dseg_addaddress(cd, codegen_finish_native_call);
4265 M_ALD(REG_ITMP3, REG_PV, disp);
4266 M_JSR(REG_RA, REG_ITMP3);
4267 M_NOP; /* XXX fill me! */
4269 /* call finished trace function */
4271 if (opt_verbosecall) {
4272 if (IS_INT_LNG_TYPE(md->returntype.type))
4273 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4275 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4277 disp = dseg_addaddress(cd, m);
4278 M_ALD(rd->argintregs[0], REG_PV, disp);
4280 M_MOV(REG_RESULT, rd->argintregs[1]);
4281 M_DMFC1(REG_ITMP1, REG_FRESULT);
4282 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4283 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4285 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4286 M_ALD(REG_ITMP3, REG_PV, disp);
4287 M_JSR(REG_RA, REG_ITMP3);
4291 /* check for exception */
4293 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4294 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4295 M_ALD(REG_ITMP3, REG_PV, disp);
4296 M_JSR(REG_RA, REG_ITMP3);
4298 M_MOV(REG_RESULT, REG_ITMP3);
4300 disp = dseg_addaddress(cd, &_exceptionptr);
4301 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4303 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4305 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4307 /* restore return value */
4309 if (IS_INT_LNG_TYPE(md->returntype.type))
4310 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4312 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4314 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4315 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4317 M_RET(REG_RA); /* return to caller */
4318 M_NOP; /* DELAY SLOT */
4320 /* handle exception */
4322 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4324 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4325 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4326 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4327 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4330 /* generate static stub call code */
4338 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4339 /* Get machine code which is patched back in later. The
4340 call is 2 instruction words long. */
4342 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
4344 /* We need to split this, because an unaligned 8 byte read
4345 causes a SIGSEGV. */
4347 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
4348 ((u4 *) tmpmcodeptr)[0];
4350 /* Patch in the call to call the following code (done at
4353 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4354 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4356 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
4358 M_NOP; /* branch delay slot */
4360 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4362 /* create stack frame */
4364 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4366 /* move return address onto stack */
4368 M_AST(REG_RA, REG_SP, 5 * 8);
4370 /* move pointer to java_objectheader onto stack */
4372 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4373 /* order reversed because of data segment layout */
4375 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4376 disp = dseg_addaddress(cd, NULL); /* vftbl */
4378 M_LDA(REG_ITMP3, REG_PV, disp);
4379 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4381 M_AST(REG_ZERO, REG_SP, 4 * 8);
4384 /* move machine code onto stack */
4386 disp = dseg_adds8(cd, mcode);
4387 M_LLD(REG_ITMP3, REG_PV, disp);
4388 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4390 /* move class/method/field reference onto stack */
4392 disp = dseg_addaddress(cd, pref->ref);
4393 M_ALD(REG_ITMP3, REG_PV, disp);
4394 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4396 /* move data segment displacement onto stack */
4398 disp = dseg_adds4(cd, pref->disp);
4399 M_ILD(REG_ITMP3, REG_PV, disp);
4400 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4402 /* move patcher function pointer onto stack */
4404 disp = dseg_addaddress(cd, pref->patcher);
4405 M_ALD(REG_ITMP3, REG_PV, disp);
4406 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4408 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4409 M_ALD(REG_ITMP3, REG_PV, disp);
4417 return jd->code->entrypoint;
4422 * These are local overrides for various environment variables in Emacs.
4423 * Please do not remove this and leave it at the end of the file, where
4424 * Emacs will automagically detect them.
4425 * ---------------------------------------------------------------------
4428 * indent-tabs-mode: t
4432 * vim:noexpandtab:sw=4:ts=4: