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 4826 2006-04-24 16:06:16Z 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)((u1*)cd->mcodeptr - cd->mcodebase);
403 assert(cd->lastmcodeptr <= (u1*)cd->mcodeptr);
404 cd->lastmcodeptr = (u1*)cd->mcodeptr + 2*4; /* br + delay slot */
407 /* store relative start of block */
409 bptr->mpc = (s4) ((u1 *) 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((u1 *) 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 ((iptr->target != NULL) && (iptr->val.a == NULL)) {
555 disp = dseg_addaddress(cd, iptr->val.a);
557 codegen_addpatchref(cd, PATCHER_aconst,
558 (unresolved_class *) iptr->target, disp);
560 if (opt_showdisassemble) {
564 M_ALD(d, REG_PV, disp);
567 if (iptr->val.a == NULL) {
568 M_INTMOVE(REG_ZERO, d);
570 disp = dseg_addaddress(cd, iptr->val.a);
571 M_ALD(d, REG_PV, disp);
574 emit_store(jd, iptr, iptr->dst, d);
578 /* load/store operations **********************************************/
580 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
581 /* op1 = local variable */
583 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
584 if ((iptr->dst->varkind == LOCALVAR) &&
585 (iptr->dst->varnum == iptr->op1))
587 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
588 if (var->flags & INMEMORY)
589 #if SIZEOF_VOID_P == 8
590 M_LLD(d, REG_SP, var->regoff * 8);
592 M_ILD(d, REG_SP, var->regoff * 8);
595 M_INTMOVE(var->regoff,d);
596 emit_store(jd, iptr, iptr->dst, d);
599 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
600 /* op1 = local variable */
602 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
603 if ((iptr->dst->varkind == LOCALVAR) &&
604 (iptr->dst->varnum == iptr->op1))
606 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
607 if (var->flags & INMEMORY)
608 M_LLD(d, REG_SP, var->regoff * 8);
610 M_INTMOVE(var->regoff,d);
611 emit_store(jd, iptr, iptr->dst, d);
614 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
615 /* op1 = local variable */
617 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
618 if ((iptr->dst->varkind == LOCALVAR) &&
619 (iptr->dst->varnum == iptr->op1))
621 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
622 if (var->flags & INMEMORY)
623 M_ALD(d, REG_SP, var->regoff * 8);
625 M_INTMOVE(var->regoff,d);
626 emit_store(jd, iptr, iptr->dst, d);
629 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
630 /* op1 = local variable */
632 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
633 if ((iptr->dst->varkind == LOCALVAR) &&
634 (iptr->dst->varnum == iptr->op1))
636 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
637 if (var->flags & INMEMORY)
638 M_FLD(d, REG_SP, var->regoff * 8);
640 M_FMOV(var->regoff, d);
641 emit_store(jd, iptr, iptr->dst, d);
644 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
645 /* op1 = local variable */
647 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
648 if ((iptr->dst->varkind == LOCALVAR) &&
649 (iptr->dst->varnum == iptr->op1))
651 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
652 if (var->flags & INMEMORY)
653 M_DLD(d, REG_SP, var->regoff * 8);
655 M_DMOV(var->regoff, d);
656 emit_store(jd, iptr, iptr->dst, d);
660 case ICMD_ISTORE: /* ..., value ==> ... */
661 /* op1 = local variable */
663 if ((src->varkind == LOCALVAR) &&
664 (src->varnum == iptr->op1))
666 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
667 if (var->flags & INMEMORY) {
668 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
669 #if SIZEOF_VOID_P == 8
670 M_LST(s1, REG_SP, var->regoff * 8);
672 M_IST(s1, REG_SP, var->regoff * 8);
675 s1 = emit_load_s1(jd, iptr, src, var->regoff);
676 M_INTMOVE(s1, var->regoff);
680 case ICMD_LSTORE: /* ..., value ==> ... */
681 /* op1 = local variable */
683 if ((src->varkind == LOCALVAR) &&
684 (src->varnum == iptr->op1))
686 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
687 if (var->flags & INMEMORY) {
688 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
689 M_LST(s1, REG_SP, var->regoff * 8);
691 s1 = emit_load_s1(jd, iptr, src, var->regoff);
692 M_INTMOVE(s1, var->regoff);
696 case ICMD_ASTORE: /* ..., value ==> ... */
697 /* op1 = local variable */
699 if ((src->varkind == LOCALVAR) &&
700 (src->varnum == iptr->op1))
702 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
703 if (var->flags & INMEMORY) {
704 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
705 M_AST(s1, REG_SP, var->regoff * 8);
707 s1 = emit_load_s1(jd, iptr, src, var->regoff);
708 M_INTMOVE(s1, var->regoff);
712 case ICMD_FSTORE: /* ..., value ==> ... */
713 /* op1 = local variable */
715 if ((src->varkind == LOCALVAR) &&
716 (src->varnum == iptr->op1))
718 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
719 if (var->flags & INMEMORY) {
720 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
721 M_FST(s1, REG_SP, var->regoff * 8);
723 s1 = emit_load_s1(jd, iptr, src, var->regoff);
724 M_FMOV(s1, var->regoff);
728 case ICMD_DSTORE: /* ..., value ==> ... */
729 /* op1 = local variable */
731 if ((src->varkind == LOCALVAR) &&
732 (src->varnum == iptr->op1))
734 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
735 if (var->flags & INMEMORY) {
736 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
737 M_DST(s1, REG_SP, var->regoff * 8);
739 s1 = emit_load_s1(jd, iptr, src, var->regoff);
740 M_DMOV(s1, var->regoff);
745 /* pop/dup/swap operations ********************************************/
747 /* attention: double and longs are only one entry in CACAO ICMDs */
749 case ICMD_POP: /* ..., value ==> ... */
750 case ICMD_POP2: /* ..., value, value ==> ... */
753 case ICMD_DUP: /* ..., a ==> ..., a, a */
754 M_COPY(src, iptr->dst);
757 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
759 M_COPY(src, iptr->dst);
760 M_COPY(src->prev, iptr->dst->prev);
761 M_COPY(iptr->dst, iptr->dst->prev->prev);
764 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
766 M_COPY(src, iptr->dst);
767 M_COPY(src->prev, iptr->dst->prev);
768 M_COPY(src->prev->prev, iptr->dst->prev->prev);
769 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
772 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
774 M_COPY(src, iptr->dst);
775 M_COPY(src->prev, iptr->dst->prev);
778 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
780 M_COPY(src, iptr->dst);
781 M_COPY(src->prev, iptr->dst->prev);
782 M_COPY(src->prev->prev, iptr->dst->prev->prev);
783 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
784 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
787 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
789 M_COPY(src, iptr->dst);
790 M_COPY(src->prev, iptr->dst->prev);
791 M_COPY(src->prev->prev, iptr->dst->prev->prev);
792 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
793 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
794 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
797 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
799 M_COPY(src, iptr->dst->prev);
800 M_COPY(src->prev, iptr->dst);
804 /* integer operations *************************************************/
806 case ICMD_INEG: /* ..., value ==> ..., - value */
808 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
809 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
810 M_ISUB(REG_ZERO, s1, d);
811 emit_store(jd, iptr, iptr->dst, d);
814 case ICMD_LNEG: /* ..., value ==> ..., - value */
816 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
817 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
818 M_LSUB(REG_ZERO, s1, d);
819 emit_store(jd, iptr, iptr->dst, d);
822 case ICMD_I2L: /* ..., value ==> ..., value */
824 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
825 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
827 emit_store(jd, iptr, iptr->dst, d);
830 case ICMD_L2I: /* ..., value ==> ..., value */
832 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
833 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
834 M_ISLL_IMM(s1, 0, d );
835 emit_store(jd, iptr, iptr->dst, d);
838 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
840 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
841 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
842 M_LSLL_IMM(s1, 56, d);
843 M_LSRA_IMM( d, 56, d);
844 emit_store(jd, iptr, iptr->dst, d);
847 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
849 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
850 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
852 emit_store(jd, iptr, iptr->dst, d);
855 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
857 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
858 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
859 M_LSLL_IMM(s1, 48, d);
860 M_LSRA_IMM( d, 48, d);
861 emit_store(jd, iptr, iptr->dst, d);
865 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
867 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
868 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
869 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
871 emit_store(jd, iptr, iptr->dst, d);
874 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
875 /* val.i = constant */
877 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
878 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
879 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
880 M_IADD_IMM(s1, iptr->val.i, d);
882 ICONST(REG_ITMP2, iptr->val.i);
883 M_IADD(s1, REG_ITMP2, d);
885 emit_store(jd, iptr, iptr->dst, d);
888 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
890 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
891 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
892 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
894 emit_store(jd, iptr, iptr->dst, d);
897 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
898 /* val.l = constant */
900 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
901 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
902 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
903 M_LADD_IMM(s1, iptr->val.l, d);
905 LCONST(REG_ITMP2, iptr->val.l);
906 M_LADD(s1, REG_ITMP2, d);
908 emit_store(jd, iptr, iptr->dst, d);
911 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
913 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
914 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
915 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
917 emit_store(jd, iptr, iptr->dst, d);
920 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
921 /* val.i = constant */
923 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
924 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
925 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
926 M_IADD_IMM(s1, -iptr->val.i, d);
928 ICONST(REG_ITMP2, iptr->val.i);
929 M_ISUB(s1, REG_ITMP2, d);
931 emit_store(jd, iptr, iptr->dst, d);
934 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
936 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
937 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
938 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
940 emit_store(jd, iptr, iptr->dst, d);
943 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
944 /* val.l = constant */
946 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
947 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
948 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
949 M_LADD_IMM(s1, -iptr->val.l, d);
951 LCONST(REG_ITMP2, iptr->val.l);
952 M_LSUB(s1, REG_ITMP2, d);
954 emit_store(jd, iptr, iptr->dst, d);
957 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
959 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
960 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
961 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
966 emit_store(jd, iptr, iptr->dst, d);
969 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
970 /* val.i = constant */
972 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
973 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
974 ICONST(REG_ITMP2, iptr->val.i);
975 M_IMUL(s1, REG_ITMP2);
979 emit_store(jd, iptr, iptr->dst, d);
982 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
984 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
985 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
986 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
991 emit_store(jd, iptr, iptr->dst, d);
994 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
995 /* val.l = constant */
997 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
998 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
999 LCONST(REG_ITMP2, iptr->val.l);
1000 M_LMUL(s1, REG_ITMP2);
1004 emit_store(jd, iptr, iptr->dst, d);
1007 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1009 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1010 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1011 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1017 emit_store(jd, iptr, iptr->dst, d);
1020 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1022 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1023 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1024 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1030 emit_store(jd, iptr, iptr->dst, d);
1033 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1035 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1036 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1037 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1043 emit_store(jd, iptr, iptr->dst, d);
1046 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1048 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1049 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1050 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1056 emit_store(jd, iptr, iptr->dst, d);
1059 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1060 case ICMD_LDIVPOW2: /* val.i = constant */
1062 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1063 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1064 M_LSRA_IMM(s1, 63, REG_ITMP2);
1065 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1066 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1067 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1068 emit_store(jd, iptr, iptr->dst, d);
1071 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1073 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1074 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1075 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1077 emit_store(jd, iptr, iptr->dst, d);
1080 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1081 /* val.i = constant */
1083 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1084 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1085 M_ISLL_IMM(s1, iptr->val.i, d);
1086 emit_store(jd, iptr, iptr->dst, d);
1089 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1091 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1093 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1095 emit_store(jd, iptr, iptr->dst, d);
1098 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1099 /* val.i = constant */
1101 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1102 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1103 M_ISRA_IMM(s1, iptr->val.i, d);
1104 emit_store(jd, iptr, iptr->dst, d);
1107 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1109 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1110 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1111 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1113 emit_store(jd, iptr, iptr->dst, d);
1116 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1117 /* val.i = constant */
1119 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1120 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1121 M_ISRL_IMM(s1, iptr->val.i, d);
1122 emit_store(jd, iptr, iptr->dst, d);
1125 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1127 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1128 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1129 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1131 emit_store(jd, iptr, iptr->dst, d);
1134 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1135 /* val.i = constant */
1137 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1138 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1139 M_LSLL_IMM(s1, iptr->val.i, d);
1140 emit_store(jd, iptr, iptr->dst, d);
1143 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1145 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1146 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1147 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1149 emit_store(jd, iptr, iptr->dst, d);
1152 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1153 /* val.i = constant */
1155 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1156 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1157 M_LSRA_IMM(s1, iptr->val.i, d);
1158 emit_store(jd, iptr, iptr->dst, d);
1161 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1163 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1164 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1165 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1167 emit_store(jd, iptr, iptr->dst, d);
1170 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1171 /* val.i = constant */
1173 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1174 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1175 M_LSRL_IMM(s1, iptr->val.i, d);
1176 emit_store(jd, iptr, iptr->dst, d);
1179 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1182 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1183 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1184 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1186 emit_store(jd, iptr, iptr->dst, d);
1189 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1190 /* val.i = constant */
1192 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1193 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1194 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1195 M_AND_IMM(s1, iptr->val.i, d);
1197 ICONST(REG_ITMP2, iptr->val.i);
1198 M_AND(s1, REG_ITMP2, d);
1200 emit_store(jd, iptr, iptr->dst, d);
1203 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1204 /* val.i = constant */
1206 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1207 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1209 M_MOV(s1, REG_ITMP1);
1212 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1213 M_AND_IMM(s1, iptr->val.i, d);
1216 M_ISUB(REG_ZERO, s1, d);
1217 M_AND_IMM(d, iptr->val.i, d);
1219 ICONST(REG_ITMP2, iptr->val.i);
1220 M_AND(s1, REG_ITMP2, d);
1223 M_ISUB(REG_ZERO, s1, d);
1224 M_AND(d, REG_ITMP2, d);
1226 M_ISUB(REG_ZERO, d, d);
1227 emit_store(jd, iptr, iptr->dst, d);
1230 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1231 /* val.l = constant */
1233 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1234 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1235 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1236 M_AND_IMM(s1, iptr->val.l, d);
1238 LCONST(REG_ITMP2, iptr->val.l);
1239 M_AND(s1, REG_ITMP2, d);
1241 emit_store(jd, iptr, iptr->dst, d);
1244 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1245 /* val.l = constant */
1247 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1248 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1250 M_MOV(s1, REG_ITMP1);
1253 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1254 M_AND_IMM(s1, iptr->val.l, d);
1257 M_LSUB(REG_ZERO, s1, d);
1258 M_AND_IMM(d, iptr->val.l, d);
1260 LCONST(REG_ITMP2, iptr->val.l);
1261 M_AND(s1, REG_ITMP2, d);
1264 M_LSUB(REG_ZERO, s1, d);
1265 M_AND(d, REG_ITMP2, d);
1267 M_LSUB(REG_ZERO, d, d);
1268 emit_store(jd, iptr, iptr->dst, d);
1271 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1274 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1275 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1276 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1278 emit_store(jd, iptr, iptr->dst, d);
1281 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1282 /* val.i = constant */
1284 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1285 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1286 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1287 M_OR_IMM(s1, iptr->val.i, d);
1289 ICONST(REG_ITMP2, iptr->val.i);
1290 M_OR(s1, REG_ITMP2, d);
1292 emit_store(jd, iptr, iptr->dst, d);
1295 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1296 /* val.l = constant */
1298 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1299 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1300 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1301 M_OR_IMM(s1, iptr->val.l, d);
1303 LCONST(REG_ITMP2, iptr->val.l);
1304 M_OR(s1, REG_ITMP2, d);
1306 emit_store(jd, iptr, iptr->dst, d);
1309 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1312 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1313 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1314 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1316 emit_store(jd, iptr, iptr->dst, d);
1319 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1320 /* val.i = constant */
1322 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1323 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1324 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1325 M_XOR_IMM(s1, iptr->val.i, d);
1327 ICONST(REG_ITMP2, iptr->val.i);
1328 M_XOR(s1, REG_ITMP2, d);
1330 emit_store(jd, iptr, iptr->dst, d);
1333 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1334 /* val.l = constant */
1336 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1337 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1338 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1339 M_XOR_IMM(s1, iptr->val.l, d);
1341 LCONST(REG_ITMP2, iptr->val.l);
1342 M_XOR(s1, REG_ITMP2, d);
1344 emit_store(jd, iptr, iptr->dst, d);
1348 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1350 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1351 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1352 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1353 M_CMPLT(s1, s2, REG_ITMP3);
1354 M_CMPLT(s2, s1, REG_ITMP1);
1355 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1356 emit_store(jd, iptr, iptr->dst, d);
1360 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1361 /* op1 = variable, val.i = constant */
1363 var = &(rd->locals[iptr->op1][TYPE_INT]);
1364 if (var->flags & INMEMORY) {
1366 M_LLD(s1, REG_SP, var->regoff * 8);
1369 M_IADD_IMM(s1, iptr->val.i, s1);
1370 if (var->flags & INMEMORY)
1371 M_LST(s1, REG_SP, var->regoff * 8);
1375 /* floating operations ************************************************/
1377 case ICMD_FNEG: /* ..., value ==> ..., - value */
1379 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1380 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1382 emit_store(jd, iptr, iptr->dst, d);
1385 case ICMD_DNEG: /* ..., value ==> ..., - value */
1387 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1388 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1390 emit_store(jd, iptr, iptr->dst, d);
1393 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1395 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1396 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1397 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1399 emit_store(jd, iptr, iptr->dst, d);
1402 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1404 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1405 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1406 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1408 emit_store(jd, iptr, iptr->dst, d);
1411 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1413 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1414 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1415 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1417 emit_store(jd, iptr, iptr->dst, d);
1420 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1422 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1423 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1424 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1426 emit_store(jd, iptr, iptr->dst, d);
1429 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1431 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1432 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1433 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1435 emit_store(jd, iptr, iptr->dst, d);
1438 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1440 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1441 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1442 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1444 emit_store(jd, iptr, iptr->dst, d);
1447 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1449 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1450 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1451 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1453 emit_store(jd, iptr, iptr->dst, d);
1456 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1458 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1459 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1460 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1462 emit_store(jd, iptr, iptr->dst, d);
1466 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1468 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1469 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1470 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1471 M_FDIV(s1,s2, REG_FTMP3);
1472 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1473 M_CVTLF(REG_FTMP3, REG_FTMP3);
1474 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1475 M_FSUB(s1, REG_FTMP3, d);
1476 emit_store(jd, iptr, iptr->dst, d);
1479 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1481 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1482 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1483 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1484 M_DDIV(s1,s2, REG_FTMP3);
1485 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1486 M_CVTLD(REG_FTMP3, REG_FTMP3);
1487 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1488 M_DSUB(s1, REG_FTMP3, d);
1489 emit_store(jd, iptr, iptr->dst, d);
1493 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1495 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1496 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1499 emit_store(jd, iptr, iptr->dst, d);
1502 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1504 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1505 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1508 emit_store(jd, iptr, iptr->dst, d);
1512 /* XXX these do not work correctly */
1514 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1516 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1517 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1518 M_TRUNCFI(s1, REG_FTMP1);
1519 M_MOVDI(REG_FTMP1, d);
1521 emit_store(jd, iptr, iptr->dst, d);
1524 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1526 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1527 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1528 M_TRUNCDI(s1, REG_FTMP1);
1529 M_MOVDI(REG_FTMP1, d);
1531 emit_store(jd, iptr, iptr->dst, d);
1534 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1536 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1537 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1538 M_TRUNCFL(s1, REG_FTMP1);
1539 M_MOVDL(REG_FTMP1, d);
1541 emit_store(jd, iptr, iptr->dst, d);
1544 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1546 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1547 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1548 M_TRUNCDL(s1, REG_FTMP1);
1549 M_MOVDL(REG_FTMP1, d);
1551 emit_store(jd, iptr, iptr->dst, d);
1555 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1557 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1558 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1560 emit_store(jd, iptr, iptr->dst, d);
1563 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1565 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1566 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1568 emit_store(jd, iptr, iptr->dst, d);
1571 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1573 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1574 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1575 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1578 M_LADD_IMM(REG_ZERO, 1, d);
1582 M_LSUB_IMM(REG_ZERO, 1, d);
1583 M_CMOVT(REG_ZERO, d);
1584 emit_store(jd, iptr, iptr->dst, d);
1587 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1589 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1590 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1591 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1594 M_LADD_IMM(REG_ZERO, 1, d);
1598 M_LSUB_IMM(REG_ZERO, 1, d);
1599 M_CMOVT(REG_ZERO, d);
1600 emit_store(jd, iptr, iptr->dst, d);
1603 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1605 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1606 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1607 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1610 M_LSUB_IMM(REG_ZERO, 1, d);
1614 M_LADD_IMM(REG_ZERO, 1, d);
1615 M_CMOVT(REG_ZERO, d);
1616 emit_store(jd, iptr, iptr->dst, d);
1619 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1621 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1622 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1623 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1626 M_LSUB_IMM(REG_ZERO, 1, d);
1630 M_LADD_IMM(REG_ZERO, 1, d);
1631 M_CMOVT(REG_ZERO, d);
1632 emit_store(jd, iptr, iptr->dst, d);
1636 /* memory operations **************************************************/
1638 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1640 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1641 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1642 gen_nullptr_check(s1);
1643 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1644 emit_store(jd, iptr, iptr->dst, d);
1647 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1649 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1650 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1651 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1652 if (iptr->op1 == 0) {
1653 gen_nullptr_check(s1);
1656 M_AADD(s2, s1, REG_ITMP3);
1657 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1658 emit_store(jd, iptr, iptr->dst, d);
1661 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1663 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1664 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1665 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1666 if (iptr->op1 == 0) {
1667 gen_nullptr_check(s1);
1670 M_AADD(s2, s1, REG_ITMP3);
1671 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1672 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1673 emit_store(jd, iptr, iptr->dst, d);
1676 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1678 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1679 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1680 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1681 if (iptr->op1 == 0) {
1682 gen_nullptr_check(s1);
1685 M_AADD(s2, s1, REG_ITMP3);
1686 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1687 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1688 emit_store(jd, iptr, iptr->dst, d);
1691 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1693 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1694 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1695 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1696 if (iptr->op1 == 0) {
1697 gen_nullptr_check(s1);
1700 M_ASLL_IMM(s2, 2, REG_ITMP3);
1701 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1702 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1703 emit_store(jd, iptr, iptr->dst, d);
1706 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1708 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1709 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1710 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1711 if (iptr->op1 == 0) {
1712 gen_nullptr_check(s1);
1715 M_ASLL_IMM(s2, 3, REG_ITMP3);
1716 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1717 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1718 emit_store(jd, iptr, iptr->dst, d);
1721 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1723 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1724 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1725 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1726 if (iptr->op1 == 0) {
1727 gen_nullptr_check(s1);
1730 M_ASLL_IMM(s2, 2, REG_ITMP3);
1731 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1732 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1733 emit_store(jd, iptr, iptr->dst, d);
1736 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1738 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1739 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1740 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1741 if (iptr->op1 == 0) {
1742 gen_nullptr_check(s1);
1745 M_ASLL_IMM(s2, 3, REG_ITMP3);
1746 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1747 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1748 emit_store(jd, iptr, iptr->dst, d);
1751 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1753 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1754 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1755 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1756 if (iptr->op1 == 0) {
1757 gen_nullptr_check(s1);
1760 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1761 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1762 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1763 emit_store(jd, iptr, iptr->dst, d);
1767 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1769 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1770 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1771 if (iptr->op1 == 0) {
1772 gen_nullptr_check(s1);
1775 M_AADD(s2, s1, REG_ITMP1);
1776 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1777 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1780 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1781 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1783 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1784 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1785 if (iptr->op1 == 0) {
1786 gen_nullptr_check(s1);
1789 M_AADD(s2, s1, REG_ITMP1);
1790 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1791 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1792 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1795 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1797 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1798 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1799 if (iptr->op1 == 0) {
1800 gen_nullptr_check(s1);
1803 M_ASLL_IMM(s2, 2, REG_ITMP2);
1804 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1805 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1806 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1809 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1811 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1812 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1813 if (iptr->op1 == 0) {
1814 gen_nullptr_check(s1);
1817 M_ASLL_IMM(s2, 3, REG_ITMP2);
1818 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1819 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1820 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1823 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1825 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1826 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1827 if (iptr->op1 == 0) {
1828 gen_nullptr_check(s1);
1831 M_ASLL_IMM(s2, 2, REG_ITMP2);
1832 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1833 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1834 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1837 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1839 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1840 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1841 if (iptr->op1 == 0) {
1842 gen_nullptr_check(s1);
1845 M_ASLL_IMM(s2, 3, REG_ITMP2);
1846 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1847 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1848 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1852 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1854 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1855 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1856 if (iptr->op1 == 0) {
1857 gen_nullptr_check(s1);
1860 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1862 M_MOV(s1, rd->argintregs[0]);
1863 M_MOV(s3, rd->argintregs[1]);
1864 disp = dseg_addaddress(cd, BUILTIN_canstore);
1865 M_ALD(REG_ITMP3, REG_PV, disp);
1866 M_JSR(REG_RA, REG_ITMP3);
1869 M_BEQZ(REG_RESULT, 0);
1870 codegen_add_arraystoreexception_ref(cd);
1873 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1874 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1875 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1876 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1877 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1878 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1882 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1884 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1886 if (iptr->op1 == 0) {
1887 gen_nullptr_check(s1);
1890 M_AADD(s2, s1, REG_ITMP1);
1891 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1894 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1895 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1897 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1898 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1899 if (iptr->op1 == 0) {
1900 gen_nullptr_check(s1);
1903 M_AADD(s2, s1, REG_ITMP1);
1904 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1905 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1908 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1910 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1911 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1912 if (iptr->op1 == 0) {
1913 gen_nullptr_check(s1);
1916 M_ASLL_IMM(s2, 2, REG_ITMP2);
1917 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1918 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1921 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1923 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1924 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1925 if (iptr->op1 == 0) {
1926 gen_nullptr_check(s1);
1929 M_ASLL_IMM(s2, 3, REG_ITMP2);
1930 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1931 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1934 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1936 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1937 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1938 if (iptr->op1 == 0) {
1939 gen_nullptr_check(s1);
1942 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1943 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1944 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1948 case ICMD_GETSTATIC: /* ... ==> ..., value */
1949 /* op1 = type, val.a = field address */
1951 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1952 disp = dseg_addaddress(cd, NULL);
1954 codegen_addpatchref(cd, PATCHER_get_putstatic,
1955 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1957 if (opt_showdisassemble) {
1962 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1964 disp = dseg_addaddress(cd, &(fi->value));
1966 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1967 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1969 if (opt_showdisassemble) {
1975 M_ALD(REG_ITMP1, REG_PV, disp);
1976 switch (iptr->op1) {
1978 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1979 M_ILD_INTERN(d, REG_ITMP1, 0);
1980 emit_store(jd, iptr, iptr->dst, d);
1983 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1984 M_LLD_INTERN(d, REG_ITMP1, 0);
1985 emit_store(jd, iptr, iptr->dst, d);
1988 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1989 M_ALD_INTERN(d, REG_ITMP1, 0);
1990 emit_store(jd, iptr, iptr->dst, d);
1993 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1994 M_FLD_INTERN(d, REG_ITMP1, 0);
1995 emit_store(jd, iptr, iptr->dst, d);
1998 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1999 M_DLD_INTERN(d, REG_ITMP1, 0);
2000 emit_store(jd, iptr, iptr->dst, d);
2005 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2006 /* op1 = type, val.a = field address */
2008 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2009 disp = dseg_addaddress(cd, NULL);
2011 codegen_addpatchref(cd, PATCHER_get_putstatic,
2012 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2014 if (opt_showdisassemble) {
2019 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2021 disp = dseg_addaddress(cd, &(fi->value));
2023 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2024 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2026 if (opt_showdisassemble) {
2032 M_ALD(REG_ITMP1, REG_PV, disp);
2033 switch (iptr->op1) {
2035 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2036 M_IST_INTERN(s2, REG_ITMP1, 0);
2039 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2040 M_LST_INTERN(s2, REG_ITMP1, 0);
2043 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2044 M_AST_INTERN(s2, REG_ITMP1, 0);
2047 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2048 M_FST_INTERN(s2, REG_ITMP1, 0);
2051 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2052 M_DST_INTERN(s2, REG_ITMP1, 0);
2057 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2058 /* val = value (in current instruction) */
2059 /* op1 = type, val.a = field address (in */
2060 /* following NOP) */
2062 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2063 disp = dseg_addaddress(cd, NULL);
2065 codegen_addpatchref(cd, PATCHER_get_putstatic,
2066 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2068 if (opt_showdisassemble) {
2073 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2075 disp = dseg_addaddress(cd, &(fi->value));
2077 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2078 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2080 if (opt_showdisassemble) {
2086 M_ALD(REG_ITMP1, REG_PV, disp);
2087 switch (iptr->op1) {
2089 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2092 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2095 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2098 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2101 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2107 case ICMD_GETFIELD: /* ... ==> ..., value */
2108 /* op1 = type, val.i = field offset */
2110 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2111 gen_nullptr_check(s1);
2113 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2114 codegen_addpatchref(cd, PATCHER_get_putfield,
2115 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2117 if (opt_showdisassemble) {
2124 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2127 switch (iptr->op1) {
2129 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2131 emit_store(jd, iptr, iptr->dst, d);
2134 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2136 emit_store(jd, iptr, iptr->dst, d);
2139 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2141 emit_store(jd, iptr, iptr->dst, d);
2144 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2146 emit_store(jd, iptr, iptr->dst, d);
2149 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2151 emit_store(jd, iptr, iptr->dst, d);
2156 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2157 /* op1 = type, val.a = field address */
2159 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2160 gen_nullptr_check(s1);
2162 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2163 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2165 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2168 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2169 codegen_addpatchref(cd, PATCHER_get_putfield,
2170 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2172 if (opt_showdisassemble) {
2179 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2182 switch (iptr->op1) {
2201 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2202 /* val = value (in current instruction) */
2203 /* op1 = type, val.a = field address (in */
2204 /* following NOP) */
2206 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2207 gen_nullptr_check(s1);
2209 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2210 codegen_addpatchref(cd, PATCHER_get_putfield,
2211 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2213 if (opt_showdisassemble) {
2220 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2223 switch (iptr[1].op1) {
2225 M_IST(REG_ZERO, s1, a);
2228 M_LST(REG_ZERO, s1, a);
2231 M_AST(REG_ZERO, s1, a);
2234 M_FST(REG_ZERO, s1, a);
2237 M_DST(REG_ZERO, s1, a);
2243 /* branch operations **************************************************/
2245 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2247 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2248 M_INTMOVE(s1, REG_ITMP1_XPTR);
2250 #ifdef ENABLE_VERIFIER
2252 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2253 (unresolved_class *) iptr->val.a, 0);
2255 if (opt_showdisassemble) {
2259 #endif /* ENABLE_VERIFIER */
2261 disp = dseg_addaddress(cd, asm_handle_exception);
2262 M_ALD(REG_ITMP2, REG_PV, disp);
2263 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2265 M_NOP; /* nop ensures that XPC is less than the end */
2266 /* of basic block */
2270 case ICMD_GOTO: /* ... ==> ... */
2271 /* op1 = target JavaVM pc */
2273 codegen_addreference(cd, (basicblock *) iptr->target);
2278 case ICMD_JSR: /* ... ==> ... */
2279 /* op1 = target JavaVM pc */
2281 dseg_addtarget(cd, (basicblock *) iptr->target);
2282 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2283 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2287 case ICMD_RET: /* ... ==> ... */
2288 /* op1 = local variable */
2289 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2290 if (var->flags & INMEMORY) {
2291 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2299 case ICMD_IFNULL: /* ..., value ==> ... */
2300 /* op1 = target JavaVM pc */
2302 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2304 codegen_addreference(cd, (basicblock *) iptr->target);
2308 case ICMD_IFNONNULL: /* ..., value ==> ... */
2309 /* op1 = target JavaVM pc */
2311 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2313 codegen_addreference(cd, (basicblock *) iptr->target);
2317 case ICMD_IFEQ: /* ..., value ==> ... */
2318 /* op1 = target JavaVM pc, val.i = constant */
2320 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2321 if (iptr->val.i == 0) {
2324 ICONST(REG_ITMP2, iptr->val.i);
2325 M_BEQ(s1, REG_ITMP2, 0);
2327 codegen_addreference(cd, (basicblock *) iptr->target);
2331 case ICMD_IFLT: /* ..., value ==> ... */
2332 /* op1 = target JavaVM pc, val.i = constant */
2334 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2335 if (iptr->val.i == 0) {
2338 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2339 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2341 ICONST(REG_ITMP2, iptr->val.i);
2342 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2344 M_BNEZ(REG_ITMP1, 0);
2346 codegen_addreference(cd, (basicblock *) iptr->target);
2350 case ICMD_IFLE: /* ..., value ==> ... */
2351 /* op1 = target JavaVM pc, val.i = constant */
2353 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2354 if (iptr->val.i == 0) {
2358 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2359 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2360 M_BNEZ(REG_ITMP1, 0);
2363 ICONST(REG_ITMP2, iptr->val.i);
2364 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2365 M_BEQZ(REG_ITMP1, 0);
2368 codegen_addreference(cd, (basicblock *) iptr->target);
2372 case ICMD_IFNE: /* ..., value ==> ... */
2373 /* op1 = target JavaVM pc, val.i = constant */
2375 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2376 if (iptr->val.i == 0) {
2380 ICONST(REG_ITMP2, iptr->val.i);
2381 M_BNE(s1, REG_ITMP2, 0);
2383 codegen_addreference(cd, (basicblock *) iptr->target);
2387 case ICMD_IFGT: /* ..., value ==> ... */
2388 /* op1 = target JavaVM pc, val.i = constant */
2390 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2391 if (iptr->val.i == 0) {
2395 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2396 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2397 M_BEQZ(REG_ITMP1, 0);
2400 ICONST(REG_ITMP2, iptr->val.i);
2401 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2402 M_BNEZ(REG_ITMP1, 0);
2405 codegen_addreference(cd, (basicblock *) iptr->target);
2409 case ICMD_IFGE: /* ..., value ==> ... */
2410 /* op1 = target JavaVM pc, val.i = constant */
2412 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2413 if (iptr->val.i == 0) {
2417 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2418 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2421 ICONST(REG_ITMP2, iptr->val.i);
2422 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2424 M_BEQZ(REG_ITMP1, 0);
2426 codegen_addreference(cd, (basicblock *) iptr->target);
2430 case ICMD_IF_LEQ: /* ..., value ==> ... */
2431 /* op1 = target JavaVM pc, val.l = constant */
2433 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2434 if (iptr->val.l == 0) {
2438 LCONST(REG_ITMP2, iptr->val.l);
2439 M_BEQ(s1, REG_ITMP2, 0);
2441 codegen_addreference(cd, (basicblock *) iptr->target);
2445 case ICMD_IF_LLT: /* ..., value ==> ... */
2446 /* op1 = target JavaVM pc, val.l = constant */
2448 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2449 if (iptr->val.l == 0) {
2453 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2454 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2457 LCONST(REG_ITMP2, iptr->val.l);
2458 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2460 M_BNEZ(REG_ITMP1, 0);
2462 codegen_addreference(cd, (basicblock *) iptr->target);
2466 case ICMD_IF_LLE: /* ..., value ==> ... */
2467 /* op1 = target JavaVM pc, val.l = constant */
2469 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2470 if (iptr->val.l == 0) {
2474 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2475 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2476 M_BNEZ(REG_ITMP1, 0);
2479 LCONST(REG_ITMP2, iptr->val.l);
2480 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2481 M_BEQZ(REG_ITMP1, 0);
2484 codegen_addreference(cd, (basicblock *) iptr->target);
2488 case ICMD_IF_LNE: /* ..., value ==> ... */
2489 /* op1 = target JavaVM pc, val.l = constant */
2491 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2492 if (iptr->val.l == 0) {
2496 LCONST(REG_ITMP2, iptr->val.l);
2497 M_BNE(s1, REG_ITMP2, 0);
2499 codegen_addreference(cd, (basicblock *) iptr->target);
2503 case ICMD_IF_LGT: /* ..., value ==> ... */
2504 /* op1 = target JavaVM pc, val.l = constant */
2506 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2507 if (iptr->val.l == 0) {
2511 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2512 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2513 M_BEQZ(REG_ITMP1, 0);
2516 LCONST(REG_ITMP2, iptr->val.l);
2517 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2518 M_BNEZ(REG_ITMP1, 0);
2521 codegen_addreference(cd, (basicblock *) iptr->target);
2525 case ICMD_IF_LGE: /* ..., value ==> ... */
2526 /* op1 = target JavaVM pc, val.l = constant */
2528 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2529 if (iptr->val.l == 0) {
2533 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2534 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2537 LCONST(REG_ITMP2, iptr->val.l);
2538 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2540 M_BEQZ(REG_ITMP1, 0);
2542 codegen_addreference(cd, (basicblock *) iptr->target);
2546 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2547 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2548 case ICMD_IF_ACMPEQ:
2550 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2551 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2553 codegen_addreference(cd, (basicblock *) iptr->target);
2557 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2558 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2559 case ICMD_IF_ACMPNE:
2561 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2562 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2564 codegen_addreference(cd, (basicblock *) iptr->target);
2568 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2569 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2571 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2572 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2573 M_CMPLT(s1, s2, REG_ITMP1);
2574 M_BNEZ(REG_ITMP1, 0);
2575 codegen_addreference(cd, (basicblock *) iptr->target);
2579 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2580 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2582 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2583 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2584 M_CMPGT(s1, s2, REG_ITMP1);
2585 M_BNEZ(REG_ITMP1, 0);
2586 codegen_addreference(cd, (basicblock *) iptr->target);
2590 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2591 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2593 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2594 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2595 M_CMPGT(s1, s2, REG_ITMP1);
2596 M_BEQZ(REG_ITMP1, 0);
2597 codegen_addreference(cd, (basicblock *) iptr->target);
2601 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2602 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2604 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2605 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2606 M_CMPLT(s1, s2, REG_ITMP1);
2607 M_BEQZ(REG_ITMP1, 0);
2608 codegen_addreference(cd, (basicblock *) iptr->target);
2612 #ifdef CONDITIONAL_LOADCONST
2613 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2615 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2618 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2619 /* val.i = constant */
2621 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2622 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2624 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2625 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2626 M_CMPEQ(s1, REG_ZERO, d);
2627 emit_store(jd, iptr, iptr->dst, d);
2630 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2631 M_CMPEQ(s1, REG_ZERO, d);
2633 emit_store(jd, iptr, iptr->dst, d);
2637 M_MOV(s1, REG_ITMP1);
2640 ICONST(d, iptr[1].val.i);
2642 if ((s3 >= 0) && (s3 <= 255)) {
2643 M_CMOVEQ_IMM(s1, s3, d);
2645 ICONST(REG_ITMP3, s3);
2646 M_CMOVEQ(s1, REG_ITMP3, d);
2648 emit_store(jd, iptr, iptr->dst, d);
2651 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2652 /* val.i = constant */
2654 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2655 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2657 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2658 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2659 M_CMPEQ(s1, REG_ZERO, d);
2660 emit_store(jd, iptr, iptr->dst, d);
2663 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2664 M_CMPEQ(s1, REG_ZERO, d);
2666 emit_store(jd, iptr, iptr->dst, d);
2670 M_MOV(s1, REG_ITMP1);
2673 ICONST(d, iptr[1].val.i);
2675 if ((s3 >= 0) && (s3 <= 255)) {
2676 M_CMOVNE_IMM(s1, s3, d);
2678 ICONST(REG_ITMP3, s3);
2679 M_CMOVNE(s1, REG_ITMP3, d);
2681 emit_store(jd, iptr, iptr->dst, d);
2684 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2685 /* val.i = constant */
2687 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2688 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2690 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2691 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2692 M_CMPLT(s1, REG_ZERO, d);
2693 emit_store(jd, iptr, iptr->dst, d);
2696 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2697 M_CMPLE(REG_ZERO, s1, d);
2698 emit_store(jd, iptr, iptr->dst, d);
2702 M_MOV(s1, REG_ITMP1);
2705 ICONST(d, iptr[1].val.i);
2707 if ((s3 >= 0) && (s3 <= 255)) {
2708 M_CMOVLT_IMM(s1, s3, d);
2710 ICONST(REG_ITMP3, s3);
2711 M_CMOVLT(s1, REG_ITMP3, d);
2713 emit_store(jd, iptr, iptr->dst, d);
2716 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2717 /* val.i = constant */
2719 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2720 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2722 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2723 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2724 M_CMPLE(REG_ZERO, s1, d);
2725 emit_store(jd, iptr, iptr->dst, d);
2728 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2729 M_CMPLT(s1, REG_ZERO, d);
2730 emit_store(jd, iptr, iptr->dst, d);
2734 M_MOV(s1, REG_ITMP1);
2737 ICONST(d, iptr[1].val.i);
2739 if ((s3 >= 0) && (s3 <= 255)) {
2740 M_CMOVGE_IMM(s1, s3, d);
2742 ICONST(REG_ITMP3, s3);
2743 M_CMOVGE(s1, REG_ITMP3, d);
2745 emit_store(jd, iptr, iptr->dst, d);
2748 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2749 /* val.i = constant */
2751 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2752 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2754 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2755 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2756 M_CMPLT(REG_ZERO, s1, d);
2757 emit_store(jd, iptr, iptr->dst, d);
2760 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2761 M_CMPLE(s1, REG_ZERO, d);
2762 emit_store(jd, iptr, iptr->dst, d);
2766 M_MOV(s1, REG_ITMP1);
2769 ICONST(d, iptr[1].val.i);
2771 if ((s3 >= 0) && (s3 <= 255)) {
2772 M_CMOVGT_IMM(s1, s3, d);
2774 ICONST(REG_ITMP3, s3);
2775 M_CMOVGT(s1, REG_ITMP3, d);
2777 emit_store(jd, iptr, iptr->dst, d);
2780 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2781 /* val.i = constant */
2783 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2784 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2786 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2787 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2788 M_CMPLE(s1, REG_ZERO, d);
2789 emit_store(jd, iptr, iptr->dst, d);
2792 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2793 M_CMPLT(REG_ZERO, s1, d);
2794 emit_store(jd, iptr, iptr->dst, d);
2798 M_MOV(s1, REG_ITMP1);
2801 ICONST(d, iptr[1].val.i);
2803 if ((s3 >= 0) && (s3 <= 255)) {
2804 M_CMOVLE_IMM(s1, s3, d);
2806 ICONST(REG_ITMP3, s3);
2807 M_CMOVLE(s1, REG_ITMP3, d);
2809 emit_store(jd, iptr, iptr->dst, d);
2814 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2817 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2818 M_INTMOVE(s1, REG_RESULT);
2819 goto nowperformreturn;
2821 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2823 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2824 M_INTMOVE(s1, REG_RESULT);
2826 #ifdef ENABLE_VERIFIER
2828 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2829 (unresolved_class *) iptr->val.a, 0);
2831 if (opt_showdisassemble) {
2835 #endif /* ENABLE_VERIFIER */
2836 goto nowperformreturn;
2838 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2840 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2841 M_FMOV(s1, REG_FRESULT);
2842 goto nowperformreturn;
2844 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2846 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2847 M_DMOV(s1, REG_FRESULT);
2848 goto nowperformreturn;
2850 case ICMD_RETURN: /* ... ==> ... */
2856 p = parentargs_base;
2858 /* call trace function */
2860 if (opt_verbosecall) {
2861 M_LDA(REG_SP, REG_SP, -3 * 8);
2862 M_LST(REG_RA, REG_SP, 0 * 8);
2863 M_LST(REG_RESULT, REG_SP, 1 * 8);
2864 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2866 disp = dseg_addaddress(cd, m);
2867 M_ALD(rd->argintregs[0], REG_PV, disp);
2868 M_MOV(REG_RESULT, rd->argintregs[1]);
2869 M_DMOV(REG_FRESULT, rd->argfltregs[2]);
2870 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2872 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2873 M_ALD(REG_ITMP3, REG_PV, disp);
2874 M_JSR(REG_RA, REG_ITMP3);
2877 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2878 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2879 M_LLD(REG_RA, REG_SP, 0 * 8);
2880 M_LDA(REG_SP, REG_SP, 3 * 8);
2883 #if defined(USE_THREADS)
2884 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2885 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2886 M_ALD(REG_ITMP3, REG_PV, disp);
2888 /* we need to save the proper return value */
2890 switch (iptr->opc) {
2894 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2895 M_JSR(REG_RA, REG_ITMP3);
2896 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2900 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2901 M_JSR(REG_RA, REG_ITMP3);
2902 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2905 M_JSR(REG_RA, REG_ITMP3);
2906 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2910 /* and now restore the proper return value */
2912 switch (iptr->opc) {
2916 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2920 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2926 /* restore return address */
2928 if (!m->isleafmethod) {
2929 p--; M_ALD(REG_RA, REG_SP, p * 8);
2932 /* restore saved registers */
2934 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2935 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2937 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2938 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2941 /* deallocate stack and return */
2943 if (parentargs_base) {
2946 disp = parentargs_base * 8;
2947 lo = (short) (disp);
2948 hi = (short) (((disp) - lo) >> 16);
2952 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2954 M_LUI(REG_ITMP3,hi);
2955 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2957 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2970 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2975 tptr = (void **) iptr->target;
2977 s4ptr = iptr->val.a;
2978 l = s4ptr[1]; /* low */
2979 i = s4ptr[2]; /* high */
2981 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2983 {M_INTMOVE(s1, REG_ITMP1);}
2984 else if (l <= 32768) {
2985 M_IADD_IMM(s1, -l, REG_ITMP1);
2988 ICONST(REG_ITMP2, l);
2989 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2995 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2996 M_BEQZ(REG_ITMP2, 0);
2997 codegen_addreference(cd, (basicblock *) tptr[0]);
2998 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
3000 /* build jump table top down and use address of lowest entry */
3002 /* s4ptr += 3 + i; */
3006 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3007 dseg_addtarget(cd, (basicblock *) tptr[0]);
3012 /* length of dataseg after last dseg_addtarget is used by load */
3014 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3015 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3022 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3024 s4 i, /*l, */val, *s4ptr;
3027 tptr = (void **) iptr->target;
3029 s4ptr = iptr->val.a;
3030 /*l = s4ptr[0];*/ /* default */
3031 i = s4ptr[1]; /* count */
3033 MCODECHECK((i<<2)+8);
3034 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3040 ICONST(REG_ITMP2, val);
3041 M_BEQ(s1, REG_ITMP2, 0);
3042 codegen_addreference(cd, (basicblock *) tptr[0]);
3047 tptr = (void **) iptr->target;
3048 codegen_addreference(cd, (basicblock *) tptr[0]);
3055 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3056 /* op1 = arg count val.a = builtintable entry */
3062 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3063 /* op1 = arg count, val.a = method pointer */
3065 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3066 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3067 case ICMD_INVOKEINTERFACE:
3069 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3070 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3074 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3075 md = lm->parseddesc;
3079 s3 = md->paramcount;
3081 MCODECHECK((s3 << 1) + 64);
3083 /* copy arguments to registers or stack location */
3085 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3086 if (src->varkind == ARGVAR)
3088 if (IS_INT_LNG_TYPE(src->type)) {
3089 if (!md->params[s3].inmemory) {
3090 s1 = rd->argintregs[md->params[s3].regoff];
3091 d = emit_load_s1(jd, iptr, src, s1);
3094 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3095 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3099 if (!md->params[s3].inmemory) {
3100 s1 = rd->argfltregs[md->params[s3].regoff];
3101 d = emit_load_s1(jd, iptr, src, s1);
3102 if (IS_2_WORD_TYPE(src->type))
3108 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3109 if (IS_2_WORD_TYPE(src->type))
3110 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3112 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3117 switch (iptr->opc) {
3119 disp = dseg_addaddress(cd, bte->fp);
3120 d = md->returntype.type;
3122 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3123 M_JSR(REG_RA, REG_ITMP3);
3125 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3126 M_LDA(REG_PV, REG_RA, -disp);
3128 /* if op1 == true, we need to check for an exception */
3130 if (iptr->op1 == true) {
3131 M_BEQZ(REG_RESULT, 0);
3132 codegen_add_fillinstacktrace_ref(cd);
3137 case ICMD_INVOKESPECIAL:
3138 M_BEQZ(rd->argintregs[0], 0);
3139 codegen_add_nullpointerexception_ref(cd);
3143 case ICMD_INVOKESTATIC:
3145 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3147 disp = dseg_addaddress(cd, NULL);
3149 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3152 if (opt_showdisassemble) {
3156 d = um->methodref->parseddesc.md->returntype.type;
3159 disp = dseg_addaddress(cd, lm->stubroutine);
3160 d = lm->parseddesc->returntype.type;
3163 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3164 M_JSR(REG_RA, REG_PV);
3166 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3167 M_LDA(REG_PV, REG_RA, -disp);
3170 case ICMD_INVOKEVIRTUAL:
3171 gen_nullptr_check(rd->argintregs[0]);
3174 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3176 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3178 if (opt_showdisassemble) {
3183 d = um->methodref->parseddesc.md->returntype.type;
3186 s1 = OFFSET(vftbl_t, table[0]) +
3187 sizeof(methodptr) * lm->vftblindex;
3188 d = lm->parseddesc->returntype.type;
3191 M_ALD(REG_METHODPTR, rd->argintregs[0],
3192 OFFSET(java_objectheader, vftbl));
3193 M_ALD(REG_PV, REG_METHODPTR, s1);
3194 M_JSR(REG_RA, REG_PV);
3196 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3197 M_LDA(REG_PV, REG_RA, -disp);
3200 case ICMD_INVOKEINTERFACE:
3201 gen_nullptr_check(rd->argintregs[0]);
3204 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3206 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3208 if (opt_showdisassemble) {
3214 d = um->methodref->parseddesc.md->returntype.type;
3217 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3218 sizeof(methodptr*) * lm->class->index;
3220 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3222 d = lm->parseddesc->returntype.type;
3225 M_ALD(REG_METHODPTR, rd->argintregs[0],
3226 OFFSET(java_objectheader, vftbl));
3227 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3228 M_ALD(REG_PV, REG_METHODPTR, s2);
3229 M_JSR(REG_RA, REG_PV);
3231 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3232 M_LDA(REG_PV, REG_RA, -disp);
3236 /* d contains return type */
3238 if (d != TYPE_VOID) {
3239 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3240 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3241 M_INTMOVE(REG_RESULT, s1);
3243 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3244 if (IS_2_WORD_TYPE(iptr->dst->type))
3245 M_DMOV(REG_FRESULT, s1);
3247 M_FMOV(REG_FRESULT, s1);
3249 emit_store(jd, iptr, iptr->dst, s1);
3254 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3255 /* op1: 0 == array, 1 == class */
3256 /* val.a: (classinfo*) superclass */
3258 /* superclass is an interface:
3260 * OK if ((sub == NULL) ||
3261 * (sub->vftbl->interfacetablelength > super->index) &&
3262 * (sub->vftbl->interfacetable[-super->index] != NULL));
3264 * superclass is a class:
3266 * OK if ((sub == NULL) || (0
3267 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3268 * super->vftbl->diffvall));
3271 if (iptr->op1 == 1) {
3273 vftbl_t *supervftbl;
3276 super = (classinfo *) iptr->val.a;
3283 superindex = super->index;
3284 supervftbl = super->vftbl;
3287 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3288 codegen_threadcritrestart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3291 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3293 /* calculate interface checkcast code size */
3297 s2 += (opt_showdisassemble ? 2 : 0);
3299 /* calculate class checkcast code size */
3301 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3303 s3 += (opt_showdisassemble ? 2 : 0);
3305 /* if class is not resolved, check which code to call */
3308 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3311 disp = dseg_adds4(cd, 0); /* super->flags */
3313 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3314 (constant_classref *) iptr->target,
3317 if (opt_showdisassemble) {
3321 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3322 M_ILD(REG_ITMP2, REG_PV, disp);
3323 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3324 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3328 /* interface checkcast code */
3330 if (!super || super->flags & ACC_INTERFACE) {
3336 codegen_addpatchref(cd,
3337 PATCHER_checkcast_instanceof_interface,
3338 (constant_classref *) iptr->target,
3341 if (opt_showdisassemble) {
3346 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3347 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3348 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3349 M_BLEZ(REG_ITMP3, 0);
3350 codegen_add_classcastexception_ref(cd);
3352 M_ALD(REG_ITMP3, REG_ITMP2,
3353 OFFSET(vftbl_t, interfacetable[0]) -
3354 superindex * sizeof(methodptr*));
3355 M_BEQZ(REG_ITMP3, 0);
3356 codegen_add_classcastexception_ref(cd);
3365 /* class checkcast code */
3367 if (!super || !(super->flags & ACC_INTERFACE)) {
3368 disp = dseg_addaddress(cd, (void *) supervftbl);
3375 codegen_addpatchref(cd,
3376 PATCHER_checkcast_instanceof_class,
3377 (constant_classref *) iptr->target,
3380 if (opt_showdisassemble) {
3385 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3386 M_ALD(REG_ITMP3, REG_PV, disp);
3387 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3388 codegen_threadcritstart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3390 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3391 /* if (s1 != REG_ITMP1) { */
3392 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3393 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3394 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3395 /* codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase); */
3397 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3399 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3400 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3401 M_ALD(REG_ITMP3, REG_PV, disp);
3402 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3403 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3404 codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3407 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3408 M_BNEZ(REG_ITMP3, 0);
3409 codegen_add_classcastexception_ref(cd);
3412 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3415 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3416 M_INTMOVE(s1, rd->argintregs[0]);
3418 disp = dseg_addaddress(cd, iptr->val.a);
3420 if (iptr->val.a == NULL) {
3421 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3422 (constant_classref *) iptr->target,
3425 if (opt_showdisassemble) {
3430 M_ALD(rd->argintregs[1], REG_PV, disp);
3431 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3432 M_ALD(REG_ITMP3, REG_PV, disp);
3433 M_JSR(REG_RA, REG_ITMP3);
3436 M_BEQZ(REG_RESULT, 0);
3437 codegen_add_classcastexception_ref(cd);
3440 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3441 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3444 emit_store(jd, iptr, iptr->dst, d);
3447 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3448 /* op1: 0 == array, 1 == class */
3449 /* val.a: (classinfo*) superclass */
3451 /* superclass is an interface:
3453 * return (sub != NULL) &&
3454 * (sub->vftbl->interfacetablelength > super->index) &&
3455 * (sub->vftbl->interfacetable[-super->index] != NULL);
3457 * superclass is a class:
3459 * return ((sub != NULL) && (0
3460 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3461 * super->vftbl->diffvall));
3466 vftbl_t *supervftbl;
3469 super = (classinfo *) iptr->val.a;
3476 superindex = super->index;
3477 supervftbl = super->vftbl;
3480 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3481 codegen_threadcritrestart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3484 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3485 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3487 M_MOV(s1, REG_ITMP1);
3491 /* calculate interface instanceof code size */
3495 s2 += (opt_showdisassemble ? 2 : 0);
3497 /* calculate class instanceof code size */
3501 s3 += (opt_showdisassemble ? 2 : 0);
3505 /* if class is not resolved, check which code to call */
3508 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3511 disp = dseg_adds4(cd, 0); /* super->flags */
3513 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3514 (constant_classref *) iptr->target, disp);
3516 if (opt_showdisassemble) {
3520 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3521 M_ILD(REG_ITMP3, REG_PV, disp);
3522 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3523 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3527 /* interface instanceof code */
3529 if (!super || (super->flags & ACC_INTERFACE)) {
3535 codegen_addpatchref(cd,
3536 PATCHER_checkcast_instanceof_interface,
3537 (constant_classref *) iptr->target, 0);
3539 if (opt_showdisassemble) {
3544 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3545 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3546 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3547 M_BLEZ(REG_ITMP3, 3);
3549 M_ALD(REG_ITMP1, REG_ITMP1,
3550 OFFSET(vftbl_t, interfacetable[0]) -
3551 superindex * sizeof(methodptr*));
3552 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3560 /* class instanceof code */
3562 if (!super || !(super->flags & ACC_INTERFACE)) {
3563 disp = dseg_addaddress(cd, supervftbl);
3570 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3571 (constant_classref *) iptr->target,
3574 if (opt_showdisassemble) {
3579 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3580 M_ALD(REG_ITMP2, REG_PV, disp);
3581 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3582 codegen_threadcritstart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3584 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3585 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3586 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3587 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3588 codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3590 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3591 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3594 emit_store(jd, iptr, iptr->dst, d);
3598 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3599 /* op1 = dimension, val.a = class */
3601 /* check for negative sizes and copy sizes to stack if necessary */
3603 MCODECHECK((iptr->op1 << 1) + 64);
3605 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3606 /* copy SAVEDVAR sizes to stack */
3608 if (src->varkind != ARGVAR) {
3609 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3610 M_LST(s2, REG_SP, s1 * 8);
3614 /* a0 = dimension count */
3616 ICONST(rd->argintregs[0], iptr->op1);
3618 /* is patcher function set? */
3620 if (iptr->val.a == NULL) {
3621 disp = dseg_addaddress(cd, NULL);
3623 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3624 (constant_classref *) iptr->target, disp);
3626 if (opt_showdisassemble) {
3631 disp = dseg_addaddress(cd, iptr->val.a);
3634 /* a1 = arraydescriptor */
3636 M_ALD(rd->argintregs[1], REG_PV, disp);
3638 /* a2 = pointer to dimensions = stack pointer */
3640 M_INTMOVE(REG_SP, rd->argintregs[2]);
3642 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3643 M_ALD(REG_ITMP3, REG_PV, disp);
3644 M_JSR(REG_RA, REG_ITMP3);
3647 /* check for exception before result assignment */
3649 M_BEQZ(REG_RESULT, 0);
3650 codegen_add_fillinstacktrace_ref(cd);
3653 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3654 M_INTMOVE(REG_RESULT, d);
3655 emit_store(jd, iptr, iptr->dst, d);
3659 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3663 } /* for instruction */
3665 /* copy values to interface registers */
3667 src = bptr->outstack;
3668 len = bptr->outdepth;
3670 #if defined(ENABLE_LSRA)
3675 if ((src->varkind != STACKVAR)) {
3677 if (IS_FLT_DBL_TYPE(s2)) {
3678 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3679 if (rd->interfaces[len][s2].flags & INMEMORY) {
3680 if (IS_2_WORD_TYPE(s2))
3681 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3683 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3686 if (IS_2_WORD_TYPE(s2))
3687 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3689 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3693 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3694 if (rd->interfaces[len][s2].flags & INMEMORY)
3695 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3697 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3703 /* At the end of a basic block we may have to append some nops,
3704 because the patcher stub calling code might be longer than the
3705 actual instruction. So codepatching does not change the
3706 following block unintentionally. */
3708 if ((u1 *) cd->mcodeptr < cd->lastmcodeptr) {
3709 while ((u1 *) 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((u1 *) cd->mcodebase + eref->branchpos,
3736 (u1 *) cd->mcodeptr - cd->mcodebase);
3740 /* Check if the exception is an
3741 ArrayIndexOutOfBoundsException. If so, move index register
3744 if (eref->reg != -1)
3745 M_MOV(eref->reg, REG_ITMP1);
3747 /* calcuate exception address */
3749 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3751 /* move function to call into REG_ITMP3 */
3753 disp = dseg_addaddress(cd, eref->function);
3754 M_ALD(REG_ITMP3, REG_PV, disp);
3756 if (savedmcodeptr != NULL) {
3757 M_BR(savedmcodeptr - cd->mcodeptr);
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 = (u4 *) (cd->mcodebase + pref->branchpos);
3811 /* We need to split this, because an unaligned 8 byte read
3812 causes a SIGSEGV. */
3814 mcode = ((u8) tmpmcodeptr[1] << 32) + (u4) tmpmcodeptr[0];
3816 /* Patch in the call to call the following code (done at
3819 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3820 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3822 disp = (s4) (savedmcodeptr - (tmpmcodeptr + 1));
3824 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3826 new_internalerror("Jump offset is out of range: %d > +/-%d",
3834 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3836 /* create stack frame */
3838 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3840 /* calculate return address and move it onto the stack */
3842 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3843 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3845 /* move pointer to java_objectheader onto stack */
3847 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3848 /* create a virtual java_objectheader */
3850 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3851 disp = dseg_addaddress(cd, NULL); /* vftbl */
3853 M_LDA(REG_ITMP3, REG_PV, disp);
3854 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3859 /* move machine code onto stack */
3861 disp = dseg_adds8(cd, mcode);
3862 M_LLD(REG_ITMP3, REG_PV, disp);
3863 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3865 /* move class/method/field reference onto stack */
3867 disp = dseg_addaddress(cd, pref->ref);
3868 M_ALD(REG_ITMP3, REG_PV, disp);
3869 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3871 /* move data segment displacement onto stack */
3873 disp = dseg_adds4(cd, pref->disp);
3874 M_ILD(REG_ITMP3, REG_PV, disp);
3875 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3877 /* move patcher function pointer onto stack */
3879 disp = dseg_addaddress(cd, pref->patcher);
3880 M_ALD(REG_ITMP3, REG_PV, disp);
3881 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3883 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3884 M_ALD(REG_ITMP3, REG_PV, disp);
3889 /* generate replacement-out stubs */
3894 replacementpoint = jd->code->rplpoints;
3896 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3897 /* check code segment size */
3901 /* note start of stub code */
3903 replacementpoint->outcode = (u1*) (ptrint)((u1*)cd->mcodeptr - cd->mcodebase);
3905 /* make machine code for patching */
3907 tmpmcodeptr = cd->mcodeptr;
3908 cd->mcodeptr = (u4 *) &(replacementpoint->mcode);
3910 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3911 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3913 new_internalerror("Jump offset is out of range: %d > +/-%d",
3918 M_NOP; /* delay slot */
3920 cd->mcodeptr = tmpmcodeptr;
3922 /* create stack frame - 16-byte aligned */
3924 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3926 /* push address of `rplpoint` struct */
3928 disp = dseg_addaddress(cd, replacementpoint);
3929 M_ALD(REG_ITMP3, REG_PV, disp);
3930 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3932 /* jump to replacement function */
3934 disp = dseg_addaddress(cd, asm_replacement_out);
3935 M_ALD(REG_ITMP3, REG_PV, disp);
3937 M_NOP; /* delay slot */
3944 /* everything's ok */
3950 /* createcompilerstub **********************************************************
3952 Creates a stub routine which calls the compiler.
3954 *******************************************************************************/
3956 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3957 #define COMPILERSTUB_CODESIZE 4 * 4
3959 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3962 u1 *createcompilerstub(methodinfo *m)
3964 u1 *s; /* memory to hold the stub */
3969 s = CNEW(u1, COMPILERSTUB_SIZE);
3971 /* set data pointer and code pointer */
3974 s = s + COMPILERSTUB_DATASIZE;
3976 /* mark start of dump memory area */
3978 dumpsize = dump_size();
3980 cd = DNEW(codegendata);
3981 cd->mcodeptr = (u4 *) s;
3983 /* Store the methodinfo* in the same place as in the methodheader
3984 for compiled methods. */
3986 d[0] = (ptrint) asm_call_jit_compiler;
3989 M_ALD_INTERN(REG_ITMP1, REG_PV, -1 * SIZEOF_VOID_P); /* method pointer */
3990 M_ALD_INTERN(REG_PV, REG_PV, -2 * SIZEOF_VOID_P); /* pointer to compiler */
3994 md_cacheflush(s, (s4) ((u1 *) cd->mcodeptr - s));
3996 #if defined(ENABLE_STATISTICS)
3998 count_cstub_len += COMPILERSTUB_SIZE;
4001 /* release dump area */
4003 dump_release(dumpsize);
4009 /* createnativestub ************************************************************
4011 Creates a stub routine which calls a native method.
4013 *******************************************************************************/
4015 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4020 s4 stackframesize; /* size of stackframe if needed */
4023 s4 i, j; /* count variables */
4026 s4 funcdisp; /* displacement of the function */
4028 /* get required compiler data */
4034 /* initialize variables */
4037 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4039 /* calculate stack frame size */
4042 1 + /* return address */
4043 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4044 sizeof(localref_table) / SIZEOF_VOID_P +
4045 md->paramcount + /* for saving arguments over calls */
4046 1 + /* for saving return address */
4049 /* create method header */
4051 #if SIZEOF_VOID_P == 4
4052 (void) dseg_addaddress(cd, m); /* MethodPointer */
4054 (void) dseg_addaddress(cd, m); /* MethodPointer */
4055 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4056 (void) dseg_adds4(cd, 0); /* IsSync */
4057 (void) dseg_adds4(cd, 0); /* IsLeaf */
4058 (void) dseg_adds4(cd, 0); /* IntSave */
4059 (void) dseg_adds4(cd, 0); /* FltSave */
4060 (void) dseg_addlinenumbertablesize(cd);
4061 (void) dseg_adds4(cd, 0); /* ExTableSize */
4063 /* generate stub code */
4065 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
4066 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
4068 /* call trace function */
4070 if (opt_verbosecall) {
4071 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4073 /* save integer argument registers */
4075 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4076 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4077 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4079 /* save and copy float arguments into integer registers */
4081 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4082 t = md->paramtypes[i].type;
4084 if (IS_FLT_DBL_TYPE(t)) {
4085 if (IS_2_WORD_TYPE(t)) {
4086 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4087 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4089 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4090 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4095 disp = dseg_addaddress(cd, m);
4096 M_ALD(REG_ITMP1, REG_PV, disp);
4097 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4098 disp = dseg_addaddress(cd, builtin_trace_args);
4099 M_ALD(REG_ITMP3, REG_PV, disp);
4100 M_JSR(REG_RA, REG_ITMP3);
4103 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4104 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4105 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4107 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4108 t = md->paramtypes[i].type;
4110 if (IS_FLT_DBL_TYPE(t)) {
4111 if (IS_2_WORD_TYPE(t))
4112 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4114 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4118 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4121 /* get function address (this must happen before the stackframeinfo) */
4123 funcdisp = dseg_addaddress(cd, f);
4125 #if !defined(WITH_STATIC_CLASSPATH)
4127 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4129 if (opt_showdisassemble) {
4135 /* save integer and float argument registers */
4137 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4138 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4139 M_LST(rd->argintregs[i], REG_SP, j * 8);
4144 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4145 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4146 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4151 /* prepare data structures for native function call */
4153 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4154 M_MOV(REG_PV, rd->argintregs[1]);
4155 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4156 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4157 disp = dseg_addaddress(cd, codegen_start_native_call);
4158 M_ALD(REG_ITMP3, REG_PV, disp);
4159 M_JSR(REG_RA, REG_ITMP3);
4160 M_NOP; /* XXX fill me! */
4162 /* restore integer and float argument registers */
4164 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4165 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4166 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4171 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4172 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4173 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4178 /* copy or spill arguments to new locations */
4180 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4181 t = md->paramtypes[i].type;
4183 if (IS_INT_LNG_TYPE(t)) {
4184 if (!md->params[i].inmemory) {
4185 s1 = rd->argintregs[md->params[i].regoff];
4187 if (!nmd->params[j].inmemory) {
4188 s2 = rd->argintregs[nmd->params[j].regoff];
4191 s2 = nmd->params[j].regoff;
4192 M_AST(s1, REG_SP, s2 * 8);
4196 s1 = md->params[i].regoff + stackframesize;
4197 s2 = nmd->params[j].regoff;
4198 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4199 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4203 if (!md->params[i].inmemory) {
4204 s1 = rd->argfltregs[md->params[i].regoff];
4206 if (!nmd->params[j].inmemory) {
4207 s2 = rd->argfltregs[nmd->params[j].regoff];
4208 if (IS_2_WORD_TYPE(t))
4214 s2 = nmd->params[j].regoff;
4215 if (IS_2_WORD_TYPE(t))
4216 M_DST(s1, REG_SP, s2 * 8);
4218 M_FST(s1, REG_SP, s2 * 8);
4222 s1 = md->params[i].regoff + stackframesize;
4223 s2 = nmd->params[j].regoff;
4224 if (IS_2_WORD_TYPE(t)) {
4225 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4226 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4228 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4229 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4235 /* put class into second argument register */
4237 if (m->flags & ACC_STATIC) {
4238 disp = dseg_addaddress(cd, m->class);
4239 M_ALD(rd->argintregs[1], REG_PV, disp);
4242 /* put env into first argument register */
4244 disp = dseg_addaddress(cd, _Jv_env);
4245 M_ALD(rd->argintregs[0], REG_PV, disp);
4247 /* do the native function call */
4249 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4250 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4251 M_NOP; /* delay slot */
4253 /* save return value */
4255 if (IS_INT_LNG_TYPE(md->returntype.type))
4256 M_LST(REG_RESULT, REG_SP, 0 * 8);
4258 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4260 /* remove native stackframe info */
4262 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4263 disp = dseg_addaddress(cd, codegen_finish_native_call);
4264 M_ALD(REG_ITMP3, REG_PV, disp);
4265 M_JSR(REG_RA, REG_ITMP3);
4266 M_NOP; /* XXX fill me! */
4268 /* call finished trace function */
4270 if (opt_verbosecall) {
4271 if (IS_INT_LNG_TYPE(md->returntype.type))
4272 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4274 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4276 disp = dseg_addaddress(cd, m);
4277 M_ALD(rd->argintregs[0], REG_PV, disp);
4279 M_MOV(REG_RESULT, rd->argintregs[1]);
4280 M_DMFC1(REG_ITMP1, REG_FRESULT);
4281 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4282 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4284 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4285 M_ALD(REG_ITMP3, REG_PV, disp);
4286 M_JSR(REG_RA, REG_ITMP3);
4290 /* check for exception */
4292 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4293 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4294 M_ALD(REG_ITMP3, REG_PV, disp);
4295 M_JSR(REG_RA, REG_ITMP3);
4297 M_MOV(REG_RESULT, REG_ITMP3);
4299 disp = dseg_addaddress(cd, &_exceptionptr);
4300 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4302 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4304 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4306 /* restore return value */
4308 if (IS_INT_LNG_TYPE(md->returntype.type))
4309 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4311 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4313 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4314 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4316 M_RET(REG_RA); /* return to caller */
4317 M_NOP; /* DELAY SLOT */
4319 /* handle exception */
4321 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4323 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4324 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4325 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4326 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4329 /* generate static stub call code */
4337 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4338 /* Get machine code which is patched back in later. The
4339 call is 2 instruction words long. */
4341 tmpmcodeptr = (u4 *) (cd->mcodebase + pref->branchpos);
4343 /* We need to split this, because an unaligned 8 byte read
4344 causes a SIGSEGV. */
4346 mcode = ((u8) tmpmcodeptr[1] << 32) + (u4) tmpmcodeptr[0];
4348 /* Patch in the call to call the following code (done at
4351 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4352 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4354 M_BRS(savedmcodeptr - (tmpmcodeptr + 1));
4355 M_NOP; /* branch delay slot */
4357 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4359 /* create stack frame */
4361 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4363 /* move return address onto stack */
4365 M_AST(REG_RA, REG_SP, 5 * 8);
4367 /* move pointer to java_objectheader onto stack */
4369 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4370 /* order reversed because of data segment layout */
4372 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4373 disp = dseg_addaddress(cd, NULL); /* vftbl */
4375 M_LDA(REG_ITMP3, REG_PV, disp);
4376 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4378 M_AST(REG_ZERO, REG_SP, 4 * 8);
4381 /* move machine code onto stack */
4383 disp = dseg_adds8(cd, mcode);
4384 M_LLD(REG_ITMP3, REG_PV, disp);
4385 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4387 /* move class/method/field reference onto stack */
4389 disp = dseg_addaddress(cd, pref->ref);
4390 M_ALD(REG_ITMP3, REG_PV, disp);
4391 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4393 /* move data segment displacement onto stack */
4395 disp = dseg_adds4(cd, pref->disp);
4396 M_ILD(REG_ITMP3, REG_PV, disp);
4397 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4399 /* move patcher function pointer onto stack */
4401 disp = dseg_addaddress(cd, pref->patcher);
4402 M_ALD(REG_ITMP3, REG_PV, disp);
4403 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4405 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4406 M_ALD(REG_ITMP3, REG_PV, disp);
4414 return jd->code->entrypoint;
4419 * These are local overrides for various environment variables in Emacs.
4420 * Please do not remove this and leave it at the end of the file, where
4421 * Emacs will automagically detect them.
4422 * ---------------------------------------------------------------------
4425 * indent-tabs-mode: t
4429 * vim:noexpandtab:sw=4:ts=4: