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 4744 2006-04-06 12:51:53Z 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/jit.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/reg.h"
69 #include "vm/jit/replace.h"
71 #if defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
76 /* codegen *********************************************************************
78 Generates machine code.
80 *******************************************************************************/
82 bool codegen(jitdata *jd)
87 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 /* initialize mcode variables */
169 mcodeptr = (s4 *) cd->mcodeptr;
171 /* initialize the last patcher pointer */
173 cd->lastmcodeptr = (u1 *) mcodeptr;
175 /* create stack frame (if necessary) */
178 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
180 /* save return address and used callee saved registers */
183 if (!m->isleafmethod) {
184 p--; M_AST(REG_RA, REG_SP, p * 8);
186 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
187 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
189 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
193 /* take arguments out of register or stack frame */
197 for (p = 0, l = 0; p < md->paramcount; p++) {
198 t = md->paramtypes[p].type;
199 var = &(rd->locals[l][t]);
201 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
205 s1 = md->params[p].regoff;
206 if (IS_INT_LNG_TYPE(t)) { /* integer args */
207 if (!md->params[p].inmemory) { /* register arguments */
208 s2 = rd->argintregs[s1];
209 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
210 M_INTMOVE(s2, var->regoff);
211 } else { /* reg arg -> spilled */
212 M_LST(s2, REG_SP, var->regoff * 8);
215 } else { /* stack arguments */
216 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
217 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
218 } else { /* stack arg -> spilled */
219 var->regoff = parentargs_base + s1;
223 } else { /* floating args */
224 if (!md->params[p].inmemory) { /* register arguments */
225 s2 = rd->argfltregs[s1];
226 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
227 M_TFLTMOVE(var->type, s2, var->regoff);
228 } else { /* reg arg -> spilled */
229 M_DST(s2, REG_SP, var->regoff * 8);
232 } else { /* stack arguments */
233 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
234 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
235 } else { /* stack-arg -> spilled */
236 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, mcodeptr);
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)mcodeptr & 4) {
400 replacementpoint->pc = (u1*)(ptrint)((u1*)mcodeptr - cd->mcodebase);
403 assert(cd->lastmcodeptr <= (u1*)mcodeptr);
404 cd->lastmcodeptr = (u1*)cd->mcodeptr + 2*4; /* br + delay slot */
407 /* store relative start of block */
409 bptr->mpc = (s4) ((u1 *) 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 store_reg_to_var_int(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 store_reg_to_var_int(src, d);
453 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
454 if ((src->varkind != STACKVAR)) {
456 if (IS_FLT_DBL_TYPE(s2)) {
457 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
458 s1 = rd->interfaces[len][s2].regoff;
459 M_TFLTMOVE(s2, s1, d);
462 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
464 store_reg_to_var_flt(src, d);
467 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
468 s1 = rd->interfaces[len][s2].regoff;
472 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
474 store_reg_to_var_int(src, d);
480 #if defined(ENABLE_LSRA)
483 /* walk through all instructions */
489 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
490 if (iptr->line != currentline) {
491 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
492 currentline = iptr->line;
495 MCODECHECK(64); /* an instruction usually needs < 64 words */
499 case ICMD_NOP: /* ... ==> ... */
502 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
504 var_to_reg_int(s1, src, REG_ITMP1);
506 codegen_add_nullpointerexception_ref(cd, mcodeptr);
510 /* constant operations ************************************************/
512 case ICMD_ICONST: /* ... ==> ..., constant */
513 /* op1 = 0, val.i = constant */
515 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
516 ICONST(d, iptr->val.i);
517 store_reg_to_var_int(iptr->dst, d);
520 case ICMD_LCONST: /* ... ==> ..., constant */
521 /* op1 = 0, val.l = constant */
523 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
524 LCONST(d, iptr->val.l);
525 store_reg_to_var_int(iptr->dst, d);
528 case ICMD_FCONST: /* ... ==> ..., constant */
529 /* op1 = 0, val.f = constant */
531 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
532 disp = dseg_addfloat(cd, iptr->val.f);
533 M_FLD(d, REG_PV, disp);
534 store_reg_to_var_flt(iptr->dst, d);
537 case ICMD_DCONST: /* ... ==> ..., constant */
538 /* op1 = 0, val.d = constant */
540 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
541 disp = dseg_adddouble(cd, iptr->val.d);
542 M_DLD(d, REG_PV, disp);
543 store_reg_to_var_flt (iptr->dst, d);
546 case ICMD_ACONST: /* ... ==> ..., constant */
547 /* op1 = 0, val.a = constant */
549 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
551 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
552 disp = dseg_addaddress(cd, iptr->val.a);
554 codegen_addpatchref(cd, mcodeptr,
556 (unresolved_class *) iptr->target, disp);
558 if (opt_showdisassemble) {
562 M_ALD(d, REG_PV, disp);
565 if (iptr->val.a == NULL) {
566 M_INTMOVE(REG_ZERO, d);
568 disp = dseg_addaddress(cd, iptr->val.a);
569 M_ALD(d, REG_PV, disp);
572 store_reg_to_var_int(iptr->dst, d);
576 /* load/store operations **********************************************/
578 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
579 case ICMD_LLOAD: /* op1 = local variable */
582 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
583 if ((iptr->dst->varkind == LOCALVAR) &&
584 (iptr->dst->varnum == iptr->op1))
586 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
587 if (var->flags & INMEMORY) {
588 M_LLD(d, REG_SP, 8 * var->regoff);
590 M_INTMOVE(var->regoff,d);
592 store_reg_to_var_int(iptr->dst, d);
595 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
596 case ICMD_DLOAD: /* op1 = local variable */
598 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
599 if ((iptr->dst->varkind == LOCALVAR) &&
600 (iptr->dst->varnum == iptr->op1))
602 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
604 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
605 if (var->flags & INMEMORY) {
606 M_CCFLD(var->type, t2, d, REG_SP, 8 * var->regoff);
608 M_CCFLTMOVE(var->type, t2, var->regoff, d);
611 store_reg_to_var_flt(iptr->dst, d);
615 case ICMD_ISTORE: /* ..., value ==> ... */
616 case ICMD_LSTORE: /* op1 = local variable */
619 if ((src->varkind == LOCALVAR) &&
620 (src->varnum == iptr->op1))
622 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
623 if (var->flags & INMEMORY) {
624 var_to_reg_int(s1, src, REG_ITMP1);
625 M_LST(s1, REG_SP, 8 * var->regoff);
628 var_to_reg_int(s1, src, var->regoff);
629 M_INTMOVE(s1, var->regoff);
633 case ICMD_FSTORE: /* ..., value ==> ... */
634 case ICMD_DSTORE: /* op1 = local variable */
636 if ((src->varkind == LOCALVAR) &&
637 (src->varnum == iptr->op1))
639 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
641 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
642 if (var->flags & INMEMORY) {
643 var_to_reg_flt(s1, src, REG_FTMP1);
644 M_CCFST(t1, var->type, s1, REG_SP, 8 * var->regoff);
647 var_to_reg_flt(s1, src, var->regoff);
648 M_CCFLTMOVE(t1, var->type, s1, var->regoff);
654 /* pop/dup/swap operations ********************************************/
656 /* attention: double and longs are only one entry in CACAO ICMDs */
658 case ICMD_POP: /* ..., value ==> ... */
659 case ICMD_POP2: /* ..., value, value ==> ... */
662 case ICMD_DUP: /* ..., a ==> ..., a, a */
663 M_COPY(src, iptr->dst);
666 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
668 M_COPY(src, iptr->dst);
669 M_COPY(src->prev, iptr->dst->prev);
670 M_COPY(iptr->dst, iptr->dst->prev->prev);
673 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
675 M_COPY(src, iptr->dst);
676 M_COPY(src->prev, iptr->dst->prev);
677 M_COPY(src->prev->prev, iptr->dst->prev->prev);
678 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
681 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
683 M_COPY(src, iptr->dst);
684 M_COPY(src->prev, iptr->dst->prev);
687 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
689 M_COPY(src, iptr->dst);
690 M_COPY(src->prev, iptr->dst->prev);
691 M_COPY(src->prev->prev, iptr->dst->prev->prev);
692 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
693 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
696 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
698 M_COPY(src, iptr->dst);
699 M_COPY(src->prev, iptr->dst->prev);
700 M_COPY(src->prev->prev, iptr->dst->prev->prev);
701 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
702 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
703 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
706 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
708 M_COPY(src, iptr->dst->prev);
709 M_COPY(src->prev, iptr->dst);
713 /* integer operations *************************************************/
715 case ICMD_INEG: /* ..., value ==> ..., - value */
717 var_to_reg_int(s1, src, REG_ITMP1);
718 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
719 M_ISUB(REG_ZERO, s1, d);
720 store_reg_to_var_int(iptr->dst, d);
723 case ICMD_LNEG: /* ..., value ==> ..., - value */
725 var_to_reg_int(s1, src, REG_ITMP1);
726 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
727 M_LSUB(REG_ZERO, s1, d);
728 store_reg_to_var_int(iptr->dst, d);
731 case ICMD_I2L: /* ..., value ==> ..., value */
733 var_to_reg_int(s1, src, REG_ITMP1);
734 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
736 store_reg_to_var_int(iptr->dst, d);
739 case ICMD_L2I: /* ..., value ==> ..., value */
741 var_to_reg_int(s1, src, REG_ITMP1);
742 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
743 M_ISLL_IMM(s1, 0, d );
744 store_reg_to_var_int(iptr->dst, d);
747 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
749 var_to_reg_int(s1, src, REG_ITMP1);
750 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
751 M_LSLL_IMM(s1, 56, d);
752 M_LSRA_IMM( d, 56, d);
753 store_reg_to_var_int(iptr->dst, d);
756 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
758 var_to_reg_int(s1, src, REG_ITMP1);
759 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
761 store_reg_to_var_int(iptr->dst, d);
764 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
766 var_to_reg_int(s1, src, REG_ITMP1);
767 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
768 M_LSLL_IMM(s1, 48, d);
769 M_LSRA_IMM( d, 48, d);
770 store_reg_to_var_int(iptr->dst, d);
774 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
776 var_to_reg_int(s1, src->prev, REG_ITMP1);
777 var_to_reg_int(s2, src, REG_ITMP2);
778 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
780 store_reg_to_var_int(iptr->dst, d);
783 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
784 /* val.i = constant */
786 var_to_reg_int(s1, src, REG_ITMP1);
787 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
788 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
789 M_IADD_IMM(s1, iptr->val.i, d);
791 ICONST(REG_ITMP2, iptr->val.i);
792 M_IADD(s1, REG_ITMP2, d);
794 store_reg_to_var_int(iptr->dst, d);
797 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
799 var_to_reg_int(s1, src->prev, REG_ITMP1);
800 var_to_reg_int(s2, src, REG_ITMP2);
801 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
803 store_reg_to_var_int(iptr->dst, d);
806 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
807 /* val.l = constant */
809 var_to_reg_int(s1, src, REG_ITMP1);
810 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
811 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
812 M_LADD_IMM(s1, iptr->val.l, d);
814 LCONST(REG_ITMP2, iptr->val.l);
815 M_LADD(s1, REG_ITMP2, d);
817 store_reg_to_var_int(iptr->dst, d);
820 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
822 var_to_reg_int(s1, src->prev, REG_ITMP1);
823 var_to_reg_int(s2, src, REG_ITMP2);
824 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
826 store_reg_to_var_int(iptr->dst, d);
829 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
830 /* val.i = constant */
832 var_to_reg_int(s1, src, REG_ITMP1);
833 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
834 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
835 M_IADD_IMM(s1, -iptr->val.i, d);
837 ICONST(REG_ITMP2, iptr->val.i);
838 M_ISUB(s1, REG_ITMP2, d);
840 store_reg_to_var_int(iptr->dst, d);
843 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
845 var_to_reg_int(s1, src->prev, REG_ITMP1);
846 var_to_reg_int(s2, src, REG_ITMP2);
847 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
849 store_reg_to_var_int(iptr->dst, d);
852 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
853 /* val.l = constant */
855 var_to_reg_int(s1, src, REG_ITMP1);
856 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
857 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
858 M_LADD_IMM(s1, -iptr->val.l, d);
860 LCONST(REG_ITMP2, iptr->val.l);
861 M_LSUB(s1, REG_ITMP2, d);
863 store_reg_to_var_int(iptr->dst, d);
866 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
868 var_to_reg_int(s1, src->prev, REG_ITMP1);
869 var_to_reg_int(s2, src, REG_ITMP2);
870 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
875 store_reg_to_var_int(iptr->dst, d);
878 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
879 /* val.i = constant */
881 var_to_reg_int(s1, src, REG_ITMP1);
882 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
883 ICONST(REG_ITMP2, iptr->val.i);
884 M_IMUL(s1, REG_ITMP2);
888 store_reg_to_var_int(iptr->dst, d);
891 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
893 var_to_reg_int(s1, src->prev, REG_ITMP1);
894 var_to_reg_int(s2, src, REG_ITMP2);
895 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
900 store_reg_to_var_int(iptr->dst, d);
903 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
904 /* val.l = constant */
906 var_to_reg_int(s1, src, REG_ITMP1);
907 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
908 LCONST(REG_ITMP2, iptr->val.l);
909 M_LMUL(s1, REG_ITMP2);
913 store_reg_to_var_int(iptr->dst, d);
916 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
918 var_to_reg_int(s1, src->prev, REG_ITMP1);
919 var_to_reg_int(s2, src, REG_ITMP2);
920 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
926 store_reg_to_var_int(iptr->dst, d);
929 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
931 var_to_reg_int(s1, src->prev, REG_ITMP1);
932 var_to_reg_int(s2, src, REG_ITMP2);
933 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
939 store_reg_to_var_int(iptr->dst, d);
942 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
944 var_to_reg_int(s1, src->prev, REG_ITMP1);
945 var_to_reg_int(s2, src, REG_ITMP2);
946 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
952 store_reg_to_var_int(iptr->dst, d);
955 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
957 var_to_reg_int(s1, src->prev, REG_ITMP1);
958 var_to_reg_int(s2, src, REG_ITMP2);
959 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
965 store_reg_to_var_int(iptr->dst, d);
968 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
969 case ICMD_LDIVPOW2: /* val.i = constant */
971 var_to_reg_int(s1, src, REG_ITMP1);
972 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
973 M_LSRA_IMM(s1, 63, REG_ITMP2);
974 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
975 M_LADD(s1, REG_ITMP2, REG_ITMP2);
976 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
977 store_reg_to_var_int(iptr->dst, d);
980 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
982 var_to_reg_int(s1, src->prev, REG_ITMP1);
983 var_to_reg_int(s2, src, REG_ITMP2);
984 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
990 /* val.i = constant */
992 var_to_reg_int(s1, src, REG_ITMP1);
993 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
994 M_ISLL_IMM(s1, iptr->val.i, d);
995 store_reg_to_var_int(iptr->dst, d);
998 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1000 var_to_reg_int(s1, src->prev, REG_ITMP1);
1001 var_to_reg_int(s2, src, REG_ITMP2);
1002 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1004 store_reg_to_var_int(iptr->dst, d);
1007 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1008 /* val.i = constant */
1010 var_to_reg_int(s1, src, REG_ITMP1);
1011 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1012 M_ISRA_IMM(s1, iptr->val.i, d);
1013 store_reg_to_var_int(iptr->dst, d);
1016 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1018 var_to_reg_int(s1, src->prev, REG_ITMP1);
1019 var_to_reg_int(s2, src, REG_ITMP2);
1020 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1022 store_reg_to_var_int(iptr->dst, d);
1025 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1026 /* val.i = constant */
1028 var_to_reg_int(s1, src, REG_ITMP1);
1029 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1030 M_ISRL_IMM(s1, iptr->val.i, d);
1031 store_reg_to_var_int(iptr->dst, d);
1034 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1036 var_to_reg_int(s1, src->prev, REG_ITMP1);
1037 var_to_reg_int(s2, src, REG_ITMP2);
1038 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1040 store_reg_to_var_int(iptr->dst, d);
1043 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1044 /* val.i = constant */
1046 var_to_reg_int(s1, src, REG_ITMP1);
1047 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1048 M_LSLL_IMM(s1, iptr->val.i, d);
1049 store_reg_to_var_int(iptr->dst, d);
1052 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1054 var_to_reg_int(s1, src->prev, REG_ITMP1);
1055 var_to_reg_int(s2, src, REG_ITMP2);
1056 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1062 /* val.i = constant */
1064 var_to_reg_int(s1, src, REG_ITMP1);
1065 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1066 M_LSRA_IMM(s1, iptr->val.i, d);
1067 store_reg_to_var_int(iptr->dst, d);
1070 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1072 var_to_reg_int(s1, src->prev, REG_ITMP1);
1073 var_to_reg_int(s2, src, REG_ITMP2);
1074 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1076 store_reg_to_var_int(iptr->dst, d);
1079 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1080 /* val.i = constant */
1082 var_to_reg_int(s1, src, REG_ITMP1);
1083 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1084 M_LSRL_IMM(s1, iptr->val.i, d);
1085 store_reg_to_var_int(iptr->dst, d);
1088 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1091 var_to_reg_int(s1, src->prev, REG_ITMP1);
1092 var_to_reg_int(s2, src, REG_ITMP2);
1093 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1095 store_reg_to_var_int(iptr->dst, d);
1098 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1099 /* val.i = constant */
1101 var_to_reg_int(s1, src, REG_ITMP1);
1102 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1103 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1104 M_AND_IMM(s1, iptr->val.i, d);
1106 ICONST(REG_ITMP2, iptr->val.i);
1107 M_AND(s1, REG_ITMP2, d);
1109 store_reg_to_var_int(iptr->dst, d);
1112 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1113 /* val.i = constant */
1115 var_to_reg_int(s1, src, REG_ITMP1);
1116 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1118 M_MOV(s1, REG_ITMP1);
1121 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1122 M_AND_IMM(s1, iptr->val.i, d);
1125 M_ISUB(REG_ZERO, s1, d);
1126 M_AND_IMM(d, iptr->val.i, d);
1128 ICONST(REG_ITMP2, iptr->val.i);
1129 M_AND(s1, REG_ITMP2, d);
1132 M_ISUB(REG_ZERO, s1, d);
1133 M_AND(d, REG_ITMP2, d);
1135 M_ISUB(REG_ZERO, d, d);
1136 store_reg_to_var_int(iptr->dst, d);
1139 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1140 /* val.l = constant */
1142 var_to_reg_int(s1, src, REG_ITMP1);
1143 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1144 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1145 M_AND_IMM(s1, iptr->val.l, d);
1147 LCONST(REG_ITMP2, iptr->val.l);
1148 M_AND(s1, REG_ITMP2, d);
1150 store_reg_to_var_int(iptr->dst, d);
1153 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1154 /* val.l = constant */
1156 var_to_reg_int(s1, src, REG_ITMP1);
1157 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1159 M_MOV(s1, REG_ITMP1);
1162 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1163 M_AND_IMM(s1, iptr->val.l, d);
1166 M_LSUB(REG_ZERO, s1, d);
1167 M_AND_IMM(d, iptr->val.l, d);
1169 LCONST(REG_ITMP2, iptr->val.l);
1170 M_AND(s1, REG_ITMP2, d);
1173 M_LSUB(REG_ZERO, s1, d);
1174 M_AND(d, REG_ITMP2, d);
1176 M_LSUB(REG_ZERO, d, d);
1177 store_reg_to_var_int(iptr->dst, d);
1180 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1183 var_to_reg_int(s1, src->prev, REG_ITMP1);
1184 var_to_reg_int(s2, src, REG_ITMP2);
1185 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1187 store_reg_to_var_int(iptr->dst, d);
1190 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1191 /* val.i = constant */
1193 var_to_reg_int(s1, src, REG_ITMP1);
1194 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1195 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1196 M_OR_IMM(s1, iptr->val.i, d);
1198 ICONST(REG_ITMP2, iptr->val.i);
1199 M_OR(s1, REG_ITMP2, d);
1201 store_reg_to_var_int(iptr->dst, d);
1204 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1205 /* val.l = constant */
1207 var_to_reg_int(s1, src, REG_ITMP1);
1208 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1209 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1210 M_OR_IMM(s1, iptr->val.l, d);
1212 LCONST(REG_ITMP2, iptr->val.l);
1213 M_OR(s1, REG_ITMP2, d);
1215 store_reg_to_var_int(iptr->dst, d);
1218 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1221 var_to_reg_int(s1, src->prev, REG_ITMP1);
1222 var_to_reg_int(s2, src, REG_ITMP2);
1223 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1225 store_reg_to_var_int(iptr->dst, d);
1228 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1229 /* val.i = constant */
1231 var_to_reg_int(s1, src, REG_ITMP1);
1232 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1233 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1234 M_XOR_IMM(s1, iptr->val.i, d);
1236 ICONST(REG_ITMP2, iptr->val.i);
1237 M_XOR(s1, REG_ITMP2, d);
1239 store_reg_to_var_int(iptr->dst, d);
1242 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1243 /* val.l = constant */
1245 var_to_reg_int(s1, src, REG_ITMP1);
1246 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1247 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1248 M_XOR_IMM(s1, iptr->val.l, d);
1250 LCONST(REG_ITMP2, iptr->val.l);
1251 M_XOR(s1, REG_ITMP2, d);
1253 store_reg_to_var_int(iptr->dst, d);
1257 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1259 var_to_reg_int(s1, src->prev, REG_ITMP1);
1260 var_to_reg_int(s2, src, REG_ITMP2);
1261 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1262 M_CMPLT(s1, s2, REG_ITMP3);
1263 M_CMPLT(s2, s1, REG_ITMP1);
1264 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1265 store_reg_to_var_int(iptr->dst, d);
1269 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1270 /* op1 = variable, val.i = constant */
1272 var = &(rd->locals[iptr->op1][TYPE_INT]);
1273 if (var->flags & INMEMORY) {
1275 M_LLD(s1, REG_SP, var->regoff * 8);
1278 M_IADD_IMM(s1, iptr->val.i, s1);
1279 if (var->flags & INMEMORY)
1280 M_LST(s1, REG_SP, var->regoff * 8);
1284 /* floating operations ************************************************/
1286 case ICMD_FNEG: /* ..., value ==> ..., - value */
1288 var_to_reg_flt(s1, src, REG_FTMP1);
1289 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1291 store_reg_to_var_flt(iptr->dst, d);
1294 case ICMD_DNEG: /* ..., value ==> ..., - value */
1296 var_to_reg_flt(s1, src, REG_FTMP1);
1297 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1299 store_reg_to_var_flt(iptr->dst, d);
1302 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1304 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1305 var_to_reg_flt(s2, src, REG_FTMP2);
1306 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1308 store_reg_to_var_flt(iptr->dst, d);
1311 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1313 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1314 var_to_reg_flt(s2, src, REG_FTMP2);
1315 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1317 store_reg_to_var_flt(iptr->dst, d);
1320 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1322 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1323 var_to_reg_flt(s2, src, REG_FTMP2);
1324 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1326 store_reg_to_var_flt(iptr->dst, d);
1329 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1331 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1332 var_to_reg_flt(s2, src, REG_FTMP2);
1333 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1335 store_reg_to_var_flt(iptr->dst, d);
1338 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1340 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1341 var_to_reg_flt(s2, src, REG_FTMP2);
1342 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1344 store_reg_to_var_flt(iptr->dst, d);
1347 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1349 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1350 var_to_reg_flt(s2, src, REG_FTMP2);
1351 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1353 store_reg_to_var_flt(iptr->dst, d);
1356 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1358 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1359 var_to_reg_flt(s2, src, REG_FTMP2);
1360 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1362 store_reg_to_var_flt(iptr->dst, d);
1365 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1367 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1368 var_to_reg_flt(s2, src, REG_FTMP2);
1369 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1371 store_reg_to_var_flt(iptr->dst, d);
1375 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1377 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1378 var_to_reg_flt(s2, src, REG_FTMP2);
1379 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1380 M_FDIV(s1,s2, REG_FTMP3);
1381 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1382 M_CVTLF(REG_FTMP3, REG_FTMP3);
1383 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1384 M_FSUB(s1, REG_FTMP3, d);
1385 store_reg_to_var_flt(iptr->dst, d);
1388 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1390 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1391 var_to_reg_flt(s2, src, REG_FTMP2);
1392 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1393 M_DDIV(s1,s2, REG_FTMP3);
1394 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1395 M_CVTLD(REG_FTMP3, REG_FTMP3);
1396 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1397 M_DSUB(s1, REG_FTMP3, d);
1398 store_reg_to_var_flt(iptr->dst, d);
1402 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1404 var_to_reg_int(s1, src, REG_ITMP1);
1405 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1408 store_reg_to_var_flt(iptr->dst, d);
1411 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1413 var_to_reg_int(s1, src, REG_ITMP1);
1414 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1417 store_reg_to_var_flt(iptr->dst, d);
1421 /* XXX these do not work correctly */
1423 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1425 var_to_reg_flt(s1, src, REG_FTMP1);
1426 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1427 M_TRUNCFI(s1, REG_FTMP1);
1428 M_MOVDI(REG_FTMP1, d);
1430 store_reg_to_var_int(iptr->dst, d);
1433 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1435 var_to_reg_flt(s1, src, REG_FTMP1);
1436 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1437 M_TRUNCDI(s1, REG_FTMP1);
1438 M_MOVDI(REG_FTMP1, d);
1440 store_reg_to_var_int(iptr->dst, d);
1443 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1445 var_to_reg_flt(s1, src, REG_FTMP1);
1446 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1447 M_TRUNCFL(s1, REG_FTMP1);
1448 M_MOVDL(REG_FTMP1, d);
1450 store_reg_to_var_int(iptr->dst, d);
1453 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1455 var_to_reg_flt(s1, src, REG_FTMP1);
1456 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1457 M_TRUNCDL(s1, REG_FTMP1);
1458 M_MOVDL(REG_FTMP1, d);
1460 store_reg_to_var_int(iptr->dst, d);
1464 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1466 var_to_reg_flt(s1, src, REG_FTMP1);
1467 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1469 store_reg_to_var_flt(iptr->dst, d);
1472 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1474 var_to_reg_flt(s1, src, REG_FTMP1);
1475 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1477 store_reg_to_var_flt(iptr->dst, d);
1480 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1482 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1483 var_to_reg_flt(s2, src, REG_FTMP2);
1484 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1487 M_LADD_IMM(REG_ZERO, 1, d);
1491 M_LSUB_IMM(REG_ZERO, 1, d);
1492 M_CMOVT(REG_ZERO, d);
1493 store_reg_to_var_int(iptr->dst, d);
1496 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1498 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1499 var_to_reg_flt(s2, src, REG_FTMP2);
1500 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1503 M_LADD_IMM(REG_ZERO, 1, d);
1507 M_LSUB_IMM(REG_ZERO, 1, d);
1508 M_CMOVT(REG_ZERO, d);
1509 store_reg_to_var_int(iptr->dst, d);
1512 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1514 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1515 var_to_reg_flt(s2, src, REG_FTMP2);
1516 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1519 M_LSUB_IMM(REG_ZERO, 1, d);
1523 M_LADD_IMM(REG_ZERO, 1, d);
1524 M_CMOVT(REG_ZERO, d);
1525 store_reg_to_var_int(iptr->dst, d);
1528 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1530 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1531 var_to_reg_flt(s2, src, REG_FTMP2);
1532 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1535 M_LSUB_IMM(REG_ZERO, 1, d);
1539 M_LADD_IMM(REG_ZERO, 1, d);
1540 M_CMOVT(REG_ZERO, d);
1541 store_reg_to_var_int(iptr->dst, d);
1545 /* memory operations **************************************************/
1547 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1549 var_to_reg_int(s1, src, REG_ITMP1);
1550 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1551 gen_nullptr_check(s1);
1552 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1553 store_reg_to_var_int(iptr->dst, d);
1556 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1558 var_to_reg_int(s1, src->prev, REG_ITMP1);
1559 var_to_reg_int(s2, src, REG_ITMP2);
1560 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1561 if (iptr->op1 == 0) {
1562 gen_nullptr_check(s1);
1565 M_AADD(s2, s1, REG_ITMP3);
1566 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1567 store_reg_to_var_int(iptr->dst, d);
1570 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1572 var_to_reg_int(s1, src->prev, REG_ITMP1);
1573 var_to_reg_int(s2, src, REG_ITMP2);
1574 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1575 if (iptr->op1 == 0) {
1576 gen_nullptr_check(s1);
1579 M_AADD(s2, s1, REG_ITMP3);
1580 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1581 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1582 store_reg_to_var_int(iptr->dst, d);
1585 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1587 var_to_reg_int(s1, src->prev, REG_ITMP1);
1588 var_to_reg_int(s2, src, REG_ITMP2);
1589 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1590 if (iptr->op1 == 0) {
1591 gen_nullptr_check(s1);
1594 M_AADD(s2, s1, REG_ITMP3);
1595 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1596 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1597 store_reg_to_var_int(iptr->dst, d);
1600 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1602 var_to_reg_int(s1, src->prev, REG_ITMP1);
1603 var_to_reg_int(s2, src, REG_ITMP2);
1604 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1605 if (iptr->op1 == 0) {
1606 gen_nullptr_check(s1);
1609 M_ASLL_IMM(s2, 2, REG_ITMP3);
1610 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1611 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1612 store_reg_to_var_int(iptr->dst, d);
1615 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1617 var_to_reg_int(s1, src->prev, REG_ITMP1);
1618 var_to_reg_int(s2, src, REG_ITMP2);
1619 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1620 if (iptr->op1 == 0) {
1621 gen_nullptr_check(s1);
1624 M_ASLL_IMM(s2, 3, REG_ITMP3);
1625 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1626 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1627 store_reg_to_var_int(iptr->dst, d);
1630 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1632 var_to_reg_int(s1, src->prev, REG_ITMP1);
1633 var_to_reg_int(s2, src, REG_ITMP2);
1634 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1635 if (iptr->op1 == 0) {
1636 gen_nullptr_check(s1);
1639 M_ASLL_IMM(s2, 2, REG_ITMP3);
1640 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1641 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1642 store_reg_to_var_flt(iptr->dst, d);
1645 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1647 var_to_reg_int(s1, src->prev, REG_ITMP1);
1648 var_to_reg_int(s2, src, REG_ITMP2);
1649 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1650 if (iptr->op1 == 0) {
1651 gen_nullptr_check(s1);
1654 M_ASLL_IMM(s2, 3, REG_ITMP3);
1655 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1656 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1657 store_reg_to_var_flt(iptr->dst, d);
1660 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1662 var_to_reg_int(s1, src->prev, REG_ITMP1);
1663 var_to_reg_int(s2, src, REG_ITMP2);
1664 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1665 if (iptr->op1 == 0) {
1666 gen_nullptr_check(s1);
1669 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1670 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1671 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1672 store_reg_to_var_int(iptr->dst, d);
1676 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1678 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1679 var_to_reg_int(s2, src->prev, REG_ITMP2);
1680 if (iptr->op1 == 0) {
1681 gen_nullptr_check(s1);
1684 M_AADD(s2, s1, REG_ITMP1);
1685 var_to_reg_int(s3, src, REG_ITMP3);
1686 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1689 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1690 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1692 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1693 var_to_reg_int(s2, src->prev, REG_ITMP2);
1694 if (iptr->op1 == 0) {
1695 gen_nullptr_check(s1);
1698 M_AADD(s2, s1, REG_ITMP1);
1699 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1700 var_to_reg_int(s3, src, REG_ITMP3);
1701 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1704 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1706 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1707 var_to_reg_int(s2, src->prev, REG_ITMP2);
1708 if (iptr->op1 == 0) {
1709 gen_nullptr_check(s1);
1712 M_ASLL_IMM(s2, 2, REG_ITMP2);
1713 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1714 var_to_reg_int(s3, src, REG_ITMP3);
1715 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1718 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1720 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1721 var_to_reg_int(s2, src->prev, REG_ITMP2);
1722 if (iptr->op1 == 0) {
1723 gen_nullptr_check(s1);
1726 M_ASLL_IMM(s2, 3, REG_ITMP2);
1727 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1728 var_to_reg_int(s3, src, REG_ITMP3);
1729 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1732 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1734 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1735 var_to_reg_int(s2, src->prev, REG_ITMP2);
1736 if (iptr->op1 == 0) {
1737 gen_nullptr_check(s1);
1740 M_ASLL_IMM(s2, 2, REG_ITMP2);
1741 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1742 var_to_reg_flt(s3, src, REG_FTMP1);
1743 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1746 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1748 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1749 var_to_reg_int(s2, src->prev, REG_ITMP2);
1750 if (iptr->op1 == 0) {
1751 gen_nullptr_check(s1);
1754 M_ASLL_IMM(s2, 3, REG_ITMP2);
1755 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1756 var_to_reg_flt(s3, src, REG_FTMP1);
1757 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1761 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1763 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1764 var_to_reg_int(s2, src->prev, REG_ITMP2);
1765 if (iptr->op1 == 0) {
1766 gen_nullptr_check(s1);
1769 var_to_reg_int(s3, src, REG_ITMP3);
1771 M_MOV(s1, rd->argintregs[0]);
1772 M_MOV(s3, rd->argintregs[1]);
1773 disp = dseg_addaddress(cd, BUILTIN_canstore);
1774 M_ALD(REG_ITMP3, REG_PV, disp);
1775 M_JSR(REG_RA, REG_ITMP3);
1778 M_BEQZ(REG_RESULT, 0);
1779 codegen_add_arraystoreexception_ref(cd, mcodeptr);
1782 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1783 var_to_reg_int(s2, src->prev, REG_ITMP2);
1784 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1785 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1786 var_to_reg_int(s3, src, REG_ITMP3);
1787 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1791 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1793 var_to_reg_int(s1, src->prev, REG_ITMP1);
1794 var_to_reg_int(s2, src, REG_ITMP2);
1795 if (iptr->op1 == 0) {
1796 gen_nullptr_check(s1);
1799 M_AADD(s2, s1, REG_ITMP1);
1800 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1803 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1804 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1806 var_to_reg_int(s1, src->prev, REG_ITMP1);
1807 var_to_reg_int(s2, src, REG_ITMP2);
1808 if (iptr->op1 == 0) {
1809 gen_nullptr_check(s1);
1812 M_AADD(s2, s1, REG_ITMP1);
1813 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1814 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1817 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1819 var_to_reg_int(s1, src->prev, REG_ITMP1);
1820 var_to_reg_int(s2, src, REG_ITMP2);
1821 if (iptr->op1 == 0) {
1822 gen_nullptr_check(s1);
1825 M_ASLL_IMM(s2, 2, REG_ITMP2);
1826 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1827 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1830 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1832 var_to_reg_int(s1, src->prev, REG_ITMP1);
1833 var_to_reg_int(s2, src, REG_ITMP2);
1834 if (iptr->op1 == 0) {
1835 gen_nullptr_check(s1);
1838 M_ASLL_IMM(s2, 3, REG_ITMP2);
1839 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1840 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1843 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1845 var_to_reg_int(s1, src->prev, REG_ITMP1);
1846 var_to_reg_int(s2, src, REG_ITMP2);
1847 if (iptr->op1 == 0) {
1848 gen_nullptr_check(s1);
1851 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1852 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1853 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1857 case ICMD_GETSTATIC: /* ... ==> ..., value */
1858 /* op1 = type, val.a = field address */
1860 if (iptr->val.a == NULL) {
1861 disp = dseg_addaddress(cd, NULL);
1863 codegen_addpatchref(cd, mcodeptr,
1864 PATCHER_get_putstatic,
1865 (unresolved_field *) iptr->target, disp);
1867 if (opt_showdisassemble) {
1872 fieldinfo *fi = iptr->val.a;
1874 disp = dseg_addaddress(cd, &(fi->value));
1876 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1877 codegen_addpatchref(cd, mcodeptr,
1878 PATCHER_clinit, fi->class, 0);
1880 if (opt_showdisassemble) {
1886 M_ALD(REG_ITMP1, REG_PV, disp);
1887 switch (iptr->op1) {
1889 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1890 M_ILD_INTERN(d, REG_ITMP1, 0);
1891 store_reg_to_var_int(iptr->dst, d);
1894 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1895 M_LLD_INTERN(d, REG_ITMP1, 0);
1896 store_reg_to_var_int(iptr->dst, d);
1899 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1900 M_ALD_INTERN(d, REG_ITMP1, 0);
1901 store_reg_to_var_int(iptr->dst, d);
1904 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1905 M_FLD_INTERN(d, REG_ITMP1, 0);
1906 store_reg_to_var_flt(iptr->dst, d);
1909 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1910 M_DLD_INTERN(d, REG_ITMP1, 0);
1911 store_reg_to_var_flt(iptr->dst, d);
1916 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1917 /* op1 = type, val.a = field address */
1919 if (iptr->val.a == NULL) {
1920 disp = dseg_addaddress(cd, NULL);
1922 codegen_addpatchref(cd, mcodeptr,
1923 PATCHER_get_putstatic,
1924 (unresolved_field *) iptr->target, disp);
1926 if (opt_showdisassemble) {
1931 fieldinfo *fi = iptr->val.a;
1933 disp = dseg_addaddress(cd, &(fi->value));
1935 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1936 codegen_addpatchref(cd, mcodeptr,
1937 PATCHER_clinit, fi->class, 0);
1939 if (opt_showdisassemble) {
1945 M_ALD(REG_ITMP1, REG_PV, disp);
1946 switch (iptr->op1) {
1948 var_to_reg_int(s2, src, REG_ITMP2);
1949 M_IST_INTERN(s2, REG_ITMP1, 0);
1952 var_to_reg_int(s2, src, REG_ITMP2);
1953 M_LST_INTERN(s2, REG_ITMP1, 0);
1956 var_to_reg_int(s2, src, REG_ITMP2);
1957 M_AST_INTERN(s2, REG_ITMP1, 0);
1960 var_to_reg_flt(s2, src, REG_FTMP2);
1961 M_FST_INTERN(s2, REG_ITMP1, 0);
1964 var_to_reg_flt(s2, src, REG_FTMP2);
1965 M_DST_INTERN(s2, REG_ITMP1, 0);
1970 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1971 /* val = value (in current instruction) */
1972 /* op1 = type, val.a = field address (in */
1973 /* following NOP) */
1975 if (iptr[1].val.a == NULL) {
1976 disp = dseg_addaddress(cd, NULL);
1978 codegen_addpatchref(cd, mcodeptr,
1979 PATCHER_get_putstatic,
1980 (unresolved_field *) iptr[1].target, disp);
1982 if (opt_showdisassemble) {
1987 fieldinfo *fi = iptr[1].val.a;
1989 disp = dseg_addaddress(cd, &(fi->value));
1991 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1992 codegen_addpatchref(cd, mcodeptr,
1993 PATCHER_clinit, fi->class, 0);
1995 if (opt_showdisassemble) {
2001 M_ALD(REG_ITMP1, REG_PV, disp);
2002 switch (iptr->op1) {
2004 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2007 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2010 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2013 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2016 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2022 case ICMD_GETFIELD: /* ... ==> ..., value */
2023 /* op1 = type, val.i = field offset */
2025 var_to_reg_int(s1, src, REG_ITMP1);
2026 gen_nullptr_check(s1);
2028 if (iptr->val.a == NULL) {
2029 codegen_addpatchref(cd, mcodeptr,
2030 PATCHER_get_putfield,
2031 (unresolved_field *) iptr->target, 0);
2033 if (opt_showdisassemble) {
2040 a = ((fieldinfo *) (iptr->val.a))->offset;
2043 switch (iptr->op1) {
2045 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2047 store_reg_to_var_int(iptr->dst, d);
2050 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2052 store_reg_to_var_int(iptr->dst, d);
2055 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2057 store_reg_to_var_int(iptr->dst, d);
2060 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2062 store_reg_to_var_flt(iptr->dst, d);
2065 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2067 store_reg_to_var_flt(iptr->dst, d);
2072 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2073 /* op1 = type, val.a = field address */
2075 var_to_reg_int(s1, src->prev, REG_ITMP1);
2076 gen_nullptr_check(s1);
2078 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2079 var_to_reg_int(s2, src, REG_ITMP2);
2081 var_to_reg_flt(s2, src, REG_FTMP2);
2084 if (iptr->val.a == NULL) {
2085 codegen_addpatchref(cd, mcodeptr,
2086 PATCHER_get_putfield,
2087 (unresolved_field *) iptr->target, 0);
2089 if (opt_showdisassemble) {
2096 a = ((fieldinfo *) (iptr->val.a))->offset;
2099 switch (iptr->op1) {
2118 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2119 /* val = value (in current instruction) */
2120 /* op1 = type, val.a = field address (in */
2121 /* following NOP) */
2123 var_to_reg_int(s1, src, REG_ITMP1);
2124 gen_nullptr_check(s1);
2126 if (iptr[1].val.a == NULL) {
2127 codegen_addpatchref(cd, mcodeptr,
2128 PATCHER_get_putfield,
2129 (unresolved_field *) iptr[1].target, 0);
2131 if (opt_showdisassemble) {
2138 a = ((fieldinfo *) (iptr[1].val.a))->offset;
2141 switch (iptr[1].op1) {
2143 M_IST(REG_ZERO, s1, a);
2146 M_LST(REG_ZERO, s1, a);
2149 M_AST(REG_ZERO, s1, a);
2152 M_FST(REG_ZERO, s1, a);
2155 M_DST(REG_ZERO, s1, a);
2161 /* branch operations **************************************************/
2163 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2165 var_to_reg_int(s1, src, REG_ITMP1);
2166 M_INTMOVE(s1, REG_ITMP1_XPTR);
2168 #ifdef ENABLE_VERIFIER
2170 codegen_addpatchref(cd, mcodeptr,
2171 PATCHER_athrow_areturn,
2172 (unresolved_class *) iptr->val.a, 0);
2174 if (opt_showdisassemble) {
2178 #endif /* ENABLE_VERIFIER */
2180 disp = dseg_addaddress(cd, asm_handle_exception);
2181 M_ALD(REG_ITMP2, REG_PV, disp);
2182 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2184 M_NOP; /* nop ensures that XPC is less than the end */
2185 /* of basic block */
2189 case ICMD_GOTO: /* ... ==> ... */
2190 /* op1 = target JavaVM pc */
2192 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2197 case ICMD_JSR: /* ... ==> ... */
2198 /* op1 = target JavaVM pc */
2200 dseg_addtarget(cd, (basicblock *) iptr->target);
2201 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2202 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2206 case ICMD_RET: /* ... ==> ... */
2207 /* op1 = local variable */
2208 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2209 if (var->flags & INMEMORY) {
2210 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2218 case ICMD_IFNULL: /* ..., value ==> ... */
2219 /* op1 = target JavaVM pc */
2221 var_to_reg_int(s1, src, REG_ITMP1);
2223 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2227 case ICMD_IFNONNULL: /* ..., value ==> ... */
2228 /* op1 = target JavaVM pc */
2230 var_to_reg_int(s1, src, REG_ITMP1);
2232 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2236 case ICMD_IFEQ: /* ..., value ==> ... */
2237 /* op1 = target JavaVM pc, val.i = constant */
2239 var_to_reg_int(s1, src, REG_ITMP1);
2240 if (iptr->val.i == 0) {
2243 ICONST(REG_ITMP2, iptr->val.i);
2244 M_BEQ(s1, REG_ITMP2, 0);
2246 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2250 case ICMD_IFLT: /* ..., value ==> ... */
2251 /* op1 = target JavaVM pc, val.i = constant */
2253 var_to_reg_int(s1, src, REG_ITMP1);
2254 if (iptr->val.i == 0) {
2257 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2258 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2260 ICONST(REG_ITMP2, iptr->val.i);
2261 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2263 M_BNEZ(REG_ITMP1, 0);
2265 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2269 case ICMD_IFLE: /* ..., value ==> ... */
2270 /* op1 = target JavaVM pc, val.i = constant */
2272 var_to_reg_int(s1, src, REG_ITMP1);
2273 if (iptr->val.i == 0) {
2277 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2278 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2279 M_BNEZ(REG_ITMP1, 0);
2282 ICONST(REG_ITMP2, iptr->val.i);
2283 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2284 M_BEQZ(REG_ITMP1, 0);
2287 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2291 case ICMD_IFNE: /* ..., value ==> ... */
2292 /* op1 = target JavaVM pc, val.i = constant */
2294 var_to_reg_int(s1, src, REG_ITMP1);
2295 if (iptr->val.i == 0) {
2299 ICONST(REG_ITMP2, iptr->val.i);
2300 M_BNE(s1, REG_ITMP2, 0);
2302 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2306 case ICMD_IFGT: /* ..., value ==> ... */
2307 /* op1 = target JavaVM pc, val.i = constant */
2309 var_to_reg_int(s1, src, REG_ITMP1);
2310 if (iptr->val.i == 0) {
2314 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2315 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2316 M_BEQZ(REG_ITMP1, 0);
2319 ICONST(REG_ITMP2, iptr->val.i);
2320 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2321 M_BNEZ(REG_ITMP1, 0);
2324 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2328 case ICMD_IFGE: /* ..., value ==> ... */
2329 /* op1 = target JavaVM pc, val.i = constant */
2331 var_to_reg_int(s1, src, REG_ITMP1);
2332 if (iptr->val.i == 0) {
2336 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2337 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2340 ICONST(REG_ITMP2, iptr->val.i);
2341 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2343 M_BEQZ(REG_ITMP1, 0);
2345 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2349 case ICMD_IF_LEQ: /* ..., value ==> ... */
2350 /* op1 = target JavaVM pc, val.l = constant */
2352 var_to_reg_int(s1, src, REG_ITMP1);
2353 if (iptr->val.l == 0) {
2357 LCONST(REG_ITMP2, iptr->val.l);
2358 M_BEQ(s1, REG_ITMP2, 0);
2360 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2364 case ICMD_IF_LLT: /* ..., value ==> ... */
2365 /* op1 = target JavaVM pc, val.l = constant */
2367 var_to_reg_int(s1, src, REG_ITMP1);
2368 if (iptr->val.l == 0) {
2372 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2373 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2376 LCONST(REG_ITMP2, iptr->val.l);
2377 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2379 M_BNEZ(REG_ITMP1, 0);
2381 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2385 case ICMD_IF_LLE: /* ..., value ==> ... */
2386 /* op1 = target JavaVM pc, val.l = constant */
2388 var_to_reg_int(s1, src, REG_ITMP1);
2389 if (iptr->val.l == 0) {
2393 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2394 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2395 M_BNEZ(REG_ITMP1, 0);
2398 LCONST(REG_ITMP2, iptr->val.l);
2399 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2400 M_BEQZ(REG_ITMP1, 0);
2403 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2407 case ICMD_IF_LNE: /* ..., value ==> ... */
2408 /* op1 = target JavaVM pc, val.l = constant */
2410 var_to_reg_int(s1, src, REG_ITMP1);
2411 if (iptr->val.l == 0) {
2415 LCONST(REG_ITMP2, iptr->val.l);
2416 M_BNE(s1, REG_ITMP2, 0);
2418 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2422 case ICMD_IF_LGT: /* ..., value ==> ... */
2423 /* op1 = target JavaVM pc, val.l = constant */
2425 var_to_reg_int(s1, src, REG_ITMP1);
2426 if (iptr->val.l == 0) {
2430 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2431 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2432 M_BEQZ(REG_ITMP1, 0);
2435 LCONST(REG_ITMP2, iptr->val.l);
2436 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2437 M_BNEZ(REG_ITMP1, 0);
2440 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2444 case ICMD_IF_LGE: /* ..., value ==> ... */
2445 /* op1 = target JavaVM pc, val.l = constant */
2447 var_to_reg_int(s1, src, REG_ITMP1);
2448 if (iptr->val.l == 0) {
2452 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2453 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2456 LCONST(REG_ITMP2, iptr->val.l);
2457 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2459 M_BEQZ(REG_ITMP1, 0);
2461 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2465 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2466 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2467 case ICMD_IF_ACMPEQ:
2469 var_to_reg_int(s1, src->prev, REG_ITMP1);
2470 var_to_reg_int(s2, src, REG_ITMP2);
2472 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2476 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2477 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2478 case ICMD_IF_ACMPNE:
2480 var_to_reg_int(s1, src->prev, REG_ITMP1);
2481 var_to_reg_int(s2, src, REG_ITMP2);
2483 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2487 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2488 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2490 var_to_reg_int(s1, src->prev, REG_ITMP1);
2491 var_to_reg_int(s2, src, REG_ITMP2);
2492 M_CMPLT(s1, s2, REG_ITMP1);
2493 M_BNEZ(REG_ITMP1, 0);
2494 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2498 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2499 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2501 var_to_reg_int(s1, src->prev, REG_ITMP1);
2502 var_to_reg_int(s2, src, REG_ITMP2);
2503 M_CMPGT(s1, s2, REG_ITMP1);
2504 M_BNEZ(REG_ITMP1, 0);
2505 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2509 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2510 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2512 var_to_reg_int(s1, src->prev, REG_ITMP1);
2513 var_to_reg_int(s2, src, REG_ITMP2);
2514 M_CMPGT(s1, s2, REG_ITMP1);
2515 M_BEQZ(REG_ITMP1, 0);
2516 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2520 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2521 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2523 var_to_reg_int(s1, src->prev, REG_ITMP1);
2524 var_to_reg_int(s2, src, REG_ITMP2);
2525 M_CMPLT(s1, s2, REG_ITMP1);
2526 M_BEQZ(REG_ITMP1, 0);
2527 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2531 #ifdef CONDITIONAL_LOADCONST
2532 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2534 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2537 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2538 /* val.i = constant */
2540 var_to_reg_int(s1, src, REG_ITMP1);
2541 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2543 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2544 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2545 M_CMPEQ(s1, REG_ZERO, d);
2546 store_reg_to_var_int(iptr->dst, d);
2549 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2550 M_CMPEQ(s1, REG_ZERO, d);
2552 store_reg_to_var_int(iptr->dst, d);
2556 M_MOV(s1, REG_ITMP1);
2559 ICONST(d, iptr[1].val.i);
2561 if ((s3 >= 0) && (s3 <= 255)) {
2562 M_CMOVEQ_IMM(s1, s3, d);
2564 ICONST(REG_ITMP3, s3);
2565 M_CMOVEQ(s1, REG_ITMP3, d);
2567 store_reg_to_var_int(iptr->dst, d);
2570 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2571 /* val.i = constant */
2573 var_to_reg_int(s1, src, REG_ITMP1);
2574 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2576 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2577 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2578 M_CMPEQ(s1, REG_ZERO, d);
2579 store_reg_to_var_int(iptr->dst, d);
2582 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2583 M_CMPEQ(s1, REG_ZERO, d);
2585 store_reg_to_var_int(iptr->dst, d);
2589 M_MOV(s1, REG_ITMP1);
2592 ICONST(d, iptr[1].val.i);
2594 if ((s3 >= 0) && (s3 <= 255)) {
2595 M_CMOVNE_IMM(s1, s3, d);
2597 ICONST(REG_ITMP3, s3);
2598 M_CMOVNE(s1, REG_ITMP3, d);
2600 store_reg_to_var_int(iptr->dst, d);
2603 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2604 /* val.i = constant */
2606 var_to_reg_int(s1, src, REG_ITMP1);
2607 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2609 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2610 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2611 M_CMPLT(s1, REG_ZERO, d);
2612 store_reg_to_var_int(iptr->dst, d);
2615 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2616 M_CMPLE(REG_ZERO, s1, d);
2617 store_reg_to_var_int(iptr->dst, d);
2621 M_MOV(s1, REG_ITMP1);
2624 ICONST(d, iptr[1].val.i);
2626 if ((s3 >= 0) && (s3 <= 255)) {
2627 M_CMOVLT_IMM(s1, s3, d);
2629 ICONST(REG_ITMP3, s3);
2630 M_CMOVLT(s1, REG_ITMP3, d);
2632 store_reg_to_var_int(iptr->dst, d);
2635 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2636 /* val.i = constant */
2638 var_to_reg_int(s1, src, REG_ITMP1);
2639 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2641 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2642 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2643 M_CMPLE(REG_ZERO, s1, d);
2644 store_reg_to_var_int(iptr->dst, d);
2647 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2648 M_CMPLT(s1, REG_ZERO, d);
2649 store_reg_to_var_int(iptr->dst, d);
2653 M_MOV(s1, REG_ITMP1);
2656 ICONST(d, iptr[1].val.i);
2658 if ((s3 >= 0) && (s3 <= 255)) {
2659 M_CMOVGE_IMM(s1, s3, d);
2661 ICONST(REG_ITMP3, s3);
2662 M_CMOVGE(s1, REG_ITMP3, d);
2664 store_reg_to_var_int(iptr->dst, d);
2667 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2668 /* val.i = constant */
2670 var_to_reg_int(s1, src, REG_ITMP1);
2671 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2673 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2674 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2675 M_CMPLT(REG_ZERO, s1, d);
2676 store_reg_to_var_int(iptr->dst, d);
2679 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2680 M_CMPLE(s1, REG_ZERO, d);
2681 store_reg_to_var_int(iptr->dst, d);
2685 M_MOV(s1, REG_ITMP1);
2688 ICONST(d, iptr[1].val.i);
2690 if ((s3 >= 0) && (s3 <= 255)) {
2691 M_CMOVGT_IMM(s1, s3, d);
2693 ICONST(REG_ITMP3, s3);
2694 M_CMOVGT(s1, REG_ITMP3, d);
2696 store_reg_to_var_int(iptr->dst, d);
2699 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2700 /* val.i = constant */
2702 var_to_reg_int(s1, src, REG_ITMP1);
2703 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2705 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2706 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2707 M_CMPLE(s1, REG_ZERO, d);
2708 store_reg_to_var_int(iptr->dst, d);
2711 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2712 M_CMPLT(REG_ZERO, s1, d);
2713 store_reg_to_var_int(iptr->dst, d);
2717 M_MOV(s1, REG_ITMP1);
2720 ICONST(d, iptr[1].val.i);
2722 if ((s3 >= 0) && (s3 <= 255)) {
2723 M_CMOVLE_IMM(s1, s3, d);
2725 ICONST(REG_ITMP3, s3);
2726 M_CMOVLE(s1, REG_ITMP3, d);
2728 store_reg_to_var_int(iptr->dst, d);
2733 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2736 var_to_reg_int(s1, src, REG_RESULT);
2737 M_INTMOVE(s1, REG_RESULT);
2738 goto nowperformreturn;
2740 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2742 var_to_reg_int(s1, src, REG_RESULT);
2743 M_INTMOVE(s1, REG_RESULT);
2745 #ifdef ENABLE_VERIFIER
2747 codegen_addpatchref(cd, mcodeptr,
2748 PATCHER_athrow_areturn,
2749 (unresolved_class *) iptr->val.a, 0);
2751 if (opt_showdisassemble) {
2755 #endif /* ENABLE_VERIFIER */
2756 goto nowperformreturn;
2758 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2760 var_to_reg_flt(s1, src, REG_FRESULT);
2762 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2763 M_TFLTMOVE(t, s1, REG_FRESULT);
2765 goto nowperformreturn;
2767 case ICMD_RETURN: /* ... ==> ... */
2773 p = parentargs_base;
2775 /* call trace function */
2777 if (opt_verbosecall) {
2778 M_LDA(REG_SP, REG_SP, -3 * 8);
2779 M_LST(REG_RA, REG_SP, 0 * 8);
2780 M_LST(REG_RESULT, REG_SP, 1 * 8);
2781 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2783 disp = dseg_addaddress(cd, m);
2784 M_ALD(rd->argintregs[0], REG_PV, disp);
2785 M_MOV(REG_RESULT, rd->argintregs[1]);
2786 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2787 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2789 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2790 M_ALD(REG_ITMP3, REG_PV, disp);
2791 M_JSR(REG_RA, REG_ITMP3);
2794 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2795 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2796 M_LLD(REG_RA, REG_SP, 0 * 8);
2797 M_LDA(REG_SP, REG_SP, 3 * 8);
2800 #if defined(USE_THREADS)
2801 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2802 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2803 M_ALD(REG_ITMP3, REG_PV, disp);
2805 /* we need to save the proper return value */
2807 switch (iptr->opc) {
2811 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2812 M_JSR(REG_RA, REG_ITMP3);
2813 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2817 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2818 M_JSR(REG_RA, REG_ITMP3);
2819 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2822 M_JSR(REG_RA, REG_ITMP3);
2823 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2827 /* and now restore the proper return value */
2829 switch (iptr->opc) {
2833 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2837 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2843 /* restore return address */
2845 if (!m->isleafmethod) {
2846 p--; M_ALD(REG_RA, REG_SP, p * 8);
2849 /* restore saved registers */
2851 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2852 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2854 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2855 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2858 /* deallocate stack and return */
2860 if (parentargs_base) {
2863 disp = parentargs_base * 8;
2864 lo = (short) (disp);
2865 hi = (short) (((disp) - lo) >> 16);
2869 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2871 M_LUI(REG_ITMP3,hi);
2872 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2874 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2887 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2892 tptr = (void **) iptr->target;
2894 s4ptr = iptr->val.a;
2895 l = s4ptr[1]; /* low */
2896 i = s4ptr[2]; /* high */
2898 var_to_reg_int(s1, src, REG_ITMP1);
2900 {M_INTMOVE(s1, REG_ITMP1);}
2901 else if (l <= 32768) {
2902 M_IADD_IMM(s1, -l, REG_ITMP1);
2905 ICONST(REG_ITMP2, l);
2906 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2912 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2913 M_BEQZ(REG_ITMP2, 0);
2914 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2915 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2917 /* build jump table top down and use address of lowest entry */
2919 /* s4ptr += 3 + i; */
2923 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2924 dseg_addtarget(cd, (basicblock *) tptr[0]);
2929 /* length of dataseg after last dseg_addtarget is used by load */
2931 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2932 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2939 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2941 s4 i, /*l, */val, *s4ptr;
2944 tptr = (void **) iptr->target;
2946 s4ptr = iptr->val.a;
2947 /*l = s4ptr[0];*/ /* default */
2948 i = s4ptr[1]; /* count */
2950 MCODECHECK((i<<2)+8);
2951 var_to_reg_int(s1, src, REG_ITMP1);
2957 ICONST(REG_ITMP2, val);
2958 M_BEQ(s1, REG_ITMP2, 0);
2959 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2964 tptr = (void **) iptr->target;
2965 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
2972 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2973 /* op1 = arg count val.a = builtintable entry */
2979 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2980 /* op1 = arg count, val.a = method pointer */
2982 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2983 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2984 case ICMD_INVOKEINTERFACE:
2989 unresolved_method *um = iptr->target;
2990 md = um->methodref->parseddesc.md;
2992 md = lm->parseddesc;
2996 s3 = md->paramcount;
2998 MCODECHECK((s3 << 1) + 64);
3000 /* copy arguments to registers or stack location */
3002 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3003 if (src->varkind == ARGVAR)
3005 if (IS_INT_LNG_TYPE(src->type)) {
3006 if (!md->params[s3].inmemory) {
3007 s1 = rd->argintregs[md->params[s3].regoff];
3008 var_to_reg_int(d, src, s1);
3011 var_to_reg_int(d, src, REG_ITMP1);
3012 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3016 if (!md->params[s3].inmemory) {
3017 s1 = rd->argfltregs[md->params[s3].regoff];
3018 var_to_reg_flt(d, src, s1);
3019 M_TFLTMOVE(src->type, d, s1);
3021 var_to_reg_flt(d, src, REG_FTMP1);
3022 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3027 switch (iptr->opc) {
3029 disp = dseg_addaddress(cd, bte->fp);
3030 d = md->returntype.type;
3032 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3033 M_JSR(REG_RA, REG_ITMP3);
3035 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3036 M_LDA(REG_PV, REG_RA, -disp);
3038 /* if op1 == true, we need to check for an exception */
3040 if (iptr->op1 == true) {
3041 M_BEQZ(REG_RESULT, 0);
3042 codegen_add_fillinstacktrace_ref(cd, mcodeptr);
3047 case ICMD_INVOKESPECIAL:
3048 M_BEQZ(rd->argintregs[0], 0);
3049 codegen_add_nullpointerexception_ref(cd, mcodeptr);
3053 case ICMD_INVOKESTATIC:
3055 unresolved_method *um = iptr->target;
3057 disp = dseg_addaddress(cd, NULL);
3059 codegen_addpatchref(cd, mcodeptr,
3060 PATCHER_invokestatic_special, um, disp);
3062 if (opt_showdisassemble) {
3066 d = um->methodref->parseddesc.md->returntype.type;
3069 disp = dseg_addaddress(cd, lm->stubroutine);
3070 d = lm->parseddesc->returntype.type;
3073 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3074 M_JSR(REG_RA, REG_PV);
3076 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3077 M_LDA(REG_PV, REG_RA, -disp);
3080 case ICMD_INVOKEVIRTUAL:
3081 gen_nullptr_check(rd->argintregs[0]);
3084 unresolved_method *um = iptr->target;
3086 codegen_addpatchref(cd, mcodeptr,
3087 PATCHER_invokevirtual, um, 0);
3089 if (opt_showdisassemble) {
3094 d = um->methodref->parseddesc.md->returntype.type;
3097 s1 = OFFSET(vftbl_t, table[0]) +
3098 sizeof(methodptr) * lm->vftblindex;
3099 d = lm->parseddesc->returntype.type;
3102 M_ALD(REG_METHODPTR, rd->argintregs[0],
3103 OFFSET(java_objectheader, vftbl));
3104 M_ALD(REG_PV, REG_METHODPTR, s1);
3105 M_JSR(REG_RA, REG_PV);
3107 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3108 M_LDA(REG_PV, REG_RA, -disp);
3111 case ICMD_INVOKEINTERFACE:
3112 gen_nullptr_check(rd->argintregs[0]);
3115 unresolved_method *um = iptr->target;
3117 codegen_addpatchref(cd, mcodeptr,
3118 PATCHER_invokeinterface, um, 0);
3120 if (opt_showdisassemble) {
3126 d = um->methodref->parseddesc.md->returntype.type;
3129 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3130 sizeof(methodptr*) * lm->class->index;
3132 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3134 d = lm->parseddesc->returntype.type;
3137 M_ALD(REG_METHODPTR, rd->argintregs[0],
3138 OFFSET(java_objectheader, vftbl));
3139 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3140 M_ALD(REG_PV, REG_METHODPTR, s2);
3141 M_JSR(REG_RA, REG_PV);
3143 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3144 M_LDA(REG_PV, REG_RA, -disp);
3148 /* d contains return type */
3150 if (d != TYPE_VOID) {
3151 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3152 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3153 M_INTMOVE(REG_RESULT, s1);
3154 store_reg_to_var_int(iptr->dst, s1);
3156 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3157 M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
3158 store_reg_to_var_flt(iptr->dst, s1);
3164 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3165 /* op1: 0 == array, 1 == class */
3166 /* val.a: (classinfo*) superclass */
3168 /* superclass is an interface:
3170 * OK if ((sub == NULL) ||
3171 * (sub->vftbl->interfacetablelength > super->index) &&
3172 * (sub->vftbl->interfacetable[-super->index] != NULL));
3174 * superclass is a class:
3176 * OK if ((sub == NULL) || (0
3177 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3178 * super->vftbl->diffvall));
3181 if (iptr->op1 == 1) {
3183 vftbl_t *supervftbl;
3186 super = (classinfo *) iptr->val.a;
3193 superindex = super->index;
3194 supervftbl = super->vftbl;
3197 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3198 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3201 var_to_reg_int(s1, src, REG_ITMP1);
3203 /* calculate interface checkcast code size */
3207 s2 += (opt_showdisassemble ? 2 : 0);
3209 /* calculate class checkcast code size */
3211 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3213 s3 += (opt_showdisassemble ? 2 : 0);
3215 /* if class is not resolved, check which code to call */
3218 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3221 disp = dseg_adds4(cd, 0); /* super->flags */
3223 codegen_addpatchref(cd, mcodeptr,
3224 PATCHER_checkcast_instanceof_flags,
3225 (constant_classref *) iptr->target,
3228 if (opt_showdisassemble) {
3232 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3233 M_ILD(REG_ITMP2, REG_PV, disp);
3234 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3235 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3239 /* interface checkcast code */
3241 if (!super || super->flags & ACC_INTERFACE) {
3247 codegen_addpatchref(cd, mcodeptr,
3248 PATCHER_checkcast_instanceof_interface,
3249 (constant_classref *) iptr->target,
3252 if (opt_showdisassemble) {
3257 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3258 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3259 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3260 M_BLEZ(REG_ITMP3, 0);
3261 codegen_add_classcastexception_ref(cd, mcodeptr);
3263 M_ALD(REG_ITMP3, REG_ITMP2,
3264 OFFSET(vftbl_t, interfacetable[0]) -
3265 superindex * sizeof(methodptr*));
3266 M_BEQZ(REG_ITMP3, 0);
3267 codegen_add_classcastexception_ref(cd, mcodeptr);
3276 /* class checkcast code */
3278 if (!super || !(super->flags & ACC_INTERFACE)) {
3279 disp = dseg_addaddress(cd, (void *) supervftbl);
3286 codegen_addpatchref(cd, mcodeptr,
3287 PATCHER_checkcast_instanceof_class,
3288 (constant_classref *) iptr->target,
3291 if (opt_showdisassemble) {
3296 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3297 M_ALD(REG_ITMP3, REG_PV, disp);
3298 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3299 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3301 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3302 /* if (s1 != REG_ITMP1) { */
3303 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3304 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3305 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3306 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3308 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3310 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3311 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3312 M_ALD(REG_ITMP3, REG_PV, disp);
3313 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3314 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3315 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3318 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3319 M_BNEZ(REG_ITMP3, 0);
3320 codegen_add_classcastexception_ref(cd, mcodeptr);
3323 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3326 var_to_reg_int(s1, src, rd->argintregs[0]);
3327 M_INTMOVE(s1, rd->argintregs[0]);
3329 disp = dseg_addaddress(cd, iptr->val.a);
3331 if (iptr->val.a == NULL) {
3332 codegen_addpatchref(cd, mcodeptr,
3333 PATCHER_builtin_arraycheckcast,
3334 (constant_classref *) iptr->target,
3337 if (opt_showdisassemble) {
3342 M_ALD(rd->argintregs[1], REG_PV, disp);
3343 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3344 M_ALD(REG_ITMP3, REG_PV, disp);
3345 M_JSR(REG_RA, REG_ITMP3);
3348 M_BEQZ(REG_RESULT, 0);
3349 codegen_add_classcastexception_ref(cd, mcodeptr);
3352 var_to_reg_int(s1, src, REG_ITMP1);
3353 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3356 store_reg_to_var_int(iptr->dst, d);
3359 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3360 /* op1: 0 == array, 1 == class */
3361 /* val.a: (classinfo*) superclass */
3363 /* superclass is an interface:
3365 * return (sub != NULL) &&
3366 * (sub->vftbl->interfacetablelength > super->index) &&
3367 * (sub->vftbl->interfacetable[-super->index] != NULL);
3369 * superclass is a class:
3371 * return ((sub != NULL) && (0
3372 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3373 * super->vftbl->diffvall));
3378 vftbl_t *supervftbl;
3381 super = (classinfo *) iptr->val.a;
3388 superindex = super->index;
3389 supervftbl = super->vftbl;
3392 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3393 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3396 var_to_reg_int(s1, src, REG_ITMP1);
3397 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3399 M_MOV(s1, REG_ITMP1);
3403 /* calculate interface instanceof code size */
3407 s2 += (opt_showdisassemble ? 2 : 0);
3409 /* calculate class instanceof code size */
3413 s3 += (opt_showdisassemble ? 2 : 0);
3417 /* if class is not resolved, check which code to call */
3420 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3423 disp = dseg_adds4(cd, 0); /* super->flags */
3425 codegen_addpatchref(cd, mcodeptr,
3426 PATCHER_checkcast_instanceof_flags,
3427 (constant_classref *) iptr->target, disp);
3429 if (opt_showdisassemble) {
3433 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3434 M_ILD(REG_ITMP3, REG_PV, disp);
3435 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3436 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3440 /* interface instanceof code */
3442 if (!super || (super->flags & ACC_INTERFACE)) {
3448 codegen_addpatchref(cd, mcodeptr,
3449 PATCHER_checkcast_instanceof_interface,
3450 (constant_classref *) iptr->target, 0);
3452 if (opt_showdisassemble) {
3457 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3458 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3459 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3460 M_BLEZ(REG_ITMP3, 3);
3462 M_ALD(REG_ITMP1, REG_ITMP1,
3463 OFFSET(vftbl_t, interfacetable[0]) -
3464 superindex * sizeof(methodptr*));
3465 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3473 /* class instanceof code */
3475 if (!super || !(super->flags & ACC_INTERFACE)) {
3476 disp = dseg_addaddress(cd, supervftbl);
3483 codegen_addpatchref(cd, mcodeptr,
3484 PATCHER_checkcast_instanceof_class,
3485 (constant_classref *) iptr->target,
3488 if (opt_showdisassemble) {
3493 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3494 M_ALD(REG_ITMP2, REG_PV, disp);
3495 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3496 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3498 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3499 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3500 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3501 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3502 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3504 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3505 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3508 store_reg_to_var_int(iptr->dst, d);
3512 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3513 /* op1 = dimension, val.a = class */
3515 /* check for negative sizes and copy sizes to stack if necessary */
3517 MCODECHECK((iptr->op1 << 1) + 64);
3519 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3520 /* copy SAVEDVAR sizes to stack */
3522 if (src->varkind != ARGVAR) {
3523 var_to_reg_int(s2, src, REG_ITMP1);
3524 M_LST(s2, REG_SP, s1 * 8);
3528 /* a0 = dimension count */
3530 ICONST(rd->argintregs[0], iptr->op1);
3532 /* is patcher function set? */
3534 if (iptr->val.a == NULL) {
3535 disp = dseg_addaddress(cd, NULL);
3537 codegen_addpatchref(cd, mcodeptr,
3538 PATCHER_builtin_multianewarray,
3539 (constant_classref *) iptr->target,
3542 if (opt_showdisassemble) {
3547 disp = dseg_addaddress(cd, iptr->val.a);
3550 /* a1 = arraydescriptor */
3552 M_ALD(rd->argintregs[1], REG_PV, disp);
3554 /* a2 = pointer to dimensions = stack pointer */
3556 M_INTMOVE(REG_SP, rd->argintregs[2]);
3558 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3559 M_ALD(REG_ITMP3, REG_PV, disp);
3560 M_JSR(REG_RA, REG_ITMP3);
3563 /* check for exception before result assignment */
3565 M_BEQZ(REG_RESULT, 0);
3566 codegen_add_fillinstacktrace_ref(cd, mcodeptr);
3569 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3570 M_INTMOVE(REG_RESULT, d);
3571 store_reg_to_var_int(iptr->dst, d);
3575 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3579 } /* for instruction */
3581 /* copy values to interface registers */
3583 src = bptr->outstack;
3584 len = bptr->outdepth;
3586 #if defined(ENABLE_LSRA)
3591 if ((src->varkind != STACKVAR)) {
3593 if (IS_FLT_DBL_TYPE(s2)) {
3594 var_to_reg_flt(s1, src, REG_FTMP1);
3595 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3596 M_TFLTMOVE(s2, s1, rd->interfaces[len][s2].regoff);
3599 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3603 var_to_reg_int(s1, src, REG_ITMP1);
3604 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3605 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3608 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3615 /* At the end of a basic block we may have to append some nops,
3616 because the patcher stub calling code might be longer than the
3617 actual instruction. So codepatching does not change the
3618 following block unintentionally. */
3620 if ((u1 *) mcodeptr < cd->lastmcodeptr) {
3621 while ((u1 *) mcodeptr < cd->lastmcodeptr) {
3626 } /* if (bptr -> flags >= BBREACHED) */
3627 } /* for basic block */
3629 dseg_createlinenumbertable(cd);
3632 /* generate exception and patcher stubs */
3641 savedmcodeptr = NULL;
3643 /* generate exception stubs */
3645 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3646 gen_resolvebranch((u1 *) cd->mcodebase + eref->branchpos,
3648 (u1 *) mcodeptr - cd->mcodebase);
3652 /* Check if the exception is an
3653 ArrayIndexOutOfBoundsException. If so, move index register
3656 if (eref->reg != -1)
3657 M_MOV(eref->reg, REG_ITMP1);
3659 /* calcuate exception address */
3661 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3663 /* move function to call into REG_ITMP3 */
3665 disp = dseg_addaddress(cd, eref->function);
3666 M_ALD(REG_ITMP3, REG_PV, disp);
3668 if (savedmcodeptr != NULL) {
3669 M_BR(savedmcodeptr - mcodeptr);
3673 savedmcodeptr = mcodeptr;
3675 M_MOV(REG_PV, rd->argintregs[0]);
3676 M_MOV(REG_SP, rd->argintregs[1]);
3678 if (m->isleafmethod)
3679 M_MOV(REG_RA, rd->argintregs[2]);
3681 M_ALD(rd->argintregs[2],
3682 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3684 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3685 M_MOV(REG_ITMP1, rd->argintregs[4]);
3687 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3688 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3690 if (m->isleafmethod)
3691 M_AST(REG_RA, REG_SP, 1 * 8);
3693 M_JSR(REG_RA, REG_ITMP3);
3695 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3697 if (m->isleafmethod)
3698 M_ALD(REG_RA, REG_SP, 1 * 8);
3700 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3701 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3703 a = dseg_addaddress(cd, asm_handle_exception);
3704 M_ALD(REG_ITMP3, REG_PV, a);
3711 /* generate code patching stub call code */
3713 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3714 /* check code segment size */
3718 /* Get machine code which is patched back in later. The
3719 call is 2 instruction words long. */
3721 tmpmcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
3723 /* We need to split this, because an unaligned 8 byte read
3724 causes a SIGSEGV. */
3726 mcode = ((u8) tmpmcodeptr[1] << 32) + (u4) tmpmcodeptr[0];
3728 /* Patch in the call to call the following code (done at
3731 savedmcodeptr = mcodeptr; /* save current mcodeptr */
3732 mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3734 disp = (s4) (savedmcodeptr - (tmpmcodeptr + 1));
3736 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3738 new_internalerror("Jump offset is out of range: %d > +/-%d",
3746 mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3748 /* create stack frame */
3750 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3752 /* calculate return address and move it onto the stack */
3754 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3755 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3757 /* move pointer to java_objectheader onto stack */
3759 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3760 /* create a virtual java_objectheader */
3762 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3763 disp = dseg_addaddress(cd, NULL); /* vftbl */
3765 M_LDA(REG_ITMP3, REG_PV, disp);
3766 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3771 /* move machine code onto stack */
3773 disp = dseg_adds8(cd, mcode);
3774 M_LLD(REG_ITMP3, REG_PV, disp);
3775 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3777 /* move class/method/field reference onto stack */
3779 disp = dseg_addaddress(cd, pref->ref);
3780 M_ALD(REG_ITMP3, REG_PV, disp);
3781 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3783 /* move data segment displacement onto stack */
3785 disp = dseg_adds4(cd, pref->disp);
3786 M_ILD(REG_ITMP3, REG_PV, disp);
3787 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3789 /* move patcher function pointer onto stack */
3791 disp = dseg_addaddress(cd, pref->patcher);
3792 M_ALD(REG_ITMP3, REG_PV, disp);
3793 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3795 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3796 M_ALD(REG_ITMP3, REG_PV, disp);
3801 /* generate replacement-out stubs */
3806 replacementpoint = jd->code->rplpoints;
3808 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3809 /* check code segment size */
3813 /* note start of stub code */
3815 replacementpoint->outcode = (u1*) (ptrint)((u1*)mcodeptr - cd->mcodebase);
3817 /* make machine code for patching */
3819 tmpmcodeptr = mcodeptr;
3820 mcodeptr = (s4*) &(replacementpoint->mcode);
3822 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3823 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3825 new_internalerror("Jump offset is out of range: %d > +/-%d",
3830 M_NOP; /* delay slot */
3832 mcodeptr = tmpmcodeptr;
3834 /* create stack frame - 16-byte aligned */
3836 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3838 /* push address of `rplpoint` struct */
3840 disp = dseg_addaddress(cd, replacementpoint);
3841 M_ALD(REG_ITMP3, REG_PV, disp);
3842 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3844 /* jump to replacement function */
3846 disp = dseg_addaddress(cd, asm_replacement_out);
3847 M_ALD(REG_ITMP3, REG_PV, disp);
3849 M_NOP; /* delay slot */
3854 codegen_finish(jd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
3856 /* everything's ok */
3862 /* createcompilerstub **********************************************************
3864 Creates a stub routine which calls the compiler.
3866 *******************************************************************************/
3868 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3869 #define COMPILERSTUB_CODESIZE 4 * 4
3871 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3874 u1 *createcompilerstub(methodinfo *m)
3876 u1 *s; /* memory to hold the stub */
3878 s4 *mcodeptr; /* code generation pointer */
3880 s = CNEW(u1, COMPILERSTUB_SIZE);
3882 /* set data pointer and code pointer */
3885 s = s + COMPILERSTUB_DATASIZE;
3887 mcodeptr = (s4 *) s;
3889 /* Store the methodinfo* in the same place as in the methodheader
3890 for compiled methods. */
3892 d[0] = (ptrint) asm_call_jit_compiler;
3895 M_ALD_INTERN(REG_ITMP1, REG_PV, -1 * SIZEOF_VOID_P); /* method pointer */
3896 M_ALD_INTERN(REG_PV, REG_PV, -2 * SIZEOF_VOID_P); /* pointer to compiler */
3900 md_cacheflush(s, (s4) ((u1 *) mcodeptr - s));
3902 #if defined(ENABLE_STATISTICS)
3904 count_cstub_len += COMPILERSTUB_SIZE;
3911 /* createnativestub ************************************************************
3913 Creates a stub routine which calls a native method.
3915 *******************************************************************************/
3917 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3922 s4 *mcodeptr; /* code generation pointer */
3923 s4 stackframesize; /* size of stackframe if needed */
3926 s4 i, j; /* count variables */
3929 s4 funcdisp; /* displacement of the function */
3931 /* get required compiler data */
3937 /* initialize variables */
3940 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3942 /* calculate stack frame size */
3945 1 + /* return address */
3946 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3947 sizeof(localref_table) / SIZEOF_VOID_P +
3948 md->paramcount + /* for saving arguments over calls */
3949 1 + /* for saving return address */
3952 /* create method header */
3954 #if SIZEOF_VOID_P == 4
3955 (void) dseg_addaddress(cd, m); /* MethodPointer */
3957 (void) dseg_addaddress(cd, m); /* MethodPointer */
3958 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
3959 (void) dseg_adds4(cd, 0); /* IsSync */
3960 (void) dseg_adds4(cd, 0); /* IsLeaf */
3961 (void) dseg_adds4(cd, 0); /* IntSave */
3962 (void) dseg_adds4(cd, 0); /* FltSave */
3963 (void) dseg_addlinenumbertablesize(cd);
3964 (void) dseg_adds4(cd, 0); /* ExTableSize */
3967 /* initialize mcode variables */
3969 mcodeptr = (s4 *) cd->mcodeptr;
3971 /* generate stub code */
3973 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
3974 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
3976 /* call trace function */
3978 if (opt_verbosecall) {
3979 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
3981 /* save integer argument registers */
3983 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
3984 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3985 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
3987 /* save and copy float arguments into integer registers */
3989 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3990 t = md->paramtypes[i].type;
3992 if (IS_FLT_DBL_TYPE(t)) {
3993 if (IS_2_WORD_TYPE(t)) {
3994 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3995 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3997 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3998 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4003 disp = dseg_addaddress(cd, m);
4004 M_ALD(REG_ITMP1, REG_PV, disp);
4005 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4006 disp = dseg_addaddress(cd, builtin_trace_args);
4007 M_ALD(REG_ITMP3, REG_PV, disp);
4008 M_JSR(REG_RA, REG_ITMP3);
4011 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4012 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4013 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4015 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4016 t = md->paramtypes[i].type;
4018 if (IS_FLT_DBL_TYPE(t)) {
4019 if (IS_2_WORD_TYPE(t)) {
4020 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4022 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4027 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4030 /* get function address (this must happen before the stackframeinfo) */
4032 funcdisp = dseg_addaddress(cd, f);
4034 #if !defined(WITH_STATIC_CLASSPATH)
4036 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4038 if (opt_showdisassemble) {
4044 /* save integer and float argument registers */
4046 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4047 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4048 M_LST(rd->argintregs[i], REG_SP, j * 8);
4053 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4054 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4055 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4060 /* prepare data structures for native function call */
4062 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4063 M_MOV(REG_PV, rd->argintregs[1]);
4064 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4065 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4066 disp = dseg_addaddress(cd, codegen_start_native_call);
4067 M_ALD(REG_ITMP3, REG_PV, disp);
4068 M_JSR(REG_RA, REG_ITMP3);
4069 M_NOP; /* XXX fill me! */
4071 /* restore integer and float argument registers */
4073 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4074 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4075 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4080 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4081 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4082 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4087 /* copy or spill arguments to new locations */
4089 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4090 t = md->paramtypes[i].type;
4092 if (IS_INT_LNG_TYPE(t)) {
4093 if (!md->params[i].inmemory) {
4094 s1 = rd->argintregs[md->params[i].regoff];
4096 if (!nmd->params[j].inmemory) {
4097 s2 = rd->argintregs[nmd->params[j].regoff];
4100 s2 = nmd->params[j].regoff;
4101 M_AST(s1, REG_SP, s2 * 8);
4105 s1 = md->params[i].regoff + stackframesize;
4106 s2 = nmd->params[j].regoff;
4107 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4108 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4112 if (!md->params[i].inmemory) {
4113 s1 = rd->argfltregs[md->params[i].regoff];
4115 if (!nmd->params[j].inmemory) {
4116 s2 = rd->argfltregs[nmd->params[j].regoff];
4117 M_TFLTMOVE(t, s1, s2);
4119 s2 = nmd->params[j].regoff;
4120 if (IS_2_WORD_TYPE(t))
4121 M_DST(s1, REG_SP, s2 * 8);
4123 M_FST(s1, REG_SP, s2 * 8);
4127 s1 = md->params[i].regoff + stackframesize;
4128 s2 = nmd->params[j].regoff;
4129 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4130 if (IS_2_WORD_TYPE(t))
4131 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4133 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4138 /* put class into second argument register */
4140 if (m->flags & ACC_STATIC) {
4141 disp = dseg_addaddress(cd, m->class);
4142 M_ALD(rd->argintregs[1], REG_PV, disp);
4145 /* put env into first argument register */
4147 disp = dseg_addaddress(cd, _Jv_env);
4148 M_ALD(rd->argintregs[0], REG_PV, disp);
4150 /* do the native function call */
4152 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4153 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4154 M_NOP; /* delay slot */
4156 /* save return value */
4158 if (IS_INT_LNG_TYPE(md->returntype.type))
4159 M_LST(REG_RESULT, REG_SP, 0 * 8);
4161 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4163 /* remove native stackframe info */
4165 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4166 disp = dseg_addaddress(cd, codegen_finish_native_call);
4167 M_ALD(REG_ITMP3, REG_PV, disp);
4168 M_JSR(REG_RA, REG_ITMP3);
4169 M_NOP; /* XXX fill me! */
4171 /* call finished trace function */
4173 if (opt_verbosecall) {
4174 if (IS_INT_LNG_TYPE(md->returntype.type))
4175 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4177 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4179 disp = dseg_addaddress(cd, m);
4180 M_ALD(rd->argintregs[0], REG_PV, disp);
4182 M_MOV(REG_RESULT, rd->argintregs[1]);
4183 M_DMFC1(REG_ITMP1, REG_FRESULT);
4184 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4185 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4187 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4188 M_ALD(REG_ITMP3, REG_PV, disp);
4189 M_JSR(REG_RA, REG_ITMP3);
4193 /* check for exception */
4195 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4196 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4197 M_ALD(REG_ITMP3, REG_PV, disp);
4198 M_JSR(REG_RA, REG_ITMP3);
4200 M_MOV(REG_RESULT, REG_ITMP3);
4202 disp = dseg_addaddress(cd, &_exceptionptr);
4203 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4205 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4207 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4209 /* restore return value */
4211 if (IS_INT_LNG_TYPE(md->returntype.type))
4212 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4214 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4216 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4217 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4219 M_RET(REG_RA); /* return to caller */
4220 M_NOP; /* DELAY SLOT */
4222 /* handle exception */
4224 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4226 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4227 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4228 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4229 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4232 /* generate static stub call code */
4240 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4241 /* Get machine code which is patched back in later. The
4242 call is 2 instruction words long. */
4244 tmpmcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4246 /* We need to split this, because an unaligned 8 byte read
4247 causes a SIGSEGV. */
4249 mcode = ((u8) tmpmcodeptr[1] << 32) + (u4) tmpmcodeptr[0];
4251 /* Patch in the call to call the following code (done at
4254 savedmcodeptr = mcodeptr; /* save current mcodeptr */
4255 mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4257 M_BRS(savedmcodeptr - (tmpmcodeptr + 1));
4258 M_NOP; /* branch delay slot */
4260 mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4262 /* create stack frame */
4264 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4266 /* move return address onto stack */
4268 M_AST(REG_RA, REG_SP, 5 * 8);
4270 /* move pointer to java_objectheader onto stack */
4272 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4273 /* order reversed because of data segment layout */
4275 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4276 disp = dseg_addaddress(cd, NULL); /* vftbl */
4278 M_LDA(REG_ITMP3, REG_PV, disp);
4279 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4281 M_AST(REG_ZERO, REG_SP, 4 * 8);
4284 /* move machine code onto stack */
4286 disp = dseg_adds8(cd, mcode);
4287 M_LLD(REG_ITMP3, REG_PV, disp);
4288 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4290 /* move class/method/field reference onto stack */
4292 disp = dseg_addaddress(cd, pref->ref);
4293 M_ALD(REG_ITMP3, REG_PV, disp);
4294 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4296 /* move data segment displacement onto stack */
4298 disp = dseg_adds4(cd, pref->disp);
4299 M_ILD(REG_ITMP3, REG_PV, disp);
4300 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4302 /* move patcher function pointer onto stack */
4304 disp = dseg_addaddress(cd, pref->patcher);
4305 M_ALD(REG_ITMP3, REG_PV, disp);
4306 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4308 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4309 M_ALD(REG_ITMP3, REG_PV, disp);
4315 codegen_finish(jd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4317 return jd->code->entrypoint;
4322 * These are local overrides for various environment variables in Emacs.
4323 * Please do not remove this and leave it at the end of the file, where
4324 * Emacs will automagically detect them.
4325 * ---------------------------------------------------------------------
4328 * indent-tabs-mode: t
4332 * vim:noexpandtab:sw=4:ts=4: