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 4776 2006-04-14 12:40:49Z twisti $
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
56 #include "native/native.h"
57 #include "vm/builtin.h"
59 #include "vm/exceptions.h"
60 #include "vm/options.h"
61 #include "vm/stringlocal.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/dseg.h"
66 #include "vm/jit/emit.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/replace.h"
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
77 /* codegen *********************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
97 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
98 builtintable_entry *bte;
100 rplpoint *replacementpoint;
102 /* get required compiler data */
112 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
114 /* space to save used callee saved registers */
116 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
117 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
119 parentargs_base = rd->memuse + savedregs_num;
121 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
122 if (checksync && (m->flags & ACC_SYNCHRONIZED))
126 /* adjust frame size for 16 byte alignment */
128 if (parentargs_base & 1)
131 /* create method header */
133 #if SIZEOF_VOID_P == 4
134 (void) dseg_addaddress(cd, m); /* Filler */
136 (void) dseg_addaddress(cd, m); /* MethodPointer */
137 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
139 #if defined(USE_THREADS)
140 /* IsSync contains the offset relative to the stack pointer for the
141 argument of monitor_exit used in the exception handler. Since the
142 offset could be zero and give a wrong meaning of the flag it is
146 if (checksync && (m->flags & ACC_SYNCHRONIZED))
147 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
150 (void) dseg_adds4(cd, 0); /* IsSync */
152 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
153 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
154 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
155 dseg_addlinenumbertablesize(cd);
156 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
158 /* create exception table */
160 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
161 dseg_addtarget(cd, ex->start);
162 dseg_addtarget(cd, ex->end);
163 dseg_addtarget(cd, ex->handler);
164 (void) dseg_addaddress(cd, ex->catchtype.cls);
167 /* create stack frame (if necessary) */
170 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
172 /* save return address and used callee saved registers */
175 if (!m->isleafmethod) {
176 p--; M_AST(REG_RA, REG_SP, p * 8);
178 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
179 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
181 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
182 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
185 /* take arguments out of register or stack frame */
189 for (p = 0, l = 0; p < md->paramcount; p++) {
190 t = md->paramtypes[p].type;
191 var = &(rd->locals[l][t]);
193 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
197 s1 = md->params[p].regoff;
198 if (IS_INT_LNG_TYPE(t)) { /* integer args */
199 if (!md->params[p].inmemory) { /* register arguments */
200 s2 = rd->argintregs[s1];
201 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
202 M_INTMOVE(s2, var->regoff);
203 } else { /* reg arg -> spilled */
204 M_LST(s2, REG_SP, var->regoff * 8);
207 } else { /* stack arguments */
208 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
209 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
210 } else { /* stack arg -> spilled */
211 var->regoff = parentargs_base + s1;
215 } else { /* floating args */
216 if (!md->params[p].inmemory) { /* register arguments */
217 s2 = rd->argfltregs[s1];
218 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
219 M_TFLTMOVE(var->type, s2, var->regoff);
220 } else { /* reg arg -> spilled */
221 M_DST(s2, REG_SP, var->regoff * 8);
224 } else { /* stack arguments */
225 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
226 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
227 } else { /* stack-arg -> spilled */
228 var->regoff = parentargs_base + s1;
234 /* call monitorenter function */
236 #if defined(USE_THREADS)
237 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
238 /* stack offset for monitor argument */
242 if (opt_verbosecall) {
243 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
245 for (p = 0; p < INT_ARG_CNT; p++)
246 M_LST(rd->argintregs[p], REG_SP, p * 8);
248 for (p = 0; p < FLT_ARG_CNT; p++)
249 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
251 s1 += INT_ARG_CNT + FLT_ARG_CNT;
254 /* decide which monitor enter function to call */
256 if (m->flags & ACC_STATIC) {
257 p = dseg_addaddress(cd, m->class);
258 M_ALD(rd->argintregs[0], REG_PV, p);
259 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
260 M_ALD(REG_ITMP3, REG_PV, p);
261 M_JSR(REG_RA, REG_ITMP3);
262 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
265 M_BEQZ(rd->argintregs[0], 0);
266 codegen_add_nullpointerexception_ref(cd, cd->mcodeptr);
267 p = dseg_addaddress(cd, BUILTIN_monitorenter);
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 if (opt_verbosecall) {
274 for (p = 0; p < INT_ARG_CNT; p++)
275 M_LLD(rd->argintregs[p], REG_SP, p * 8);
277 for (p = 0; p < FLT_ARG_CNT; p++)
278 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
281 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
286 /* copy argument registers to stack and call trace function */
288 if (opt_verbosecall) {
289 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
290 M_AST(REG_RA, REG_SP, 1 * 8);
292 /* save integer argument registers */
294 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
295 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
297 /* save and copy float arguments into integer registers */
299 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
300 t = md->paramtypes[p].type;
302 if (IS_FLT_DBL_TYPE(t)) {
303 if (IS_2_WORD_TYPE(t)) {
304 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
305 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
308 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
309 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
313 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
317 /* save temporary registers for leaf methods */
319 if (m->isleafmethod) {
320 for (p = 0; p < INT_TMP_CNT; p++)
321 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
323 for (p = 0; p < FLT_TMP_CNT; p++)
324 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
327 p = dseg_addaddress(cd, m);
328 M_ALD(REG_ITMP1, REG_PV, p);
329 M_AST(REG_ITMP1, REG_SP, 0 * 8);
330 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
331 M_ALD(REG_ITMP3, REG_PV, disp);
332 M_JSR(REG_RA, REG_ITMP3);
335 M_ALD(REG_RA, REG_SP, 1 * 8);
337 /* restore integer argument registers */
339 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
340 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
342 /* restore float argument registers */
344 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
345 t = md->paramtypes[p].type;
347 if (IS_FLT_DBL_TYPE(t)) {
348 if (IS_2_WORD_TYPE(t)) {
349 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
352 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
356 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
360 /* restore temporary registers for leaf methods */
362 if (m->isleafmethod) {
363 for (p = 0; p < INT_TMP_CNT; p++)
364 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
366 for (p = 0; p < FLT_TMP_CNT; p++)
367 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
370 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
375 /* end of header generation */
377 replacementpoint = jd->code->rplpoints;
379 /* walk through all basic blocks */
381 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
383 /* handle replacement points */
385 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
387 /* 8-byte align pc */
388 if ((ptrint)cd->mcodeptr & 4) {
392 replacementpoint->pc = (u1*)(ptrint)((u1*)cd->mcodeptr - cd->mcodebase);
395 assert(cd->lastmcodeptr <= (u1*)cd->mcodeptr);
396 cd->lastmcodeptr = (u1*)cd->mcodeptr + 2*4; /* br + delay slot */
399 /* store relative start of block */
401 bptr->mpc = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
403 if (bptr->flags >= BBREACHED) {
405 /* branch resolving */
408 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
409 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
415 /* copy interface registers to their destination */
420 #if defined(ENABLE_LSRA)
422 while (src != NULL) {
424 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
425 /* d = reg_of_var(m, src, REG_ITMP1); */
426 if (!(src->flags & INMEMORY))
430 M_INTMOVE(REG_ITMP1, d);
431 emit_store(jd, NULL, src, d);
437 while (src != NULL) {
439 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
440 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
441 M_INTMOVE(REG_ITMP1, d);
442 emit_store(jd, NULL, src, d);
445 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
446 if ((src->varkind != STACKVAR)) {
448 if (IS_FLT_DBL_TYPE(s2)) {
449 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
450 s1 = rd->interfaces[len][s2].regoff;
451 M_TFLTMOVE(s2, s1, d);
454 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
456 emit_store(jd, NULL, src, d);
459 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
460 s1 = rd->interfaces[len][s2].regoff;
464 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
466 emit_store(jd, NULL, src, d);
472 #if defined(ENABLE_LSRA)
475 /* walk through all instructions */
481 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
482 if (iptr->line != currentline) {
483 dseg_addlinenumber(cd, iptr->line, (u1 *) cd->mcodeptr);
484 currentline = iptr->line;
487 MCODECHECK(64); /* an instruction usually needs < 64 words */
491 case ICMD_NOP: /* ... ==> ... */
494 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
496 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
498 codegen_add_nullpointerexception_ref(cd, cd->mcodeptr);
502 /* constant operations ************************************************/
504 case ICMD_ICONST: /* ... ==> ..., constant */
505 /* op1 = 0, val.i = constant */
507 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
508 ICONST(d, iptr->val.i);
509 emit_store(jd, iptr, iptr->dst, d);
512 case ICMD_LCONST: /* ... ==> ..., constant */
513 /* op1 = 0, val.l = constant */
515 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
516 LCONST(d, iptr->val.l);
517 emit_store(jd, iptr, iptr->dst, d);
520 case ICMD_FCONST: /* ... ==> ..., constant */
521 /* op1 = 0, val.f = constant */
523 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
524 disp = dseg_addfloat(cd, iptr->val.f);
525 M_FLD(d, REG_PV, disp);
526 emit_store(jd, iptr, iptr->dst, d);
529 case ICMD_DCONST: /* ... ==> ..., constant */
530 /* op1 = 0, val.d = constant */
532 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
533 disp = dseg_adddouble(cd, iptr->val.d);
534 M_DLD(d, REG_PV, disp);
535 emit_store(jd, iptr, iptr->dst, d);
538 case ICMD_ACONST: /* ... ==> ..., constant */
539 /* op1 = 0, val.a = constant */
541 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
543 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
544 disp = dseg_addaddress(cd, iptr->val.a);
546 codegen_addpatchref(cd, cd->mcodeptr,
548 (unresolved_class *) iptr->target, disp);
550 if (opt_showdisassemble) {
554 M_ALD(d, REG_PV, disp);
557 if (iptr->val.a == NULL) {
558 M_INTMOVE(REG_ZERO, d);
560 disp = dseg_addaddress(cd, iptr->val.a);
561 M_ALD(d, REG_PV, disp);
564 emit_store(jd, iptr, iptr->dst, d);
568 /* load/store operations **********************************************/
570 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
571 case ICMD_LLOAD: /* op1 = local variable */
574 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
575 if ((iptr->dst->varkind == LOCALVAR) &&
576 (iptr->dst->varnum == iptr->op1))
578 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
579 if (var->flags & INMEMORY) {
580 M_LLD(d, REG_SP, 8 * var->regoff);
582 M_INTMOVE(var->regoff,d);
584 emit_store(jd, iptr, iptr->dst, d);
587 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
588 case ICMD_DLOAD: /* op1 = local variable */
590 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
591 if ((iptr->dst->varkind == LOCALVAR) &&
592 (iptr->dst->varnum == iptr->op1))
594 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
596 int t2 = ((iptr->opc == ICMD_FLOAD) ? TYPE_FLT : TYPE_DBL);
597 if (var->flags & INMEMORY) {
598 M_CCFLD(var->type, t2, d, REG_SP, 8 * var->regoff);
600 M_CCFLTMOVE(var->type, t2, var->regoff, d);
603 emit_store(jd, iptr, iptr->dst, d);
607 case ICMD_ISTORE: /* ..., value ==> ... */
608 case ICMD_LSTORE: /* op1 = local variable */
611 if ((src->varkind == LOCALVAR) &&
612 (src->varnum == iptr->op1))
614 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
615 if (var->flags & INMEMORY) {
616 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
617 M_LST(s1, REG_SP, 8 * var->regoff);
620 s1 = emit_load_s1(jd, iptr, src, var->regoff);
621 M_INTMOVE(s1, var->regoff);
625 case ICMD_FSTORE: /* ..., value ==> ... */
626 case ICMD_DSTORE: /* op1 = local variable */
628 if ((src->varkind == LOCALVAR) &&
629 (src->varnum == iptr->op1))
631 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
633 int t1 = ((iptr->opc == ICMD_FSTORE) ? TYPE_FLT : TYPE_DBL);
634 if (var->flags & INMEMORY) {
635 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
636 M_CCFST(t1, var->type, s1, REG_SP, 8 * var->regoff);
639 s1 = emit_load_s1(jd, iptr, src, var->regoff);
640 M_CCFLTMOVE(t1, var->type, s1, var->regoff);
646 /* pop/dup/swap operations ********************************************/
648 /* attention: double and longs are only one entry in CACAO ICMDs */
650 case ICMD_POP: /* ..., value ==> ... */
651 case ICMD_POP2: /* ..., value, value ==> ... */
654 case ICMD_DUP: /* ..., a ==> ..., a, a */
655 M_COPY(src, iptr->dst);
658 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
660 M_COPY(src, iptr->dst);
661 M_COPY(src->prev, iptr->dst->prev);
662 M_COPY(iptr->dst, iptr->dst->prev->prev);
665 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
667 M_COPY(src, iptr->dst);
668 M_COPY(src->prev, iptr->dst->prev);
669 M_COPY(src->prev->prev, iptr->dst->prev->prev);
670 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
673 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
675 M_COPY(src, iptr->dst);
676 M_COPY(src->prev, iptr->dst->prev);
679 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
681 M_COPY(src, iptr->dst);
682 M_COPY(src->prev, iptr->dst->prev);
683 M_COPY(src->prev->prev, iptr->dst->prev->prev);
684 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
685 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
688 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
690 M_COPY(src, iptr->dst);
691 M_COPY(src->prev, iptr->dst->prev);
692 M_COPY(src->prev->prev, iptr->dst->prev->prev);
693 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
694 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
695 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
698 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
700 M_COPY(src, iptr->dst->prev);
701 M_COPY(src->prev, iptr->dst);
705 /* integer operations *************************************************/
707 case ICMD_INEG: /* ..., value ==> ..., - value */
709 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
710 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
711 M_ISUB(REG_ZERO, s1, d);
712 emit_store(jd, iptr, iptr->dst, d);
715 case ICMD_LNEG: /* ..., value ==> ..., - value */
717 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
718 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
719 M_LSUB(REG_ZERO, s1, d);
720 emit_store(jd, iptr, iptr->dst, d);
723 case ICMD_I2L: /* ..., value ==> ..., value */
725 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
726 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
728 emit_store(jd, iptr, iptr->dst, d);
731 case ICMD_L2I: /* ..., value ==> ..., value */
733 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
734 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
735 M_ISLL_IMM(s1, 0, d );
736 emit_store(jd, iptr, iptr->dst, d);
739 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
741 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
742 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
743 M_LSLL_IMM(s1, 56, d);
744 M_LSRA_IMM( d, 56, d);
745 emit_store(jd, iptr, iptr->dst, d);
748 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
750 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
751 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
753 emit_store(jd, iptr, iptr->dst, d);
756 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
758 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
759 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
760 M_LSLL_IMM(s1, 48, d);
761 M_LSRA_IMM( d, 48, d);
762 emit_store(jd, iptr, iptr->dst, d);
766 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
768 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
769 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
770 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
772 emit_store(jd, iptr, iptr->dst, d);
775 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
776 /* val.i = constant */
778 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
779 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
780 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
781 M_IADD_IMM(s1, iptr->val.i, d);
783 ICONST(REG_ITMP2, iptr->val.i);
784 M_IADD(s1, REG_ITMP2, d);
786 emit_store(jd, iptr, iptr->dst, d);
789 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
791 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
792 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
793 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
795 emit_store(jd, iptr, iptr->dst, d);
798 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
799 /* val.l = constant */
801 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
802 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
803 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
804 M_LADD_IMM(s1, iptr->val.l, d);
806 LCONST(REG_ITMP2, iptr->val.l);
807 M_LADD(s1, REG_ITMP2, d);
809 emit_store(jd, iptr, iptr->dst, d);
812 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
814 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
815 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
816 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
818 emit_store(jd, iptr, iptr->dst, d);
821 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
822 /* val.i = constant */
824 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
825 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
826 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
827 M_IADD_IMM(s1, -iptr->val.i, d);
829 ICONST(REG_ITMP2, iptr->val.i);
830 M_ISUB(s1, REG_ITMP2, d);
832 emit_store(jd, iptr, iptr->dst, d);
835 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
837 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
838 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
839 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
841 emit_store(jd, iptr, iptr->dst, d);
844 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
845 /* val.l = constant */
847 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
848 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
849 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
850 M_LADD_IMM(s1, -iptr->val.l, d);
852 LCONST(REG_ITMP2, iptr->val.l);
853 M_LSUB(s1, REG_ITMP2, d);
855 emit_store(jd, iptr, iptr->dst, d);
858 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
860 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
861 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
862 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
867 emit_store(jd, iptr, iptr->dst, d);
870 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
871 /* val.i = constant */
873 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
874 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
875 ICONST(REG_ITMP2, iptr->val.i);
876 M_IMUL(s1, REG_ITMP2);
880 emit_store(jd, iptr, iptr->dst, d);
883 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
885 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
886 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
887 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
892 emit_store(jd, iptr, iptr->dst, d);
895 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
896 /* val.l = constant */
898 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
899 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
900 LCONST(REG_ITMP2, iptr->val.l);
901 M_LMUL(s1, REG_ITMP2);
905 emit_store(jd, iptr, iptr->dst, d);
908 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
910 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
912 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
918 emit_store(jd, iptr, iptr->dst, d);
921 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
923 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
924 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
925 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
931 emit_store(jd, iptr, iptr->dst, d);
934 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
936 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
937 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
938 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
944 emit_store(jd, iptr, iptr->dst, d);
947 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
949 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
950 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
951 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
957 emit_store(jd, iptr, iptr->dst, d);
960 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
961 case ICMD_LDIVPOW2: /* val.i = constant */
963 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
964 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
965 M_LSRA_IMM(s1, 63, REG_ITMP2);
966 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
967 M_LADD(s1, REG_ITMP2, REG_ITMP2);
968 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
969 emit_store(jd, iptr, iptr->dst, d);
972 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
974 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
975 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
976 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
978 emit_store(jd, iptr, iptr->dst, d);
981 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
982 /* val.i = constant */
984 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
985 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
986 M_ISLL_IMM(s1, iptr->val.i, d);
987 emit_store(jd, iptr, iptr->dst, d);
990 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
992 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
993 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
994 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
996 emit_store(jd, iptr, iptr->dst, d);
999 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1000 /* val.i = constant */
1002 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1003 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1004 M_ISRA_IMM(s1, iptr->val.i, d);
1005 emit_store(jd, iptr, iptr->dst, d);
1008 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1010 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1011 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1012 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1014 emit_store(jd, iptr, iptr->dst, d);
1017 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1018 /* val.i = constant */
1020 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1021 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1022 M_ISRL_IMM(s1, iptr->val.i, d);
1023 emit_store(jd, iptr, iptr->dst, d);
1026 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1028 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1029 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1030 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1032 emit_store(jd, iptr, iptr->dst, d);
1035 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1036 /* val.i = constant */
1038 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1039 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1040 M_LSLL_IMM(s1, iptr->val.i, d);
1041 emit_store(jd, iptr, iptr->dst, d);
1044 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1046 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1047 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1048 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1050 emit_store(jd, iptr, iptr->dst, d);
1053 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1054 /* val.i = constant */
1056 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1057 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1058 M_LSRA_IMM(s1, iptr->val.i, d);
1059 emit_store(jd, iptr, iptr->dst, d);
1062 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1064 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1065 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1066 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1068 emit_store(jd, iptr, iptr->dst, d);
1071 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1072 /* val.i = constant */
1074 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1075 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1076 M_LSRL_IMM(s1, iptr->val.i, d);
1077 emit_store(jd, iptr, iptr->dst, d);
1080 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1083 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1084 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1085 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1087 emit_store(jd, iptr, iptr->dst, d);
1090 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1091 /* val.i = constant */
1093 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1094 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1095 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1096 M_AND_IMM(s1, iptr->val.i, d);
1098 ICONST(REG_ITMP2, iptr->val.i);
1099 M_AND(s1, REG_ITMP2, d);
1101 emit_store(jd, iptr, iptr->dst, d);
1104 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1105 /* val.i = constant */
1107 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1108 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1110 M_MOV(s1, REG_ITMP1);
1113 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1114 M_AND_IMM(s1, iptr->val.i, d);
1117 M_ISUB(REG_ZERO, s1, d);
1118 M_AND_IMM(d, iptr->val.i, d);
1120 ICONST(REG_ITMP2, iptr->val.i);
1121 M_AND(s1, REG_ITMP2, d);
1124 M_ISUB(REG_ZERO, s1, d);
1125 M_AND(d, REG_ITMP2, d);
1127 M_ISUB(REG_ZERO, d, d);
1128 emit_store(jd, iptr, iptr->dst, d);
1131 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1132 /* val.l = constant */
1134 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1135 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1136 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1137 M_AND_IMM(s1, iptr->val.l, d);
1139 LCONST(REG_ITMP2, iptr->val.l);
1140 M_AND(s1, REG_ITMP2, d);
1142 emit_store(jd, iptr, iptr->dst, d);
1145 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1146 /* val.l = constant */
1148 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1149 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1151 M_MOV(s1, REG_ITMP1);
1154 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1155 M_AND_IMM(s1, iptr->val.l, d);
1158 M_LSUB(REG_ZERO, s1, d);
1159 M_AND_IMM(d, iptr->val.l, d);
1161 LCONST(REG_ITMP2, iptr->val.l);
1162 M_AND(s1, REG_ITMP2, d);
1165 M_LSUB(REG_ZERO, s1, d);
1166 M_AND(d, REG_ITMP2, d);
1168 M_LSUB(REG_ZERO, d, d);
1169 emit_store(jd, iptr, iptr->dst, d);
1172 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1175 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1176 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1177 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1179 emit_store(jd, iptr, iptr->dst, d);
1182 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1183 /* val.i = constant */
1185 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1186 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1187 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1188 M_OR_IMM(s1, iptr->val.i, d);
1190 ICONST(REG_ITMP2, iptr->val.i);
1191 M_OR(s1, REG_ITMP2, d);
1193 emit_store(jd, iptr, iptr->dst, d);
1196 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1197 /* val.l = constant */
1199 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1200 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1201 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1202 M_OR_IMM(s1, iptr->val.l, d);
1204 LCONST(REG_ITMP2, iptr->val.l);
1205 M_OR(s1, REG_ITMP2, d);
1207 emit_store(jd, iptr, iptr->dst, d);
1210 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1213 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1214 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1215 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1217 emit_store(jd, iptr, iptr->dst, d);
1220 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1221 /* val.i = constant */
1223 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1224 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1225 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1226 M_XOR_IMM(s1, iptr->val.i, d);
1228 ICONST(REG_ITMP2, iptr->val.i);
1229 M_XOR(s1, REG_ITMP2, d);
1231 emit_store(jd, iptr, iptr->dst, d);
1234 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1235 /* val.l = constant */
1237 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1238 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1239 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1240 M_XOR_IMM(s1, iptr->val.l, d);
1242 LCONST(REG_ITMP2, iptr->val.l);
1243 M_XOR(s1, REG_ITMP2, d);
1245 emit_store(jd, iptr, iptr->dst, d);
1249 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1251 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1252 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1253 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1254 M_CMPLT(s1, s2, REG_ITMP3);
1255 M_CMPLT(s2, s1, REG_ITMP1);
1256 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1257 emit_store(jd, iptr, iptr->dst, d);
1261 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1262 /* op1 = variable, val.i = constant */
1264 var = &(rd->locals[iptr->op1][TYPE_INT]);
1265 if (var->flags & INMEMORY) {
1267 M_LLD(s1, REG_SP, var->regoff * 8);
1270 M_IADD_IMM(s1, iptr->val.i, s1);
1271 if (var->flags & INMEMORY)
1272 M_LST(s1, REG_SP, var->regoff * 8);
1276 /* floating operations ************************************************/
1278 case ICMD_FNEG: /* ..., value ==> ..., - value */
1280 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1281 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1283 emit_store(jd, iptr, iptr->dst, d);
1286 case ICMD_DNEG: /* ..., value ==> ..., - value */
1288 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1289 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1291 emit_store(jd, iptr, iptr->dst, d);
1294 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1296 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1297 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1298 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1300 emit_store(jd, iptr, iptr->dst, d);
1303 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1305 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1306 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1307 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1309 emit_store(jd, iptr, iptr->dst, d);
1312 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1314 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1315 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1316 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1318 emit_store(jd, iptr, iptr->dst, d);
1321 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1323 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1324 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1325 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1327 emit_store(jd, iptr, iptr->dst, d);
1330 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1332 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1333 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1334 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1336 emit_store(jd, iptr, iptr->dst, d);
1339 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1341 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1342 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1343 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1345 emit_store(jd, iptr, iptr->dst, d);
1348 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1350 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1351 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1352 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1354 emit_store(jd, iptr, iptr->dst, d);
1357 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1359 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1360 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1361 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1363 emit_store(jd, iptr, iptr->dst, d);
1367 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1369 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1370 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1371 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1372 M_FDIV(s1,s2, REG_FTMP3);
1373 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1374 M_CVTLF(REG_FTMP3, REG_FTMP3);
1375 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1376 M_FSUB(s1, REG_FTMP3, d);
1377 emit_store(jd, iptr, iptr->dst, d);
1380 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1382 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1383 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1384 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1385 M_DDIV(s1,s2, REG_FTMP3);
1386 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1387 M_CVTLD(REG_FTMP3, REG_FTMP3);
1388 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1389 M_DSUB(s1, REG_FTMP3, d);
1390 emit_store(jd, iptr, iptr->dst, d);
1394 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1396 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1397 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1400 emit_store(jd, iptr, iptr->dst, d);
1403 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1405 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1406 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1409 emit_store(jd, iptr, iptr->dst, d);
1413 /* XXX these do not work correctly */
1415 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1417 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1418 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1419 M_TRUNCFI(s1, REG_FTMP1);
1420 M_MOVDI(REG_FTMP1, d);
1422 emit_store(jd, iptr, iptr->dst, d);
1425 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1427 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1428 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1429 M_TRUNCDI(s1, REG_FTMP1);
1430 M_MOVDI(REG_FTMP1, d);
1432 emit_store(jd, iptr, iptr->dst, d);
1435 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1437 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1438 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1439 M_TRUNCFL(s1, REG_FTMP1);
1440 M_MOVDL(REG_FTMP1, d);
1442 emit_store(jd, iptr, iptr->dst, d);
1445 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1447 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1448 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1449 M_TRUNCDL(s1, REG_FTMP1);
1450 M_MOVDL(REG_FTMP1, d);
1452 emit_store(jd, iptr, iptr->dst, d);
1456 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1458 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1459 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1461 emit_store(jd, iptr, iptr->dst, d);
1464 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1466 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1467 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1469 emit_store(jd, iptr, iptr->dst, d);
1472 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1474 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1475 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1476 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1479 M_LADD_IMM(REG_ZERO, 1, d);
1483 M_LSUB_IMM(REG_ZERO, 1, d);
1484 M_CMOVT(REG_ZERO, d);
1485 emit_store(jd, iptr, iptr->dst, d);
1488 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1490 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1491 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1492 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1495 M_LADD_IMM(REG_ZERO, 1, d);
1499 M_LSUB_IMM(REG_ZERO, 1, d);
1500 M_CMOVT(REG_ZERO, d);
1501 emit_store(jd, iptr, iptr->dst, d);
1504 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1506 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1507 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1508 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1511 M_LSUB_IMM(REG_ZERO, 1, d);
1515 M_LADD_IMM(REG_ZERO, 1, d);
1516 M_CMOVT(REG_ZERO, d);
1517 emit_store(jd, iptr, iptr->dst, d);
1520 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1522 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1523 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1524 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1527 M_LSUB_IMM(REG_ZERO, 1, d);
1531 M_LADD_IMM(REG_ZERO, 1, d);
1532 M_CMOVT(REG_ZERO, d);
1533 emit_store(jd, iptr, iptr->dst, d);
1537 /* memory operations **************************************************/
1539 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1541 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1542 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1543 gen_nullptr_check(s1);
1544 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1545 emit_store(jd, iptr, iptr->dst, d);
1548 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1550 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1551 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1552 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1553 if (iptr->op1 == 0) {
1554 gen_nullptr_check(s1);
1557 M_AADD(s2, s1, REG_ITMP3);
1558 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1559 emit_store(jd, iptr, iptr->dst, d);
1562 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1564 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1565 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1566 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1567 if (iptr->op1 == 0) {
1568 gen_nullptr_check(s1);
1571 M_AADD(s2, s1, REG_ITMP3);
1572 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1573 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1574 emit_store(jd, iptr, iptr->dst, d);
1577 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1579 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1580 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1581 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1582 if (iptr->op1 == 0) {
1583 gen_nullptr_check(s1);
1586 M_AADD(s2, s1, REG_ITMP3);
1587 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1588 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1589 emit_store(jd, iptr, iptr->dst, d);
1592 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1594 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1595 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1596 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1597 if (iptr->op1 == 0) {
1598 gen_nullptr_check(s1);
1601 M_ASLL_IMM(s2, 2, REG_ITMP3);
1602 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1603 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1604 emit_store(jd, iptr, iptr->dst, d);
1607 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1609 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1610 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1611 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1612 if (iptr->op1 == 0) {
1613 gen_nullptr_check(s1);
1616 M_ASLL_IMM(s2, 3, REG_ITMP3);
1617 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1618 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1619 emit_store(jd, iptr, iptr->dst, d);
1622 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1624 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1625 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1626 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1627 if (iptr->op1 == 0) {
1628 gen_nullptr_check(s1);
1631 M_ASLL_IMM(s2, 2, REG_ITMP3);
1632 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1633 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1634 emit_store(jd, iptr, iptr->dst, d);
1637 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1639 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1640 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1641 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1642 if (iptr->op1 == 0) {
1643 gen_nullptr_check(s1);
1646 M_ASLL_IMM(s2, 3, REG_ITMP3);
1647 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1648 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1649 emit_store(jd, iptr, iptr->dst, d);
1652 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1654 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1655 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1656 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1657 if (iptr->op1 == 0) {
1658 gen_nullptr_check(s1);
1661 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1662 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1663 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1664 emit_store(jd, iptr, iptr->dst, d);
1668 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1670 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1671 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1672 if (iptr->op1 == 0) {
1673 gen_nullptr_check(s1);
1676 M_AADD(s2, s1, REG_ITMP1);
1677 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1678 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1681 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1682 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1684 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1685 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1686 if (iptr->op1 == 0) {
1687 gen_nullptr_check(s1);
1690 M_AADD(s2, s1, REG_ITMP1);
1691 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1692 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1693 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1696 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1698 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1699 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1700 if (iptr->op1 == 0) {
1701 gen_nullptr_check(s1);
1704 M_ASLL_IMM(s2, 2, REG_ITMP2);
1705 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1706 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1707 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1710 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1712 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1713 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1714 if (iptr->op1 == 0) {
1715 gen_nullptr_check(s1);
1718 M_ASLL_IMM(s2, 3, REG_ITMP2);
1719 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1720 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1721 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1724 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1726 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1727 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1728 if (iptr->op1 == 0) {
1729 gen_nullptr_check(s1);
1732 M_ASLL_IMM(s2, 2, REG_ITMP2);
1733 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1734 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1735 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1738 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1740 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1741 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1742 if (iptr->op1 == 0) {
1743 gen_nullptr_check(s1);
1746 M_ASLL_IMM(s2, 3, REG_ITMP2);
1747 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1748 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1749 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1753 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1755 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1756 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1757 if (iptr->op1 == 0) {
1758 gen_nullptr_check(s1);
1761 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1763 M_MOV(s1, rd->argintregs[0]);
1764 M_MOV(s3, rd->argintregs[1]);
1765 disp = dseg_addaddress(cd, BUILTIN_canstore);
1766 M_ALD(REG_ITMP3, REG_PV, disp);
1767 M_JSR(REG_RA, REG_ITMP3);
1770 M_BEQZ(REG_RESULT, 0);
1771 codegen_add_arraystoreexception_ref(cd, cd->mcodeptr);
1774 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1775 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1776 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1777 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1778 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1779 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1783 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1785 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1786 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1787 if (iptr->op1 == 0) {
1788 gen_nullptr_check(s1);
1791 M_AADD(s2, s1, REG_ITMP1);
1792 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1795 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1796 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1798 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1799 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1800 if (iptr->op1 == 0) {
1801 gen_nullptr_check(s1);
1804 M_AADD(s2, s1, REG_ITMP1);
1805 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1806 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1809 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1811 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1812 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1813 if (iptr->op1 == 0) {
1814 gen_nullptr_check(s1);
1817 M_ASLL_IMM(s2, 2, REG_ITMP2);
1818 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1819 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1822 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1824 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1825 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1826 if (iptr->op1 == 0) {
1827 gen_nullptr_check(s1);
1830 M_ASLL_IMM(s2, 3, REG_ITMP2);
1831 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1832 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1835 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1837 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1838 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1839 if (iptr->op1 == 0) {
1840 gen_nullptr_check(s1);
1843 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1844 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1845 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1849 case ICMD_GETSTATIC: /* ... ==> ..., value */
1850 /* op1 = type, val.a = field address */
1852 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1853 disp = dseg_addaddress(cd, NULL);
1855 codegen_addpatchref(cd, cd->mcodeptr,
1856 PATCHER_get_putstatic,
1857 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1859 if (opt_showdisassemble) {
1864 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1866 disp = dseg_addaddress(cd, &(fi->value));
1868 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1869 codegen_addpatchref(cd, cd->mcodeptr,
1870 PATCHER_clinit, fi->class, 0);
1872 if (opt_showdisassemble) {
1878 M_ALD(REG_ITMP1, REG_PV, disp);
1879 switch (iptr->op1) {
1881 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1882 M_ILD_INTERN(d, REG_ITMP1, 0);
1883 emit_store(jd, iptr, iptr->dst, d);
1886 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1887 M_LLD_INTERN(d, REG_ITMP1, 0);
1888 emit_store(jd, iptr, iptr->dst, d);
1891 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1892 M_ALD_INTERN(d, REG_ITMP1, 0);
1893 emit_store(jd, iptr, iptr->dst, d);
1896 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1897 M_FLD_INTERN(d, REG_ITMP1, 0);
1898 emit_store(jd, iptr, iptr->dst, d);
1901 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1902 M_DLD_INTERN(d, REG_ITMP1, 0);
1903 emit_store(jd, iptr, iptr->dst, d);
1908 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1909 /* op1 = type, val.a = field address */
1911 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1912 disp = dseg_addaddress(cd, NULL);
1914 codegen_addpatchref(cd, cd->mcodeptr,
1915 PATCHER_get_putstatic,
1916 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1918 if (opt_showdisassemble) {
1923 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1925 disp = dseg_addaddress(cd, &(fi->value));
1927 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1928 codegen_addpatchref(cd, cd->mcodeptr,
1929 PATCHER_clinit, fi->class, 0);
1931 if (opt_showdisassemble) {
1937 M_ALD(REG_ITMP1, REG_PV, disp);
1938 switch (iptr->op1) {
1940 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1941 M_IST_INTERN(s2, REG_ITMP1, 0);
1944 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1945 M_LST_INTERN(s2, REG_ITMP1, 0);
1948 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1949 M_AST_INTERN(s2, REG_ITMP1, 0);
1952 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1953 M_FST_INTERN(s2, REG_ITMP1, 0);
1956 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1957 M_DST_INTERN(s2, REG_ITMP1, 0);
1962 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1963 /* val = value (in current instruction) */
1964 /* op1 = type, val.a = field address (in */
1965 /* following NOP) */
1967 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1968 disp = dseg_addaddress(cd, NULL);
1970 codegen_addpatchref(cd, cd->mcodeptr,
1971 PATCHER_get_putstatic,
1972 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
1974 if (opt_showdisassemble) {
1979 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
1981 disp = dseg_addaddress(cd, &(fi->value));
1983 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1984 codegen_addpatchref(cd, cd->mcodeptr,
1985 PATCHER_clinit, fi->class, 0);
1987 if (opt_showdisassemble) {
1993 M_ALD(REG_ITMP1, REG_PV, disp);
1994 switch (iptr->op1) {
1996 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1999 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2002 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2005 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2008 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2014 case ICMD_GETFIELD: /* ... ==> ..., value */
2015 /* op1 = type, val.i = field offset */
2017 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2018 gen_nullptr_check(s1);
2020 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2021 codegen_addpatchref(cd, cd->mcodeptr,
2022 PATCHER_get_putfield,
2023 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2025 if (opt_showdisassemble) {
2032 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2035 switch (iptr->op1) {
2037 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2039 emit_store(jd, iptr, iptr->dst, d);
2042 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2044 emit_store(jd, iptr, iptr->dst, d);
2047 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2049 emit_store(jd, iptr, iptr->dst, d);
2052 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2054 emit_store(jd, iptr, iptr->dst, d);
2057 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2059 emit_store(jd, iptr, iptr->dst, d);
2064 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2065 /* op1 = type, val.a = field address */
2067 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2068 gen_nullptr_check(s1);
2070 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2071 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2073 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2076 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2077 codegen_addpatchref(cd, cd->mcodeptr,
2078 PATCHER_get_putfield,
2079 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2081 if (opt_showdisassemble) {
2088 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2091 switch (iptr->op1) {
2110 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2111 /* val = value (in current instruction) */
2112 /* op1 = type, val.a = field address (in */
2113 /* following NOP) */
2115 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2116 gen_nullptr_check(s1);
2118 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2119 codegen_addpatchref(cd, cd->mcodeptr,
2120 PATCHER_get_putfield,
2121 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2123 if (opt_showdisassemble) {
2130 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2133 switch (iptr[1].op1) {
2135 M_IST(REG_ZERO, s1, a);
2138 M_LST(REG_ZERO, s1, a);
2141 M_AST(REG_ZERO, s1, a);
2144 M_FST(REG_ZERO, s1, a);
2147 M_DST(REG_ZERO, s1, a);
2153 /* branch operations **************************************************/
2155 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2157 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2158 M_INTMOVE(s1, REG_ITMP1_XPTR);
2160 #ifdef ENABLE_VERIFIER
2162 codegen_addpatchref(cd, cd->mcodeptr,
2163 PATCHER_athrow_areturn,
2164 (unresolved_class *) iptr->val.a, 0);
2166 if (opt_showdisassemble) {
2170 #endif /* ENABLE_VERIFIER */
2172 disp = dseg_addaddress(cd, asm_handle_exception);
2173 M_ALD(REG_ITMP2, REG_PV, disp);
2174 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2176 M_NOP; /* nop ensures that XPC is less than the end */
2177 /* of basic block */
2181 case ICMD_GOTO: /* ... ==> ... */
2182 /* op1 = target JavaVM pc */
2184 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2189 case ICMD_JSR: /* ... ==> ... */
2190 /* op1 = target JavaVM pc */
2192 dseg_addtarget(cd, (basicblock *) iptr->target);
2193 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2194 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2198 case ICMD_RET: /* ... ==> ... */
2199 /* op1 = local variable */
2200 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2201 if (var->flags & INMEMORY) {
2202 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2210 case ICMD_IFNULL: /* ..., value ==> ... */
2211 /* op1 = target JavaVM pc */
2213 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2215 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2219 case ICMD_IFNONNULL: /* ..., value ==> ... */
2220 /* op1 = target JavaVM pc */
2222 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2224 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2228 case ICMD_IFEQ: /* ..., value ==> ... */
2229 /* op1 = target JavaVM pc, val.i = constant */
2231 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2232 if (iptr->val.i == 0) {
2235 ICONST(REG_ITMP2, iptr->val.i);
2236 M_BEQ(s1, REG_ITMP2, 0);
2238 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2242 case ICMD_IFLT: /* ..., value ==> ... */
2243 /* op1 = target JavaVM pc, val.i = constant */
2245 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2246 if (iptr->val.i == 0) {
2249 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2250 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2252 ICONST(REG_ITMP2, iptr->val.i);
2253 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2255 M_BNEZ(REG_ITMP1, 0);
2257 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2261 case ICMD_IFLE: /* ..., value ==> ... */
2262 /* op1 = target JavaVM pc, val.i = constant */
2264 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2265 if (iptr->val.i == 0) {
2269 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2270 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2271 M_BNEZ(REG_ITMP1, 0);
2274 ICONST(REG_ITMP2, iptr->val.i);
2275 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2276 M_BEQZ(REG_ITMP1, 0);
2279 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2283 case ICMD_IFNE: /* ..., value ==> ... */
2284 /* op1 = target JavaVM pc, val.i = constant */
2286 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2287 if (iptr->val.i == 0) {
2291 ICONST(REG_ITMP2, iptr->val.i);
2292 M_BNE(s1, REG_ITMP2, 0);
2294 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2298 case ICMD_IFGT: /* ..., value ==> ... */
2299 /* op1 = target JavaVM pc, val.i = constant */
2301 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2302 if (iptr->val.i == 0) {
2306 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2307 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2308 M_BEQZ(REG_ITMP1, 0);
2311 ICONST(REG_ITMP2, iptr->val.i);
2312 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2313 M_BNEZ(REG_ITMP1, 0);
2316 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2320 case ICMD_IFGE: /* ..., value ==> ... */
2321 /* op1 = target JavaVM pc, val.i = constant */
2323 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2324 if (iptr->val.i == 0) {
2328 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2329 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2332 ICONST(REG_ITMP2, iptr->val.i);
2333 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2335 M_BEQZ(REG_ITMP1, 0);
2337 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2341 case ICMD_IF_LEQ: /* ..., value ==> ... */
2342 /* op1 = target JavaVM pc, val.l = constant */
2344 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2345 if (iptr->val.l == 0) {
2349 LCONST(REG_ITMP2, iptr->val.l);
2350 M_BEQ(s1, REG_ITMP2, 0);
2352 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2356 case ICMD_IF_LLT: /* ..., value ==> ... */
2357 /* op1 = target JavaVM pc, val.l = constant */
2359 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2360 if (iptr->val.l == 0) {
2364 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2365 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2368 LCONST(REG_ITMP2, iptr->val.l);
2369 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2371 M_BNEZ(REG_ITMP1, 0);
2373 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2377 case ICMD_IF_LLE: /* ..., value ==> ... */
2378 /* op1 = target JavaVM pc, val.l = constant */
2380 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2381 if (iptr->val.l == 0) {
2385 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2386 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2387 M_BNEZ(REG_ITMP1, 0);
2390 LCONST(REG_ITMP2, iptr->val.l);
2391 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2392 M_BEQZ(REG_ITMP1, 0);
2395 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2399 case ICMD_IF_LNE: /* ..., value ==> ... */
2400 /* op1 = target JavaVM pc, val.l = constant */
2402 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2403 if (iptr->val.l == 0) {
2407 LCONST(REG_ITMP2, iptr->val.l);
2408 M_BNE(s1, REG_ITMP2, 0);
2410 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2414 case ICMD_IF_LGT: /* ..., value ==> ... */
2415 /* op1 = target JavaVM pc, val.l = constant */
2417 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2418 if (iptr->val.l == 0) {
2422 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2423 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2424 M_BEQZ(REG_ITMP1, 0);
2427 LCONST(REG_ITMP2, iptr->val.l);
2428 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2429 M_BNEZ(REG_ITMP1, 0);
2432 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2436 case ICMD_IF_LGE: /* ..., value ==> ... */
2437 /* op1 = target JavaVM pc, val.l = constant */
2439 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2440 if (iptr->val.l == 0) {
2444 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2445 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2448 LCONST(REG_ITMP2, iptr->val.l);
2449 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2451 M_BEQZ(REG_ITMP1, 0);
2453 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2457 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2458 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2459 case ICMD_IF_ACMPEQ:
2461 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2462 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2464 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2468 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2469 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2470 case ICMD_IF_ACMPNE:
2472 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2473 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2475 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2479 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2480 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2482 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2483 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2484 M_CMPLT(s1, s2, REG_ITMP1);
2485 M_BNEZ(REG_ITMP1, 0);
2486 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2490 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2491 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2493 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2494 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2495 M_CMPGT(s1, s2, REG_ITMP1);
2496 M_BNEZ(REG_ITMP1, 0);
2497 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2501 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2502 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2504 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2505 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2506 M_CMPGT(s1, s2, REG_ITMP1);
2507 M_BEQZ(REG_ITMP1, 0);
2508 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2512 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2513 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2515 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2516 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2517 M_CMPLT(s1, s2, REG_ITMP1);
2518 M_BEQZ(REG_ITMP1, 0);
2519 codegen_addreference(cd, (basicblock *) iptr->target, cd->mcodeptr);
2523 #ifdef CONDITIONAL_LOADCONST
2524 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2526 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2529 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2530 /* val.i = constant */
2532 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2533 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2535 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2536 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2537 M_CMPEQ(s1, REG_ZERO, d);
2538 emit_store(jd, iptr, iptr->dst, d);
2541 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2542 M_CMPEQ(s1, REG_ZERO, d);
2544 emit_store(jd, iptr, iptr->dst, d);
2548 M_MOV(s1, REG_ITMP1);
2551 ICONST(d, iptr[1].val.i);
2553 if ((s3 >= 0) && (s3 <= 255)) {
2554 M_CMOVEQ_IMM(s1, s3, d);
2556 ICONST(REG_ITMP3, s3);
2557 M_CMOVEQ(s1, REG_ITMP3, d);
2559 emit_store(jd, iptr, iptr->dst, d);
2562 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2563 /* val.i = constant */
2565 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2566 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2568 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2569 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2570 M_CMPEQ(s1, REG_ZERO, d);
2571 emit_store(jd, iptr, iptr->dst, d);
2574 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2575 M_CMPEQ(s1, REG_ZERO, d);
2577 emit_store(jd, iptr, iptr->dst, d);
2581 M_MOV(s1, REG_ITMP1);
2584 ICONST(d, iptr[1].val.i);
2586 if ((s3 >= 0) && (s3 <= 255)) {
2587 M_CMOVNE_IMM(s1, s3, d);
2589 ICONST(REG_ITMP3, s3);
2590 M_CMOVNE(s1, REG_ITMP3, d);
2592 emit_store(jd, iptr, iptr->dst, d);
2595 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2596 /* val.i = constant */
2598 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2599 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2601 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2602 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2603 M_CMPLT(s1, REG_ZERO, d);
2604 emit_store(jd, iptr, iptr->dst, d);
2607 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2608 M_CMPLE(REG_ZERO, s1, d);
2609 emit_store(jd, iptr, iptr->dst, d);
2613 M_MOV(s1, REG_ITMP1);
2616 ICONST(d, iptr[1].val.i);
2618 if ((s3 >= 0) && (s3 <= 255)) {
2619 M_CMOVLT_IMM(s1, s3, d);
2621 ICONST(REG_ITMP3, s3);
2622 M_CMOVLT(s1, REG_ITMP3, d);
2624 emit_store(jd, iptr, iptr->dst, d);
2627 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2628 /* val.i = constant */
2630 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2631 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2633 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2634 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2635 M_CMPLE(REG_ZERO, s1, d);
2636 emit_store(jd, iptr, iptr->dst, d);
2639 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2640 M_CMPLT(s1, REG_ZERO, d);
2641 emit_store(jd, iptr, iptr->dst, d);
2645 M_MOV(s1, REG_ITMP1);
2648 ICONST(d, iptr[1].val.i);
2650 if ((s3 >= 0) && (s3 <= 255)) {
2651 M_CMOVGE_IMM(s1, s3, d);
2653 ICONST(REG_ITMP3, s3);
2654 M_CMOVGE(s1, REG_ITMP3, d);
2656 emit_store(jd, iptr, iptr->dst, d);
2659 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2660 /* val.i = constant */
2662 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2663 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2665 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2666 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2667 M_CMPLT(REG_ZERO, s1, d);
2668 emit_store(jd, iptr, iptr->dst, d);
2671 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2672 M_CMPLE(s1, REG_ZERO, d);
2673 emit_store(jd, iptr, iptr->dst, d);
2677 M_MOV(s1, REG_ITMP1);
2680 ICONST(d, iptr[1].val.i);
2682 if ((s3 >= 0) && (s3 <= 255)) {
2683 M_CMOVGT_IMM(s1, s3, d);
2685 ICONST(REG_ITMP3, s3);
2686 M_CMOVGT(s1, REG_ITMP3, d);
2688 emit_store(jd, iptr, iptr->dst, d);
2691 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2692 /* val.i = constant */
2694 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2695 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2697 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2698 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2699 M_CMPLE(s1, REG_ZERO, d);
2700 emit_store(jd, iptr, iptr->dst, d);
2703 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2704 M_CMPLT(REG_ZERO, s1, d);
2705 emit_store(jd, iptr, iptr->dst, d);
2709 M_MOV(s1, REG_ITMP1);
2712 ICONST(d, iptr[1].val.i);
2714 if ((s3 >= 0) && (s3 <= 255)) {
2715 M_CMOVLE_IMM(s1, s3, d);
2717 ICONST(REG_ITMP3, s3);
2718 M_CMOVLE(s1, REG_ITMP3, d);
2720 emit_store(jd, iptr, iptr->dst, d);
2725 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2728 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2729 M_INTMOVE(s1, REG_RESULT);
2730 goto nowperformreturn;
2732 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2734 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2735 M_INTMOVE(s1, REG_RESULT);
2737 #ifdef ENABLE_VERIFIER
2739 codegen_addpatchref(cd, cd->mcodeptr,
2740 PATCHER_athrow_areturn,
2741 (unresolved_class *) iptr->val.a, 0);
2743 if (opt_showdisassemble) {
2747 #endif /* ENABLE_VERIFIER */
2748 goto nowperformreturn;
2750 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2752 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2754 int t = ((iptr->opc == ICMD_FRETURN) ? TYPE_FLT : TYPE_DBL);
2755 M_TFLTMOVE(t, s1, REG_FRESULT);
2757 goto nowperformreturn;
2759 case ICMD_RETURN: /* ... ==> ... */
2765 p = parentargs_base;
2767 /* call trace function */
2769 if (opt_verbosecall) {
2770 M_LDA(REG_SP, REG_SP, -3 * 8);
2771 M_LST(REG_RA, REG_SP, 0 * 8);
2772 M_LST(REG_RESULT, REG_SP, 1 * 8);
2773 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2775 disp = dseg_addaddress(cd, m);
2776 M_ALD(rd->argintregs[0], REG_PV, disp);
2777 M_MOV(REG_RESULT, rd->argintregs[1]);
2778 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2779 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2781 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2782 M_ALD(REG_ITMP3, REG_PV, disp);
2783 M_JSR(REG_RA, REG_ITMP3);
2786 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2787 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2788 M_LLD(REG_RA, REG_SP, 0 * 8);
2789 M_LDA(REG_SP, REG_SP, 3 * 8);
2792 #if defined(USE_THREADS)
2793 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2794 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2795 M_ALD(REG_ITMP3, REG_PV, disp);
2797 /* we need to save the proper return value */
2799 switch (iptr->opc) {
2803 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2804 M_JSR(REG_RA, REG_ITMP3);
2805 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2809 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2810 M_JSR(REG_RA, REG_ITMP3);
2811 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2814 M_JSR(REG_RA, REG_ITMP3);
2815 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2819 /* and now restore the proper return value */
2821 switch (iptr->opc) {
2825 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2829 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2835 /* restore return address */
2837 if (!m->isleafmethod) {
2838 p--; M_ALD(REG_RA, REG_SP, p * 8);
2841 /* restore saved registers */
2843 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2844 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2846 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2847 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2850 /* deallocate stack and return */
2852 if (parentargs_base) {
2855 disp = parentargs_base * 8;
2856 lo = (short) (disp);
2857 hi = (short) (((disp) - lo) >> 16);
2861 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2863 M_LUI(REG_ITMP3,hi);
2864 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2866 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2879 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2884 tptr = (void **) iptr->target;
2886 s4ptr = iptr->val.a;
2887 l = s4ptr[1]; /* low */
2888 i = s4ptr[2]; /* high */
2890 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2892 {M_INTMOVE(s1, REG_ITMP1);}
2893 else if (l <= 32768) {
2894 M_IADD_IMM(s1, -l, REG_ITMP1);
2897 ICONST(REG_ITMP2, l);
2898 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2904 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2905 M_BEQZ(REG_ITMP2, 0);
2906 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
2907 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2909 /* build jump table top down and use address of lowest entry */
2911 /* s4ptr += 3 + i; */
2915 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2916 dseg_addtarget(cd, (basicblock *) tptr[0]);
2921 /* length of dataseg after last dseg_addtarget is used by load */
2923 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2924 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2931 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2933 s4 i, /*l, */val, *s4ptr;
2936 tptr = (void **) iptr->target;
2938 s4ptr = iptr->val.a;
2939 /*l = s4ptr[0];*/ /* default */
2940 i = s4ptr[1]; /* count */
2942 MCODECHECK((i<<2)+8);
2943 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2949 ICONST(REG_ITMP2, val);
2950 M_BEQ(s1, REG_ITMP2, 0);
2951 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
2956 tptr = (void **) iptr->target;
2957 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
2964 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2965 /* op1 = arg count val.a = builtintable entry */
2971 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2972 /* op1 = arg count, val.a = method pointer */
2974 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2975 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2976 case ICMD_INVOKEINTERFACE:
2978 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2979 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
2983 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
2984 md = lm->parseddesc;
2988 s3 = md->paramcount;
2990 MCODECHECK((s3 << 1) + 64);
2992 /* copy arguments to registers or stack location */
2994 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2995 if (src->varkind == ARGVAR)
2997 if (IS_INT_LNG_TYPE(src->type)) {
2998 if (!md->params[s3].inmemory) {
2999 s1 = rd->argintregs[md->params[s3].regoff];
3000 d = emit_load_s1(jd, iptr, src, s1);
3003 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3004 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3008 if (!md->params[s3].inmemory) {
3009 s1 = rd->argfltregs[md->params[s3].regoff];
3010 d = emit_load_s1(jd, iptr, src, s1);
3011 M_TFLTMOVE(src->type, d, s1);
3013 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3014 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3019 switch (iptr->opc) {
3021 disp = dseg_addaddress(cd, bte->fp);
3022 d = md->returntype.type;
3024 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3025 M_JSR(REG_RA, REG_ITMP3);
3027 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3028 M_LDA(REG_PV, REG_RA, -disp);
3030 /* if op1 == true, we need to check for an exception */
3032 if (iptr->op1 == true) {
3033 M_BEQZ(REG_RESULT, 0);
3034 codegen_add_fillinstacktrace_ref(cd, cd->mcodeptr);
3039 case ICMD_INVOKESPECIAL:
3040 M_BEQZ(rd->argintregs[0], 0);
3041 codegen_add_nullpointerexception_ref(cd, cd->mcodeptr);
3045 case ICMD_INVOKESTATIC:
3047 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3049 disp = dseg_addaddress(cd, NULL);
3051 codegen_addpatchref(cd, cd->mcodeptr,
3052 PATCHER_invokestatic_special, um, disp);
3054 if (opt_showdisassemble) {
3058 d = um->methodref->parseddesc.md->returntype.type;
3061 disp = dseg_addaddress(cd, lm->stubroutine);
3062 d = lm->parseddesc->returntype.type;
3065 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3066 M_JSR(REG_RA, REG_PV);
3068 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3069 M_LDA(REG_PV, REG_RA, -disp);
3072 case ICMD_INVOKEVIRTUAL:
3073 gen_nullptr_check(rd->argintregs[0]);
3076 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3078 codegen_addpatchref(cd, cd->mcodeptr,
3079 PATCHER_invokevirtual, um, 0);
3081 if (opt_showdisassemble) {
3086 d = um->methodref->parseddesc.md->returntype.type;
3089 s1 = OFFSET(vftbl_t, table[0]) +
3090 sizeof(methodptr) * lm->vftblindex;
3091 d = lm->parseddesc->returntype.type;
3094 M_ALD(REG_METHODPTR, rd->argintregs[0],
3095 OFFSET(java_objectheader, vftbl));
3096 M_ALD(REG_PV, REG_METHODPTR, s1);
3097 M_JSR(REG_RA, REG_PV);
3099 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3100 M_LDA(REG_PV, REG_RA, -disp);
3103 case ICMD_INVOKEINTERFACE:
3104 gen_nullptr_check(rd->argintregs[0]);
3107 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3109 codegen_addpatchref(cd, cd->mcodeptr,
3110 PATCHER_invokeinterface, um, 0);
3112 if (opt_showdisassemble) {
3118 d = um->methodref->parseddesc.md->returntype.type;
3121 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3122 sizeof(methodptr*) * lm->class->index;
3124 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3126 d = lm->parseddesc->returntype.type;
3129 M_ALD(REG_METHODPTR, rd->argintregs[0],
3130 OFFSET(java_objectheader, vftbl));
3131 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3132 M_ALD(REG_PV, REG_METHODPTR, s2);
3133 M_JSR(REG_RA, REG_PV);
3135 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3136 M_LDA(REG_PV, REG_RA, -disp);
3140 /* d contains return type */
3142 if (d != TYPE_VOID) {
3143 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3144 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3145 M_INTMOVE(REG_RESULT, s1);
3147 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3148 M_TFLTMOVE(iptr->dst->type, REG_FRESULT, s1);
3150 emit_store(jd, iptr, iptr->dst, s1);
3155 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3156 /* op1: 0 == array, 1 == class */
3157 /* val.a: (classinfo*) superclass */
3159 /* superclass is an interface:
3161 * OK if ((sub == NULL) ||
3162 * (sub->vftbl->interfacetablelength > super->index) &&
3163 * (sub->vftbl->interfacetable[-super->index] != NULL));
3165 * superclass is a class:
3167 * OK if ((sub == NULL) || (0
3168 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3169 * super->vftbl->diffvall));
3172 if (iptr->op1 == 1) {
3174 vftbl_t *supervftbl;
3177 super = (classinfo *) iptr->val.a;
3184 superindex = super->index;
3185 supervftbl = super->vftbl;
3188 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3189 codegen_threadcritrestart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3192 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3194 /* calculate interface checkcast code size */
3198 s2 += (opt_showdisassemble ? 2 : 0);
3200 /* calculate class checkcast code size */
3202 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3204 s3 += (opt_showdisassemble ? 2 : 0);
3206 /* if class is not resolved, check which code to call */
3209 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3212 disp = dseg_adds4(cd, 0); /* super->flags */
3214 codegen_addpatchref(cd, cd->mcodeptr,
3215 PATCHER_checkcast_instanceof_flags,
3216 (constant_classref *) iptr->target,
3219 if (opt_showdisassemble) {
3223 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3224 M_ILD(REG_ITMP2, REG_PV, disp);
3225 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3226 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3230 /* interface checkcast code */
3232 if (!super || super->flags & ACC_INTERFACE) {
3238 codegen_addpatchref(cd, cd->mcodeptr,
3239 PATCHER_checkcast_instanceof_interface,
3240 (constant_classref *) iptr->target,
3243 if (opt_showdisassemble) {
3248 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3249 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3250 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3251 M_BLEZ(REG_ITMP3, 0);
3252 codegen_add_classcastexception_ref(cd, cd->mcodeptr);
3254 M_ALD(REG_ITMP3, REG_ITMP2,
3255 OFFSET(vftbl_t, interfacetable[0]) -
3256 superindex * sizeof(methodptr*));
3257 M_BEQZ(REG_ITMP3, 0);
3258 codegen_add_classcastexception_ref(cd, cd->mcodeptr);
3267 /* class checkcast code */
3269 if (!super || !(super->flags & ACC_INTERFACE)) {
3270 disp = dseg_addaddress(cd, (void *) supervftbl);
3277 codegen_addpatchref(cd, cd->mcodeptr,
3278 PATCHER_checkcast_instanceof_class,
3279 (constant_classref *) iptr->target,
3282 if (opt_showdisassemble) {
3287 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3288 M_ALD(REG_ITMP3, REG_PV, disp);
3289 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3290 codegen_threadcritstart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3292 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3293 /* if (s1 != REG_ITMP1) { */
3294 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3295 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3296 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3297 /* codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase); */
3299 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3301 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3302 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3303 M_ALD(REG_ITMP3, REG_PV, disp);
3304 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3305 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3306 codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3309 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3310 M_BNEZ(REG_ITMP3, 0);
3311 codegen_add_classcastexception_ref(cd, cd->mcodeptr);
3314 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3317 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3318 M_INTMOVE(s1, rd->argintregs[0]);
3320 disp = dseg_addaddress(cd, iptr->val.a);
3322 if (iptr->val.a == NULL) {
3323 codegen_addpatchref(cd, cd->mcodeptr,
3324 PATCHER_builtin_arraycheckcast,
3325 (constant_classref *) iptr->target,
3328 if (opt_showdisassemble) {
3333 M_ALD(rd->argintregs[1], REG_PV, disp);
3334 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3335 M_ALD(REG_ITMP3, REG_PV, disp);
3336 M_JSR(REG_RA, REG_ITMP3);
3339 M_BEQZ(REG_RESULT, 0);
3340 codegen_add_classcastexception_ref(cd, cd->mcodeptr);
3343 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3344 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3347 emit_store(jd, iptr, iptr->dst, d);
3350 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3351 /* op1: 0 == array, 1 == class */
3352 /* val.a: (classinfo*) superclass */
3354 /* superclass is an interface:
3356 * return (sub != NULL) &&
3357 * (sub->vftbl->interfacetablelength > super->index) &&
3358 * (sub->vftbl->interfacetable[-super->index] != NULL);
3360 * superclass is a class:
3362 * return ((sub != NULL) && (0
3363 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3364 * super->vftbl->diffvall));
3369 vftbl_t *supervftbl;
3372 super = (classinfo *) iptr->val.a;
3379 superindex = super->index;
3380 supervftbl = super->vftbl;
3383 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3384 codegen_threadcritrestart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3387 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3388 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3390 M_MOV(s1, REG_ITMP1);
3394 /* calculate interface instanceof code size */
3398 s2 += (opt_showdisassemble ? 2 : 0);
3400 /* calculate class instanceof code size */
3404 s3 += (opt_showdisassemble ? 2 : 0);
3408 /* if class is not resolved, check which code to call */
3411 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3414 disp = dseg_adds4(cd, 0); /* super->flags */
3416 codegen_addpatchref(cd, cd->mcodeptr,
3417 PATCHER_checkcast_instanceof_flags,
3418 (constant_classref *) iptr->target, disp);
3420 if (opt_showdisassemble) {
3424 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3425 M_ILD(REG_ITMP3, REG_PV, disp);
3426 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3427 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3431 /* interface instanceof code */
3433 if (!super || (super->flags & ACC_INTERFACE)) {
3439 codegen_addpatchref(cd, cd->mcodeptr,
3440 PATCHER_checkcast_instanceof_interface,
3441 (constant_classref *) iptr->target, 0);
3443 if (opt_showdisassemble) {
3448 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3449 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3450 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3451 M_BLEZ(REG_ITMP3, 3);
3453 M_ALD(REG_ITMP1, REG_ITMP1,
3454 OFFSET(vftbl_t, interfacetable[0]) -
3455 superindex * sizeof(methodptr*));
3456 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3464 /* class instanceof code */
3466 if (!super || !(super->flags & ACC_INTERFACE)) {
3467 disp = dseg_addaddress(cd, supervftbl);
3474 codegen_addpatchref(cd, cd->mcodeptr,
3475 PATCHER_checkcast_instanceof_class,
3476 (constant_classref *) iptr->target,
3479 if (opt_showdisassemble) {
3484 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3485 M_ALD(REG_ITMP2, REG_PV, disp);
3486 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3487 codegen_threadcritstart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3489 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3490 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3491 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3492 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3493 codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3495 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3496 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3499 emit_store(jd, iptr, iptr->dst, d);
3503 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3504 /* op1 = dimension, val.a = class */
3506 /* check for negative sizes and copy sizes to stack if necessary */
3508 MCODECHECK((iptr->op1 << 1) + 64);
3510 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3511 /* copy SAVEDVAR sizes to stack */
3513 if (src->varkind != ARGVAR) {
3514 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3515 M_LST(s2, REG_SP, s1 * 8);
3519 /* a0 = dimension count */
3521 ICONST(rd->argintregs[0], iptr->op1);
3523 /* is patcher function set? */
3525 if (iptr->val.a == NULL) {
3526 disp = dseg_addaddress(cd, NULL);
3528 codegen_addpatchref(cd, cd->mcodeptr,
3529 PATCHER_builtin_multianewarray,
3530 (constant_classref *) iptr->target,
3533 if (opt_showdisassemble) {
3538 disp = dseg_addaddress(cd, iptr->val.a);
3541 /* a1 = arraydescriptor */
3543 M_ALD(rd->argintregs[1], REG_PV, disp);
3545 /* a2 = pointer to dimensions = stack pointer */
3547 M_INTMOVE(REG_SP, rd->argintregs[2]);
3549 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3550 M_ALD(REG_ITMP3, REG_PV, disp);
3551 M_JSR(REG_RA, REG_ITMP3);
3554 /* check for exception before result assignment */
3556 M_BEQZ(REG_RESULT, 0);
3557 codegen_add_fillinstacktrace_ref(cd, cd->mcodeptr);
3560 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3561 M_INTMOVE(REG_RESULT, d);
3562 emit_store(jd, iptr, iptr->dst, d);
3566 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3570 } /* for instruction */
3572 /* copy values to interface registers */
3574 src = bptr->outstack;
3575 len = bptr->outdepth;
3577 #if defined(ENABLE_LSRA)
3582 if ((src->varkind != STACKVAR)) {
3584 if (IS_FLT_DBL_TYPE(s2)) {
3585 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3586 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3587 M_TFLTMOVE(s2, s1, rd->interfaces[len][s2].regoff);
3590 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3594 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3595 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3596 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3599 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3606 /* At the end of a basic block we may have to append some nops,
3607 because the patcher stub calling code might be longer than the
3608 actual instruction. So codepatching does not change the
3609 following block unintentionally. */
3611 if ((u1 *) cd->mcodeptr < cd->lastmcodeptr) {
3612 while ((u1 *) cd->mcodeptr < cd->lastmcodeptr) {
3617 } /* if (bptr -> flags >= BBREACHED) */
3618 } /* for basic block */
3620 dseg_createlinenumbertable(cd);
3623 /* generate exception and patcher stubs */
3632 savedmcodeptr = NULL;
3634 /* generate exception stubs */
3636 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3637 gen_resolvebranch((u1 *) cd->mcodebase + eref->branchpos,
3639 (u1 *) cd->mcodeptr - cd->mcodebase);
3643 /* Check if the exception is an
3644 ArrayIndexOutOfBoundsException. If so, move index register
3647 if (eref->reg != -1)
3648 M_MOV(eref->reg, REG_ITMP1);
3650 /* calcuate exception address */
3652 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3654 /* move function to call into REG_ITMP3 */
3656 disp = dseg_addaddress(cd, eref->function);
3657 M_ALD(REG_ITMP3, REG_PV, disp);
3659 if (savedmcodeptr != NULL) {
3660 M_BR(savedmcodeptr - cd->mcodeptr);
3664 savedmcodeptr = cd->mcodeptr;
3666 M_MOV(REG_PV, rd->argintregs[0]);
3667 M_MOV(REG_SP, rd->argintregs[1]);
3669 if (m->isleafmethod)
3670 M_MOV(REG_RA, rd->argintregs[2]);
3672 M_ALD(rd->argintregs[2],
3673 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3675 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3676 M_MOV(REG_ITMP1, rd->argintregs[4]);
3678 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3679 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3681 if (m->isleafmethod)
3682 M_AST(REG_RA, REG_SP, 1 * 8);
3684 M_JSR(REG_RA, REG_ITMP3);
3686 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3688 if (m->isleafmethod)
3689 M_ALD(REG_RA, REG_SP, 1 * 8);
3691 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3692 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3694 a = dseg_addaddress(cd, asm_handle_exception);
3695 M_ALD(REG_ITMP3, REG_PV, a);
3702 /* generate code patching stub call code */
3704 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3705 /* check code segment size */
3709 /* Get machine code which is patched back in later. The
3710 call is 2 instruction words long. */
3712 tmpmcodeptr = (u4 *) (cd->mcodebase + pref->branchpos);
3714 /* We need to split this, because an unaligned 8 byte read
3715 causes a SIGSEGV. */
3717 mcode = ((u8) tmpmcodeptr[1] << 32) + (u4) tmpmcodeptr[0];
3719 /* Patch in the call to call the following code (done at
3722 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3723 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3725 disp = (s4) (savedmcodeptr - (tmpmcodeptr + 1));
3727 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3729 new_internalerror("Jump offset is out of range: %d > +/-%d",
3737 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3739 /* create stack frame */
3741 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3743 /* calculate return address and move it onto the stack */
3745 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3746 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3748 /* move pointer to java_objectheader onto stack */
3750 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3751 /* create a virtual java_objectheader */
3753 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3754 disp = dseg_addaddress(cd, NULL); /* vftbl */
3756 M_LDA(REG_ITMP3, REG_PV, disp);
3757 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3762 /* move machine code onto stack */
3764 disp = dseg_adds8(cd, mcode);
3765 M_LLD(REG_ITMP3, REG_PV, disp);
3766 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3768 /* move class/method/field reference onto stack */
3770 disp = dseg_addaddress(cd, pref->ref);
3771 M_ALD(REG_ITMP3, REG_PV, disp);
3772 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3774 /* move data segment displacement onto stack */
3776 disp = dseg_adds4(cd, pref->disp);
3777 M_ILD(REG_ITMP3, REG_PV, disp);
3778 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3780 /* move patcher function pointer onto stack */
3782 disp = dseg_addaddress(cd, pref->patcher);
3783 M_ALD(REG_ITMP3, REG_PV, disp);
3784 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3786 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3787 M_ALD(REG_ITMP3, REG_PV, disp);
3792 /* generate replacement-out stubs */
3797 replacementpoint = jd->code->rplpoints;
3799 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3800 /* check code segment size */
3804 /* note start of stub code */
3806 replacementpoint->outcode = (u1*) (ptrint)((u1*)cd->mcodeptr - cd->mcodebase);
3808 /* make machine code for patching */
3810 tmpmcodeptr = cd->mcodeptr;
3811 cd->mcodeptr = (u4 *) &(replacementpoint->mcode);
3813 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3814 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3816 new_internalerror("Jump offset is out of range: %d > +/-%d",
3821 M_NOP; /* delay slot */
3823 cd->mcodeptr = tmpmcodeptr;
3825 /* create stack frame - 16-byte aligned */
3827 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3829 /* push address of `rplpoint` struct */
3831 disp = dseg_addaddress(cd, replacementpoint);
3832 M_ALD(REG_ITMP3, REG_PV, disp);
3833 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3835 /* jump to replacement function */
3837 disp = dseg_addaddress(cd, asm_replacement_out);
3838 M_ALD(REG_ITMP3, REG_PV, disp);
3840 M_NOP; /* delay slot */
3845 codegen_finish(jd, (s4) ((u1 *) cd->mcodeptr - cd->mcodebase));
3847 /* everything's ok */
3853 /* createcompilerstub **********************************************************
3855 Creates a stub routine which calls the compiler.
3857 *******************************************************************************/
3859 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3860 #define COMPILERSTUB_CODESIZE 4 * 4
3862 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3865 u1 *createcompilerstub(methodinfo *m)
3867 u1 *s; /* memory to hold the stub */
3872 s = CNEW(u1, COMPILERSTUB_SIZE);
3874 /* set data pointer and code pointer */
3877 s = s + COMPILERSTUB_DATASIZE;
3879 /* mark start of dump memory area */
3881 dumpsize = dump_size();
3883 cd = DNEW(codegendata);
3884 cd->mcodeptr = (u4 *) s;
3886 /* Store the methodinfo* in the same place as in the methodheader
3887 for compiled methods. */
3889 d[0] = (ptrint) asm_call_jit_compiler;
3892 M_ALD_INTERN(REG_ITMP1, REG_PV, -1 * SIZEOF_VOID_P); /* method pointer */
3893 M_ALD_INTERN(REG_PV, REG_PV, -2 * SIZEOF_VOID_P); /* pointer to compiler */
3897 md_cacheflush(s, (s4) ((u1 *) cd->mcodeptr - s));
3899 #if defined(ENABLE_STATISTICS)
3901 count_cstub_len += COMPILERSTUB_SIZE;
3904 /* release dump area */
3906 dump_release(dumpsize);
3912 /* createnativestub ************************************************************
3914 Creates a stub routine which calls a native method.
3916 *******************************************************************************/
3918 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
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 */
3966 /* generate stub code */
3968 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
3969 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
3971 /* call trace function */
3973 if (opt_verbosecall) {
3974 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
3976 /* save integer argument registers */
3978 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
3979 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
3980 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
3982 /* save and copy float arguments into integer registers */
3984 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3985 t = md->paramtypes[i].type;
3987 if (IS_FLT_DBL_TYPE(t)) {
3988 if (IS_2_WORD_TYPE(t)) {
3989 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3990 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3992 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3993 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
3998 disp = dseg_addaddress(cd, m);
3999 M_ALD(REG_ITMP1, REG_PV, disp);
4000 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4001 disp = dseg_addaddress(cd, builtin_trace_args);
4002 M_ALD(REG_ITMP3, REG_PV, disp);
4003 M_JSR(REG_RA, REG_ITMP3);
4006 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4007 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4008 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4010 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4011 t = md->paramtypes[i].type;
4013 if (IS_FLT_DBL_TYPE(t)) {
4014 if (IS_2_WORD_TYPE(t)) {
4015 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4017 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4022 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4025 /* get function address (this must happen before the stackframeinfo) */
4027 funcdisp = dseg_addaddress(cd, f);
4029 #if !defined(WITH_STATIC_CLASSPATH)
4031 codegen_addpatchref(cd, cd->mcodeptr, PATCHER_resolve_native, m, funcdisp);
4033 if (opt_showdisassemble) {
4039 /* save integer and float argument registers */
4041 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4042 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4043 M_LST(rd->argintregs[i], REG_SP, j * 8);
4048 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4049 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4050 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4055 /* prepare data structures for native function call */
4057 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4058 M_MOV(REG_PV, rd->argintregs[1]);
4059 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4060 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4061 disp = dseg_addaddress(cd, codegen_start_native_call);
4062 M_ALD(REG_ITMP3, REG_PV, disp);
4063 M_JSR(REG_RA, REG_ITMP3);
4064 M_NOP; /* XXX fill me! */
4066 /* restore integer and float argument registers */
4068 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4069 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4070 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4075 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4076 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4077 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4082 /* copy or spill arguments to new locations */
4084 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4085 t = md->paramtypes[i].type;
4087 if (IS_INT_LNG_TYPE(t)) {
4088 if (!md->params[i].inmemory) {
4089 s1 = rd->argintregs[md->params[i].regoff];
4091 if (!nmd->params[j].inmemory) {
4092 s2 = rd->argintregs[nmd->params[j].regoff];
4095 s2 = nmd->params[j].regoff;
4096 M_AST(s1, REG_SP, s2 * 8);
4100 s1 = md->params[i].regoff + stackframesize;
4101 s2 = nmd->params[j].regoff;
4102 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4103 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4107 if (!md->params[i].inmemory) {
4108 s1 = rd->argfltregs[md->params[i].regoff];
4110 if (!nmd->params[j].inmemory) {
4111 s2 = rd->argfltregs[nmd->params[j].regoff];
4112 M_TFLTMOVE(t, s1, s2);
4114 s2 = nmd->params[j].regoff;
4115 if (IS_2_WORD_TYPE(t))
4116 M_DST(s1, REG_SP, s2 * 8);
4118 M_FST(s1, REG_SP, s2 * 8);
4122 s1 = md->params[i].regoff + stackframesize;
4123 s2 = nmd->params[j].regoff;
4124 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4125 if (IS_2_WORD_TYPE(t))
4126 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4128 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4133 /* put class into second argument register */
4135 if (m->flags & ACC_STATIC) {
4136 disp = dseg_addaddress(cd, m->class);
4137 M_ALD(rd->argintregs[1], REG_PV, disp);
4140 /* put env into first argument register */
4142 disp = dseg_addaddress(cd, _Jv_env);
4143 M_ALD(rd->argintregs[0], REG_PV, disp);
4145 /* do the native function call */
4147 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4148 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4149 M_NOP; /* delay slot */
4151 /* save return value */
4153 if (IS_INT_LNG_TYPE(md->returntype.type))
4154 M_LST(REG_RESULT, REG_SP, 0 * 8);
4156 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4158 /* remove native stackframe info */
4160 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4161 disp = dseg_addaddress(cd, codegen_finish_native_call);
4162 M_ALD(REG_ITMP3, REG_PV, disp);
4163 M_JSR(REG_RA, REG_ITMP3);
4164 M_NOP; /* XXX fill me! */
4166 /* call finished trace function */
4168 if (opt_verbosecall) {
4169 if (IS_INT_LNG_TYPE(md->returntype.type))
4170 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4172 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4174 disp = dseg_addaddress(cd, m);
4175 M_ALD(rd->argintregs[0], REG_PV, disp);
4177 M_MOV(REG_RESULT, rd->argintregs[1]);
4178 M_DMFC1(REG_ITMP1, REG_FRESULT);
4179 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4180 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4182 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4183 M_ALD(REG_ITMP3, REG_PV, disp);
4184 M_JSR(REG_RA, REG_ITMP3);
4188 /* check for exception */
4190 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4191 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4192 M_ALD(REG_ITMP3, REG_PV, disp);
4193 M_JSR(REG_RA, REG_ITMP3);
4195 M_MOV(REG_RESULT, REG_ITMP3);
4197 disp = dseg_addaddress(cd, &_exceptionptr);
4198 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4200 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4202 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4204 /* restore return value */
4206 if (IS_INT_LNG_TYPE(md->returntype.type))
4207 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4209 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4211 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4212 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4214 M_RET(REG_RA); /* return to caller */
4215 M_NOP; /* DELAY SLOT */
4217 /* handle exception */
4219 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4221 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4222 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4223 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4224 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4227 /* generate static stub call code */
4235 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4236 /* Get machine code which is patched back in later. The
4237 call is 2 instruction words long. */
4239 tmpmcodeptr = (u4 *) (cd->mcodebase + pref->branchpos);
4241 /* We need to split this, because an unaligned 8 byte read
4242 causes a SIGSEGV. */
4244 mcode = ((u8) tmpmcodeptr[1] << 32) + (u4) tmpmcodeptr[0];
4246 /* Patch in the call to call the following code (done at
4249 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4250 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4252 M_BRS(savedmcodeptr - (tmpmcodeptr + 1));
4253 M_NOP; /* branch delay slot */
4255 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4257 /* create stack frame */
4259 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4261 /* move return address onto stack */
4263 M_AST(REG_RA, REG_SP, 5 * 8);
4265 /* move pointer to java_objectheader onto stack */
4267 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4268 /* order reversed because of data segment layout */
4270 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4271 disp = dseg_addaddress(cd, NULL); /* vftbl */
4273 M_LDA(REG_ITMP3, REG_PV, disp);
4274 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4276 M_AST(REG_ZERO, REG_SP, 4 * 8);
4279 /* move machine code onto stack */
4281 disp = dseg_adds8(cd, mcode);
4282 M_LLD(REG_ITMP3, REG_PV, disp);
4283 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4285 /* move class/method/field reference onto stack */
4287 disp = dseg_addaddress(cd, pref->ref);
4288 M_ALD(REG_ITMP3, REG_PV, disp);
4289 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4291 /* move data segment displacement onto stack */
4293 disp = dseg_adds4(cd, pref->disp);
4294 M_ILD(REG_ITMP3, REG_PV, disp);
4295 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4297 /* move patcher function pointer onto stack */
4299 disp = dseg_addaddress(cd, pref->patcher);
4300 M_ALD(REG_ITMP3, REG_PV, disp);
4301 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4303 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4304 M_ALD(REG_ITMP3, REG_PV, disp);
4310 codegen_finish(jd, (s4) ((u1 *) cd->mcodeptr - cd->mcodebase));
4312 return jd->code->entrypoint;
4317 * These are local overrides for various environment variables in Emacs.
4318 * Please do not remove this and leave it at the end of the file, where
4319 * Emacs will automagically detect them.
4320 * ---------------------------------------------------------------------
4323 * indent-tabs-mode: t
4327 * vim:noexpandtab:sw=4:ts=4: