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 4937 2006-05-18 14:33:32Z edwin $
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(ENABLE_THREADS)
122 /* space to save argument of monitor_enter */
124 if (checksync && (m->flags & ACC_SYNCHRONIZED))
128 /* adjust frame size for 16 byte alignment */
130 if (parentargs_base & 1)
133 /* create method header */
135 #if SIZEOF_VOID_P == 4
136 (void) dseg_addaddress(cd, m); /* Filler */
138 (void) dseg_addaddress(cd, m); /* MethodPointer */
139 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
141 #if defined(ENABLE_THREADS)
142 /* IsSync contains the offset relative to the stack pointer for the
143 argument of monitor_exit used in the exception handler. Since the
144 offset could be zero and give a wrong meaning of the flag it is
148 if (checksync && (m->flags & ACC_SYNCHRONIZED))
149 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
152 (void) dseg_adds4(cd, 0); /* IsSync */
154 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
155 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
156 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
157 dseg_addlinenumbertablesize(cd);
158 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
160 /* create exception table */
162 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
163 dseg_addtarget(cd, ex->start);
164 dseg_addtarget(cd, ex->end);
165 dseg_addtarget(cd, ex->handler);
166 (void) dseg_addaddress(cd, ex->catchtype.cls);
169 /* create stack frame (if necessary) */
172 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
174 /* save return address and used callee saved registers */
177 if (!m->isleafmethod) {
178 p--; M_AST(REG_RA, REG_SP, p * 8);
180 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
181 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
183 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
184 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
187 /* take arguments out of register or stack frame */
191 for (p = 0, l = 0; p < md->paramcount; p++) {
192 t = md->paramtypes[p].type;
193 var = &(rd->locals[l][t]);
195 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
199 s1 = md->params[p].regoff;
200 if (IS_INT_LNG_TYPE(t)) { /* integer args */
201 if (!md->params[p].inmemory) { /* register arguments */
202 s2 = rd->argintregs[s1];
203 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
204 M_INTMOVE(s2, var->regoff);
205 } else { /* reg arg -> spilled */
206 M_LST(s2, REG_SP, var->regoff * 8);
209 } else { /* stack arguments */
210 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
211 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
212 } else { /* stack arg -> spilled */
213 var->regoff = parentargs_base + s1;
217 } else { /* floating args */
218 if (!md->params[p].inmemory) { /* register arguments */
219 s2 = rd->argfltregs[s1];
220 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
221 if (IS_2_WORD_TYPE(t))
222 M_DMOV(s2, var->regoff);
224 M_FMOV(s2, var->regoff);
225 } else { /* reg arg -> spilled */
226 if (IS_2_WORD_TYPE(t))
227 M_DST(s2, REG_SP, var->regoff * 8);
229 M_FST(s2, REG_SP, var->regoff * 8);
232 } else { /* stack arguments */
233 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
234 if (IS_2_WORD_TYPE(t))
235 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
237 M_FLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
238 } else /* stack-arg -> spilled */
239 var->regoff = parentargs_base + s1;
244 /* call monitorenter function */
246 #if defined(ENABLE_THREADS)
247 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
248 /* stack offset for monitor argument */
252 if (opt_verbosecall) {
253 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
255 for (p = 0; p < INT_ARG_CNT; p++)
256 M_LST(rd->argintregs[p], REG_SP, p * 8);
258 for (p = 0; p < FLT_ARG_CNT; p++)
259 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
261 s1 += INT_ARG_CNT + FLT_ARG_CNT;
264 /* decide which monitor enter function to call */
266 if (m->flags & ACC_STATIC) {
267 p = dseg_addaddress(cd, m->class);
268 M_ALD(rd->argintregs[0], REG_PV, p);
269 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
270 M_ALD(REG_ITMP3, REG_PV, p);
271 M_JSR(REG_RA, REG_ITMP3);
272 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
275 M_BEQZ(rd->argintregs[0], 0);
276 codegen_add_nullpointerexception_ref(cd);
277 p = dseg_addaddress(cd, BUILTIN_monitorenter);
278 M_ALD(REG_ITMP3, REG_PV, p);
279 M_JSR(REG_RA, REG_ITMP3);
280 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
283 if (opt_verbosecall) {
284 for (p = 0; p < INT_ARG_CNT; p++)
285 M_LLD(rd->argintregs[p], REG_SP, p * 8);
287 for (p = 0; p < FLT_ARG_CNT; p++)
288 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
291 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
296 /* copy argument registers to stack and call trace function */
298 if (opt_verbosecall) {
299 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
300 M_AST(REG_RA, REG_SP, 1 * 8);
302 /* save integer argument registers */
304 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
305 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
307 /* save and copy float arguments into integer registers */
309 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
310 t = md->paramtypes[p].type;
312 if (IS_FLT_DBL_TYPE(t)) {
313 if (IS_2_WORD_TYPE(t)) {
314 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
315 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
318 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
319 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
323 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
327 /* save temporary registers for leaf methods */
329 if (m->isleafmethod) {
330 for (p = 0; p < INT_TMP_CNT; p++)
331 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
333 for (p = 0; p < FLT_TMP_CNT; p++)
334 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
337 p = dseg_addaddress(cd, m);
338 M_ALD(REG_ITMP1, REG_PV, p);
339 M_AST(REG_ITMP1, REG_SP, 0 * 8);
340 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
341 M_ALD(REG_ITMP3, REG_PV, disp);
342 M_JSR(REG_RA, REG_ITMP3);
345 M_ALD(REG_RA, REG_SP, 1 * 8);
347 /* restore integer argument registers */
349 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
350 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
352 /* restore float argument registers */
354 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
355 t = md->paramtypes[p].type;
357 if (IS_FLT_DBL_TYPE(t)) {
358 if (IS_2_WORD_TYPE(t)) {
359 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
362 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
366 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
370 /* restore temporary registers for leaf methods */
372 if (m->isleafmethod) {
373 for (p = 0; p < INT_TMP_CNT; p++)
374 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
376 for (p = 0; p < FLT_TMP_CNT; p++)
377 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
380 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
385 /* end of header generation */
387 replacementpoint = jd->code->rplpoints;
389 /* walk through all basic blocks */
391 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
393 /* handle replacement points */
395 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
397 /* 8-byte align pc */
398 if ((ptrint) cd->mcodeptr & 4) {
402 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
405 assert(cd->lastmcodeptr <= cd->mcodeptr);
406 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
409 /* store relative start of block */
411 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
413 if (bptr->flags >= BBREACHED) {
415 /* branch resolving */
418 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
419 gen_resolvebranch(cd->mcodebase + bref->branchpos,
425 /* copy interface registers to their destination */
430 #if defined(ENABLE_LSRA)
432 while (src != NULL) {
434 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
435 /* d = reg_of_var(m, src, REG_ITMP1); */
436 if (!(src->flags & INMEMORY))
440 M_INTMOVE(REG_ITMP1, d);
441 emit_store(jd, NULL, src, d);
447 while (src != NULL) {
449 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
450 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
451 M_INTMOVE(REG_ITMP1, d);
452 emit_store(jd, NULL, src, d);
455 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
456 if ((src->varkind != STACKVAR)) {
458 s1 = rd->interfaces[len][s2].regoff;
459 if (IS_FLT_DBL_TYPE(s2)) {
460 if (rd->interfaces[len][s2].flags & INMEMORY) {
461 if (IS_2_WORD_TYPE(s2))
462 M_DLD(d, REG_SP, s1 * 8);
464 M_FLD(d, REG_SP, s1 * 8);
467 if (IS_2_WORD_TYPE(s2))
474 if (rd->interfaces[len][s2].flags & INMEMORY)
475 M_LLD(d, REG_SP, s1 * 8);
480 emit_store(jd, NULL, src, d);
485 #if defined(ENABLE_LSRA)
488 /* walk through all instructions */
494 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
495 if (iptr->line != currentline) {
496 dseg_addlinenumber(cd, iptr->line);
497 currentline = iptr->line;
500 MCODECHECK(64); /* an instruction usually needs < 64 words */
504 case ICMD_NOP: /* ... ==> ... */
507 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
509 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
511 codegen_add_nullpointerexception_ref(cd);
515 /* constant operations ************************************************/
517 case ICMD_ICONST: /* ... ==> ..., constant */
518 /* op1 = 0, val.i = constant */
520 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
521 ICONST(d, iptr->val.i);
522 emit_store(jd, iptr, iptr->dst, d);
525 case ICMD_LCONST: /* ... ==> ..., constant */
526 /* op1 = 0, val.l = constant */
528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
529 LCONST(d, iptr->val.l);
530 emit_store(jd, iptr, iptr->dst, d);
533 case ICMD_FCONST: /* ... ==> ..., constant */
534 /* op1 = 0, val.f = constant */
536 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
537 disp = dseg_addfloat(cd, iptr->val.f);
538 M_FLD(d, REG_PV, disp);
539 emit_store(jd, iptr, iptr->dst, d);
542 case ICMD_DCONST: /* ... ==> ..., constant */
543 /* op1 = 0, val.d = constant */
545 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
546 disp = dseg_adddouble(cd, iptr->val.d);
547 M_DLD(d, REG_PV, disp);
548 emit_store(jd, iptr, iptr->dst, d);
551 case ICMD_ACONST: /* ... ==> ..., constant */
552 /* op1 = 0, val.a = constant */
554 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
556 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
557 disp = dseg_addaddress(cd, NULL);
559 codegen_addpatchref(cd, PATCHER_aconst,
560 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
563 if (opt_showdisassemble) {
567 M_ALD(d, REG_PV, disp);
570 if (iptr->val.a == NULL) {
571 M_INTMOVE(REG_ZERO, d);
573 disp = dseg_addaddress(cd, iptr->val.a);
574 M_ALD(d, REG_PV, disp);
577 emit_store(jd, iptr, iptr->dst, d);
581 /* load/store operations **********************************************/
583 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
584 /* op1 = local variable */
586 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
587 if ((iptr->dst->varkind == LOCALVAR) &&
588 (iptr->dst->varnum == iptr->op1))
590 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
591 if (var->flags & INMEMORY)
592 #if SIZEOF_VOID_P == 8
593 M_LLD(d, REG_SP, var->regoff * 8);
595 M_ILD(d, REG_SP, var->regoff * 8);
598 M_INTMOVE(var->regoff,d);
599 emit_store(jd, iptr, iptr->dst, d);
602 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
603 /* op1 = local variable */
605 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
606 if ((iptr->dst->varkind == LOCALVAR) &&
607 (iptr->dst->varnum == iptr->op1))
609 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
610 if (var->flags & INMEMORY)
611 M_LLD(d, REG_SP, var->regoff * 8);
613 M_INTMOVE(var->regoff,d);
614 emit_store(jd, iptr, iptr->dst, d);
617 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
618 /* op1 = local variable */
620 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
621 if ((iptr->dst->varkind == LOCALVAR) &&
622 (iptr->dst->varnum == iptr->op1))
624 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
625 if (var->flags & INMEMORY)
626 M_ALD(d, REG_SP, var->regoff * 8);
628 M_INTMOVE(var->regoff,d);
629 emit_store(jd, iptr, iptr->dst, d);
632 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
633 /* op1 = local variable */
635 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
636 if ((iptr->dst->varkind == LOCALVAR) &&
637 (iptr->dst->varnum == iptr->op1))
639 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
640 if (var->flags & INMEMORY)
641 M_FLD(d, REG_SP, var->regoff * 8);
643 M_FMOV(var->regoff, d);
644 emit_store(jd, iptr, iptr->dst, d);
647 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
648 /* op1 = local variable */
650 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
651 if ((iptr->dst->varkind == LOCALVAR) &&
652 (iptr->dst->varnum == iptr->op1))
654 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
655 if (var->flags & INMEMORY)
656 M_DLD(d, REG_SP, var->regoff * 8);
658 M_DMOV(var->regoff, d);
659 emit_store(jd, iptr, iptr->dst, d);
663 case ICMD_ISTORE: /* ..., value ==> ... */
664 /* op1 = local variable */
666 if ((src->varkind == LOCALVAR) &&
667 (src->varnum == iptr->op1))
669 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
670 if (var->flags & INMEMORY) {
671 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
672 #if SIZEOF_VOID_P == 8
673 M_LST(s1, REG_SP, var->regoff * 8);
675 M_IST(s1, REG_SP, var->regoff * 8);
678 s1 = emit_load_s1(jd, iptr, src, var->regoff);
679 M_INTMOVE(s1, var->regoff);
683 case ICMD_LSTORE: /* ..., value ==> ... */
684 /* op1 = local variable */
686 if ((src->varkind == LOCALVAR) &&
687 (src->varnum == iptr->op1))
689 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
690 if (var->flags & INMEMORY) {
691 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
692 M_LST(s1, REG_SP, var->regoff * 8);
694 s1 = emit_load_s1(jd, iptr, src, var->regoff);
695 M_INTMOVE(s1, var->regoff);
699 case ICMD_ASTORE: /* ..., value ==> ... */
700 /* op1 = local variable */
702 if ((src->varkind == LOCALVAR) &&
703 (src->varnum == iptr->op1))
705 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
706 if (var->flags & INMEMORY) {
707 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
708 M_AST(s1, REG_SP, var->regoff * 8);
710 s1 = emit_load_s1(jd, iptr, src, var->regoff);
711 M_INTMOVE(s1, var->regoff);
715 case ICMD_FSTORE: /* ..., value ==> ... */
716 /* op1 = local variable */
718 if ((src->varkind == LOCALVAR) &&
719 (src->varnum == iptr->op1))
721 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
722 if (var->flags & INMEMORY) {
723 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
724 M_FST(s1, REG_SP, var->regoff * 8);
726 s1 = emit_load_s1(jd, iptr, src, var->regoff);
727 M_FMOV(s1, var->regoff);
731 case ICMD_DSTORE: /* ..., value ==> ... */
732 /* op1 = local variable */
734 if ((src->varkind == LOCALVAR) &&
735 (src->varnum == iptr->op1))
737 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
738 if (var->flags & INMEMORY) {
739 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
740 M_DST(s1, REG_SP, var->regoff * 8);
742 s1 = emit_load_s1(jd, iptr, src, var->regoff);
743 M_DMOV(s1, var->regoff);
748 /* pop/dup/swap operations ********************************************/
750 /* attention: double and longs are only one entry in CACAO ICMDs */
752 case ICMD_POP: /* ..., value ==> ... */
753 case ICMD_POP2: /* ..., value, value ==> ... */
756 case ICMD_DUP: /* ..., a ==> ..., a, a */
757 M_COPY(src, iptr->dst);
760 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
762 M_COPY(src, iptr->dst);
763 M_COPY(src->prev, iptr->dst->prev);
764 M_COPY(iptr->dst, iptr->dst->prev->prev);
767 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
769 M_COPY(src, iptr->dst);
770 M_COPY(src->prev, iptr->dst->prev);
771 M_COPY(src->prev->prev, iptr->dst->prev->prev);
772 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
775 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
777 M_COPY(src, iptr->dst);
778 M_COPY(src->prev, iptr->dst->prev);
781 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
783 M_COPY(src, iptr->dst);
784 M_COPY(src->prev, iptr->dst->prev);
785 M_COPY(src->prev->prev, iptr->dst->prev->prev);
786 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
787 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
790 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
792 M_COPY(src, iptr->dst);
793 M_COPY(src->prev, iptr->dst->prev);
794 M_COPY(src->prev->prev, iptr->dst->prev->prev);
795 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
796 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
797 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
800 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
802 M_COPY(src, iptr->dst->prev);
803 M_COPY(src->prev, iptr->dst);
807 /* integer operations *************************************************/
809 case ICMD_INEG: /* ..., value ==> ..., - value */
811 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
812 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
813 M_ISUB(REG_ZERO, s1, d);
814 emit_store(jd, iptr, iptr->dst, d);
817 case ICMD_LNEG: /* ..., value ==> ..., - value */
819 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
820 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
821 M_LSUB(REG_ZERO, s1, d);
822 emit_store(jd, iptr, iptr->dst, d);
825 case ICMD_I2L: /* ..., value ==> ..., value */
827 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
828 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
830 emit_store(jd, iptr, iptr->dst, d);
833 case ICMD_L2I: /* ..., value ==> ..., value */
835 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
836 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
837 M_ISLL_IMM(s1, 0, d );
838 emit_store(jd, iptr, iptr->dst, d);
841 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
843 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
844 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
845 M_LSLL_IMM(s1, 56, d);
846 M_LSRA_IMM( d, 56, d);
847 emit_store(jd, iptr, iptr->dst, d);
850 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
852 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
853 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
855 emit_store(jd, iptr, iptr->dst, d);
858 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
860 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
861 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
862 M_LSLL_IMM(s1, 48, d);
863 M_LSRA_IMM( d, 48, d);
864 emit_store(jd, iptr, iptr->dst, d);
868 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
870 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
871 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
872 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
874 emit_store(jd, iptr, iptr->dst, d);
877 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
878 /* val.i = constant */
880 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
881 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
882 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
883 M_IADD_IMM(s1, iptr->val.i, d);
885 ICONST(REG_ITMP2, iptr->val.i);
886 M_IADD(s1, REG_ITMP2, d);
888 emit_store(jd, iptr, iptr->dst, d);
891 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
893 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
894 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
895 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
897 emit_store(jd, iptr, iptr->dst, d);
900 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
901 /* val.l = constant */
903 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
904 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
905 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
906 M_LADD_IMM(s1, iptr->val.l, d);
908 LCONST(REG_ITMP2, iptr->val.l);
909 M_LADD(s1, REG_ITMP2, d);
911 emit_store(jd, iptr, iptr->dst, d);
914 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
916 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
917 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
918 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
920 emit_store(jd, iptr, iptr->dst, d);
923 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
924 /* val.i = constant */
926 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
927 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
928 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
929 M_IADD_IMM(s1, -iptr->val.i, d);
931 ICONST(REG_ITMP2, iptr->val.i);
932 M_ISUB(s1, REG_ITMP2, d);
934 emit_store(jd, iptr, iptr->dst, d);
937 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
939 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
940 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
941 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
943 emit_store(jd, iptr, iptr->dst, d);
946 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
947 /* val.l = constant */
949 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
950 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
951 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
952 M_LADD_IMM(s1, -iptr->val.l, d);
954 LCONST(REG_ITMP2, iptr->val.l);
955 M_LSUB(s1, REG_ITMP2, d);
957 emit_store(jd, iptr, iptr->dst, d);
960 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
962 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
963 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
964 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
969 emit_store(jd, iptr, iptr->dst, d);
972 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
973 /* val.i = constant */
975 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
976 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
977 ICONST(REG_ITMP2, iptr->val.i);
978 M_IMUL(s1, REG_ITMP2);
982 emit_store(jd, iptr, iptr->dst, d);
985 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
987 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
988 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
989 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
994 emit_store(jd, iptr, iptr->dst, d);
997 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
998 /* val.l = constant */
1000 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1001 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1002 LCONST(REG_ITMP2, iptr->val.l);
1003 M_LMUL(s1, REG_ITMP2);
1007 emit_store(jd, iptr, iptr->dst, d);
1010 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1012 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1013 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1014 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1020 emit_store(jd, iptr, iptr->dst, d);
1023 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1025 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1026 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1027 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1033 emit_store(jd, iptr, iptr->dst, d);
1036 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1038 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1039 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1040 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1046 emit_store(jd, iptr, iptr->dst, d);
1049 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1051 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1052 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1053 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1059 emit_store(jd, iptr, iptr->dst, d);
1062 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1063 case ICMD_LDIVPOW2: /* val.i = constant */
1065 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1066 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1067 M_LSRA_IMM(s1, 63, REG_ITMP2);
1068 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1069 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1070 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1071 emit_store(jd, iptr, iptr->dst, d);
1074 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1076 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1077 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1078 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1080 emit_store(jd, iptr, iptr->dst, d);
1083 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1084 /* val.i = constant */
1086 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1087 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1088 M_ISLL_IMM(s1, iptr->val.i, d);
1089 emit_store(jd, iptr, iptr->dst, d);
1092 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1094 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1095 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1096 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1098 emit_store(jd, iptr, iptr->dst, d);
1101 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1102 /* val.i = constant */
1104 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1105 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1106 M_ISRA_IMM(s1, iptr->val.i, d);
1107 emit_store(jd, iptr, iptr->dst, d);
1110 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1112 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1113 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1114 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1116 emit_store(jd, iptr, iptr->dst, d);
1119 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1120 /* val.i = constant */
1122 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1123 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1124 M_ISRL_IMM(s1, iptr->val.i, d);
1125 emit_store(jd, iptr, iptr->dst, d);
1128 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1130 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1131 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1132 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1134 emit_store(jd, iptr, iptr->dst, d);
1137 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1138 /* val.i = constant */
1140 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1141 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1142 M_LSLL_IMM(s1, iptr->val.i, d);
1143 emit_store(jd, iptr, iptr->dst, d);
1146 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1148 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1149 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1150 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1152 emit_store(jd, iptr, iptr->dst, d);
1155 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1156 /* val.i = constant */
1158 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1159 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1160 M_LSRA_IMM(s1, iptr->val.i, d);
1161 emit_store(jd, iptr, iptr->dst, d);
1164 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1166 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1167 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1168 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1170 emit_store(jd, iptr, iptr->dst, d);
1173 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1174 /* val.i = constant */
1176 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1177 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1178 M_LSRL_IMM(s1, iptr->val.i, d);
1179 emit_store(jd, iptr, iptr->dst, d);
1182 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1185 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1186 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1187 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1189 emit_store(jd, iptr, iptr->dst, d);
1192 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1193 /* val.i = constant */
1195 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1196 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1197 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1198 M_AND_IMM(s1, iptr->val.i, d);
1200 ICONST(REG_ITMP2, iptr->val.i);
1201 M_AND(s1, REG_ITMP2, d);
1203 emit_store(jd, iptr, iptr->dst, d);
1206 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1207 /* val.i = constant */
1209 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1210 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1212 M_MOV(s1, REG_ITMP1);
1215 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1216 M_AND_IMM(s1, iptr->val.i, d);
1219 M_ISUB(REG_ZERO, s1, d);
1220 M_AND_IMM(d, iptr->val.i, d);
1222 ICONST(REG_ITMP2, iptr->val.i);
1223 M_AND(s1, REG_ITMP2, d);
1226 M_ISUB(REG_ZERO, s1, d);
1227 M_AND(d, REG_ITMP2, d);
1229 M_ISUB(REG_ZERO, d, d);
1230 emit_store(jd, iptr, iptr->dst, d);
1233 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1234 /* val.l = constant */
1236 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1237 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1238 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1239 M_AND_IMM(s1, iptr->val.l, d);
1241 LCONST(REG_ITMP2, iptr->val.l);
1242 M_AND(s1, REG_ITMP2, d);
1244 emit_store(jd, iptr, iptr->dst, d);
1247 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1248 /* val.l = constant */
1250 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1251 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1253 M_MOV(s1, REG_ITMP1);
1256 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1257 M_AND_IMM(s1, iptr->val.l, d);
1260 M_LSUB(REG_ZERO, s1, d);
1261 M_AND_IMM(d, iptr->val.l, d);
1263 LCONST(REG_ITMP2, iptr->val.l);
1264 M_AND(s1, REG_ITMP2, d);
1267 M_LSUB(REG_ZERO, s1, d);
1268 M_AND(d, REG_ITMP2, d);
1270 M_LSUB(REG_ZERO, d, d);
1271 emit_store(jd, iptr, iptr->dst, d);
1274 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1277 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1278 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1279 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1281 emit_store(jd, iptr, iptr->dst, d);
1284 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1285 /* val.i = constant */
1287 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1288 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1289 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1290 M_OR_IMM(s1, iptr->val.i, d);
1292 ICONST(REG_ITMP2, iptr->val.i);
1293 M_OR(s1, REG_ITMP2, d);
1295 emit_store(jd, iptr, iptr->dst, d);
1298 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1299 /* val.l = constant */
1301 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1302 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1303 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1304 M_OR_IMM(s1, iptr->val.l, d);
1306 LCONST(REG_ITMP2, iptr->val.l);
1307 M_OR(s1, REG_ITMP2, d);
1309 emit_store(jd, iptr, iptr->dst, d);
1312 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1315 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1316 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1317 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1319 emit_store(jd, iptr, iptr->dst, d);
1322 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1323 /* val.i = constant */
1325 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1326 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1327 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1328 M_XOR_IMM(s1, iptr->val.i, d);
1330 ICONST(REG_ITMP2, iptr->val.i);
1331 M_XOR(s1, REG_ITMP2, d);
1333 emit_store(jd, iptr, iptr->dst, d);
1336 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1337 /* val.l = constant */
1339 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1340 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1341 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1342 M_XOR_IMM(s1, iptr->val.l, d);
1344 LCONST(REG_ITMP2, iptr->val.l);
1345 M_XOR(s1, REG_ITMP2, d);
1347 emit_store(jd, iptr, iptr->dst, d);
1351 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1353 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1354 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1355 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1356 M_CMPLT(s1, s2, REG_ITMP3);
1357 M_CMPLT(s2, s1, REG_ITMP1);
1358 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1359 emit_store(jd, iptr, iptr->dst, d);
1363 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1364 /* op1 = variable, val.i = constant */
1366 var = &(rd->locals[iptr->op1][TYPE_INT]);
1367 if (var->flags & INMEMORY) {
1369 M_LLD(s1, REG_SP, var->regoff * 8);
1372 M_IADD_IMM(s1, iptr->val.i, s1);
1373 if (var->flags & INMEMORY)
1374 M_LST(s1, REG_SP, var->regoff * 8);
1378 /* floating operations ************************************************/
1380 case ICMD_FNEG: /* ..., value ==> ..., - value */
1382 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1383 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1385 emit_store(jd, iptr, iptr->dst, d);
1388 case ICMD_DNEG: /* ..., value ==> ..., - value */
1390 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1391 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1393 emit_store(jd, iptr, iptr->dst, d);
1396 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1398 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1399 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1400 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1402 emit_store(jd, iptr, iptr->dst, d);
1405 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1407 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1408 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1409 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1411 emit_store(jd, iptr, iptr->dst, d);
1414 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1416 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1417 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1418 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1420 emit_store(jd, iptr, iptr->dst, d);
1423 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1425 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1426 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1427 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1429 emit_store(jd, iptr, iptr->dst, d);
1432 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1434 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1435 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1436 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1438 emit_store(jd, iptr, iptr->dst, d);
1441 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1443 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1444 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1445 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1447 emit_store(jd, iptr, iptr->dst, d);
1450 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1452 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1453 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1454 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1456 emit_store(jd, iptr, iptr->dst, d);
1459 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1461 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1462 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1463 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1465 emit_store(jd, iptr, iptr->dst, d);
1469 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1471 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1472 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1473 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1474 M_FDIV(s1,s2, REG_FTMP3);
1475 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1476 M_CVTLF(REG_FTMP3, REG_FTMP3);
1477 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1478 M_FSUB(s1, REG_FTMP3, d);
1479 emit_store(jd, iptr, iptr->dst, d);
1482 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1484 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1485 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1486 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1487 M_DDIV(s1,s2, REG_FTMP3);
1488 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1489 M_CVTLD(REG_FTMP3, REG_FTMP3);
1490 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1491 M_DSUB(s1, REG_FTMP3, d);
1492 emit_store(jd, iptr, iptr->dst, d);
1496 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1498 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1499 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1502 emit_store(jd, iptr, iptr->dst, d);
1505 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1507 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1508 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1511 emit_store(jd, iptr, iptr->dst, d);
1515 /* XXX these do not work correctly */
1517 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1519 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1520 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1521 M_TRUNCFI(s1, REG_FTMP1);
1522 M_MOVDI(REG_FTMP1, d);
1524 emit_store(jd, iptr, iptr->dst, d);
1527 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1529 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1530 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1531 M_TRUNCDI(s1, REG_FTMP1);
1532 M_MOVDI(REG_FTMP1, d);
1534 emit_store(jd, iptr, iptr->dst, d);
1537 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1539 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1540 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1541 M_TRUNCFL(s1, REG_FTMP1);
1542 M_MOVDL(REG_FTMP1, d);
1544 emit_store(jd, iptr, iptr->dst, d);
1547 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1549 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1550 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1551 M_TRUNCDL(s1, REG_FTMP1);
1552 M_MOVDL(REG_FTMP1, d);
1554 emit_store(jd, iptr, iptr->dst, d);
1558 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1560 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1561 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1563 emit_store(jd, iptr, iptr->dst, d);
1566 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1568 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1569 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1571 emit_store(jd, iptr, iptr->dst, d);
1574 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1576 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1577 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1578 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1581 M_LADD_IMM(REG_ZERO, 1, d);
1585 M_LSUB_IMM(REG_ZERO, 1, d);
1586 M_CMOVT(REG_ZERO, d);
1587 emit_store(jd, iptr, iptr->dst, d);
1590 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1592 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1593 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1594 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1597 M_LADD_IMM(REG_ZERO, 1, d);
1601 M_LSUB_IMM(REG_ZERO, 1, d);
1602 M_CMOVT(REG_ZERO, d);
1603 emit_store(jd, iptr, iptr->dst, d);
1606 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1608 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1609 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1610 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1613 M_LSUB_IMM(REG_ZERO, 1, d);
1617 M_LADD_IMM(REG_ZERO, 1, d);
1618 M_CMOVT(REG_ZERO, d);
1619 emit_store(jd, iptr, iptr->dst, d);
1622 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1624 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1625 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1626 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1629 M_LSUB_IMM(REG_ZERO, 1, d);
1633 M_LADD_IMM(REG_ZERO, 1, d);
1634 M_CMOVT(REG_ZERO, d);
1635 emit_store(jd, iptr, iptr->dst, d);
1639 /* memory operations **************************************************/
1641 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1643 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1644 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1645 gen_nullptr_check(s1);
1646 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1647 emit_store(jd, iptr, iptr->dst, d);
1650 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1652 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1653 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1654 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1655 if (iptr->op1 == 0) {
1656 gen_nullptr_check(s1);
1659 M_AADD(s2, s1, REG_ITMP3);
1660 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1661 emit_store(jd, iptr, iptr->dst, d);
1664 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1666 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1667 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1668 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1669 if (iptr->op1 == 0) {
1670 gen_nullptr_check(s1);
1673 M_AADD(s2, s1, REG_ITMP3);
1674 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1675 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1676 emit_store(jd, iptr, iptr->dst, d);
1679 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1681 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1682 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1683 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1684 if (iptr->op1 == 0) {
1685 gen_nullptr_check(s1);
1688 M_AADD(s2, s1, REG_ITMP3);
1689 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1690 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1691 emit_store(jd, iptr, iptr->dst, d);
1694 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1696 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1697 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1698 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1699 if (iptr->op1 == 0) {
1700 gen_nullptr_check(s1);
1703 M_ASLL_IMM(s2, 2, REG_ITMP3);
1704 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1705 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1706 emit_store(jd, iptr, iptr->dst, d);
1709 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1711 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1713 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1714 if (iptr->op1 == 0) {
1715 gen_nullptr_check(s1);
1718 M_ASLL_IMM(s2, 3, REG_ITMP3);
1719 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1720 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1721 emit_store(jd, iptr, iptr->dst, d);
1724 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1726 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1727 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1728 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1729 if (iptr->op1 == 0) {
1730 gen_nullptr_check(s1);
1733 M_ASLL_IMM(s2, 2, REG_ITMP3);
1734 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1735 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1736 emit_store(jd, iptr, iptr->dst, d);
1739 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1741 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1742 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1743 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1744 if (iptr->op1 == 0) {
1745 gen_nullptr_check(s1);
1748 M_ASLL_IMM(s2, 3, REG_ITMP3);
1749 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1750 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1751 emit_store(jd, iptr, iptr->dst, d);
1754 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1756 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1757 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1758 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1759 if (iptr->op1 == 0) {
1760 gen_nullptr_check(s1);
1763 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1764 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1765 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1766 emit_store(jd, iptr, iptr->dst, d);
1770 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1772 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1773 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1774 if (iptr->op1 == 0) {
1775 gen_nullptr_check(s1);
1778 M_AADD(s2, s1, REG_ITMP1);
1779 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1780 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1783 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1784 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1786 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1787 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1788 if (iptr->op1 == 0) {
1789 gen_nullptr_check(s1);
1792 M_AADD(s2, s1, REG_ITMP1);
1793 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1794 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1795 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1798 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1800 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1801 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1802 if (iptr->op1 == 0) {
1803 gen_nullptr_check(s1);
1806 M_ASLL_IMM(s2, 2, REG_ITMP2);
1807 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1808 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1809 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1812 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1814 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1815 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1816 if (iptr->op1 == 0) {
1817 gen_nullptr_check(s1);
1820 M_ASLL_IMM(s2, 3, REG_ITMP2);
1821 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1822 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1823 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1826 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1828 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1829 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1830 if (iptr->op1 == 0) {
1831 gen_nullptr_check(s1);
1834 M_ASLL_IMM(s2, 2, REG_ITMP2);
1835 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1836 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1837 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1840 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1842 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1843 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1844 if (iptr->op1 == 0) {
1845 gen_nullptr_check(s1);
1848 M_ASLL_IMM(s2, 3, REG_ITMP2);
1849 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1850 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1851 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1855 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1857 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1858 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1859 if (iptr->op1 == 0) {
1860 gen_nullptr_check(s1);
1863 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1865 M_MOV(s1, rd->argintregs[0]);
1866 M_MOV(s3, rd->argintregs[1]);
1867 disp = dseg_addaddress(cd, BUILTIN_canstore);
1868 M_ALD(REG_ITMP3, REG_PV, disp);
1869 M_JSR(REG_RA, REG_ITMP3);
1872 M_BEQZ(REG_RESULT, 0);
1873 codegen_add_arraystoreexception_ref(cd);
1876 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1877 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1878 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1879 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1880 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1881 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1885 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1887 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1888 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1889 if (iptr->op1 == 0) {
1890 gen_nullptr_check(s1);
1893 M_AADD(s2, s1, REG_ITMP1);
1894 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1897 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1898 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1900 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1901 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1902 if (iptr->op1 == 0) {
1903 gen_nullptr_check(s1);
1906 M_AADD(s2, s1, REG_ITMP1);
1907 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1908 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1911 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1913 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1914 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1915 if (iptr->op1 == 0) {
1916 gen_nullptr_check(s1);
1919 M_ASLL_IMM(s2, 2, REG_ITMP2);
1920 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1921 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1924 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1926 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1927 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1928 if (iptr->op1 == 0) {
1929 gen_nullptr_check(s1);
1932 M_ASLL_IMM(s2, 3, REG_ITMP2);
1933 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1934 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1937 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1939 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1940 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1941 if (iptr->op1 == 0) {
1942 gen_nullptr_check(s1);
1945 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1946 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1947 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1951 case ICMD_GETSTATIC: /* ... ==> ..., value */
1952 /* op1 = type, val.a = field address */
1954 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1955 disp = dseg_addaddress(cd, NULL);
1957 codegen_addpatchref(cd, PATCHER_get_putstatic,
1958 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1960 if (opt_showdisassemble) {
1965 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1967 disp = dseg_addaddress(cd, &(fi->value));
1969 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1970 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1972 if (opt_showdisassemble) {
1978 M_ALD(REG_ITMP1, REG_PV, disp);
1979 switch (iptr->op1) {
1981 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1982 M_ILD_INTERN(d, REG_ITMP1, 0);
1983 emit_store(jd, iptr, iptr->dst, d);
1986 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1987 M_LLD_INTERN(d, REG_ITMP1, 0);
1988 emit_store(jd, iptr, iptr->dst, d);
1991 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1992 M_ALD_INTERN(d, REG_ITMP1, 0);
1993 emit_store(jd, iptr, iptr->dst, d);
1996 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1997 M_FLD_INTERN(d, REG_ITMP1, 0);
1998 emit_store(jd, iptr, iptr->dst, d);
2001 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2002 M_DLD_INTERN(d, REG_ITMP1, 0);
2003 emit_store(jd, iptr, iptr->dst, d);
2008 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2009 /* op1 = type, val.a = field address */
2011 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2012 disp = dseg_addaddress(cd, NULL);
2014 codegen_addpatchref(cd, PATCHER_get_putstatic,
2015 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2017 if (opt_showdisassemble) {
2022 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2024 disp = dseg_addaddress(cd, &(fi->value));
2026 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2027 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2029 if (opt_showdisassemble) {
2035 M_ALD(REG_ITMP1, REG_PV, disp);
2036 switch (iptr->op1) {
2038 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2039 M_IST_INTERN(s2, REG_ITMP1, 0);
2042 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2043 M_LST_INTERN(s2, REG_ITMP1, 0);
2046 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2047 M_AST_INTERN(s2, REG_ITMP1, 0);
2050 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2051 M_FST_INTERN(s2, REG_ITMP1, 0);
2054 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2055 M_DST_INTERN(s2, REG_ITMP1, 0);
2060 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2061 /* val = value (in current instruction) */
2062 /* op1 = type, val.a = field address (in */
2063 /* following NOP) */
2065 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2066 disp = dseg_addaddress(cd, NULL);
2068 codegen_addpatchref(cd, PATCHER_get_putstatic,
2069 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2071 if (opt_showdisassemble) {
2076 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2078 disp = dseg_addaddress(cd, &(fi->value));
2080 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2081 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2083 if (opt_showdisassemble) {
2089 M_ALD(REG_ITMP1, REG_PV, disp);
2090 switch (iptr->op1) {
2092 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2095 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2098 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2101 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2104 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2110 case ICMD_GETFIELD: /* ... ==> ..., value */
2111 /* op1 = type, val.i = field offset */
2113 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2114 gen_nullptr_check(s1);
2116 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2117 codegen_addpatchref(cd, PATCHER_get_putfield,
2118 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2120 if (opt_showdisassemble) {
2127 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2130 switch (iptr->op1) {
2132 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2134 emit_store(jd, iptr, iptr->dst, d);
2137 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2139 emit_store(jd, iptr, iptr->dst, d);
2142 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2144 emit_store(jd, iptr, iptr->dst, d);
2147 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2149 emit_store(jd, iptr, iptr->dst, d);
2152 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2154 emit_store(jd, iptr, iptr->dst, d);
2159 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2160 /* op1 = type, val.a = field address */
2162 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2163 gen_nullptr_check(s1);
2165 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2166 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2168 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2171 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2172 codegen_addpatchref(cd, PATCHER_get_putfield,
2173 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2175 if (opt_showdisassemble) {
2182 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2185 switch (iptr->op1) {
2204 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2205 /* val = value (in current instruction) */
2206 /* op1 = type, val.a = field address (in */
2207 /* following NOP) */
2209 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2210 gen_nullptr_check(s1);
2212 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2213 codegen_addpatchref(cd, PATCHER_get_putfield,
2214 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2216 if (opt_showdisassemble) {
2223 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2226 switch (iptr[1].op1) {
2228 M_IST(REG_ZERO, s1, a);
2231 M_LST(REG_ZERO, s1, a);
2234 M_AST(REG_ZERO, s1, a);
2237 M_FST(REG_ZERO, s1, a);
2240 M_DST(REG_ZERO, s1, a);
2246 /* branch operations **************************************************/
2248 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2250 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2251 M_INTMOVE(s1, REG_ITMP1_XPTR);
2253 #ifdef ENABLE_VERIFIER
2255 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2256 (unresolved_class *) iptr->val.a, 0);
2258 if (opt_showdisassemble) {
2262 #endif /* ENABLE_VERIFIER */
2264 disp = dseg_addaddress(cd, asm_handle_exception);
2265 M_ALD(REG_ITMP2, REG_PV, disp);
2266 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2268 M_NOP; /* nop ensures that XPC is less than the end */
2269 /* of basic block */
2273 case ICMD_GOTO: /* ... ==> ... */
2274 /* op1 = target JavaVM pc */
2276 codegen_addreference(cd, (basicblock *) iptr->target);
2281 case ICMD_JSR: /* ... ==> ... */
2282 /* op1 = target JavaVM pc */
2284 dseg_addtarget(cd, (basicblock *) iptr->target);
2285 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2286 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2290 case ICMD_RET: /* ... ==> ... */
2291 /* op1 = local variable */
2292 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2293 if (var->flags & INMEMORY) {
2294 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2302 case ICMD_IFNULL: /* ..., value ==> ... */
2303 /* op1 = target JavaVM pc */
2305 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2307 codegen_addreference(cd, (basicblock *) iptr->target);
2311 case ICMD_IFNONNULL: /* ..., value ==> ... */
2312 /* op1 = target JavaVM pc */
2314 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2316 codegen_addreference(cd, (basicblock *) iptr->target);
2320 case ICMD_IFEQ: /* ..., 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) {
2327 ICONST(REG_ITMP2, iptr->val.i);
2328 M_BEQ(s1, REG_ITMP2, 0);
2330 codegen_addreference(cd, (basicblock *) iptr->target);
2334 case ICMD_IFLT: /* ..., value ==> ... */
2335 /* op1 = target JavaVM pc, val.i = constant */
2337 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2338 if (iptr->val.i == 0) {
2341 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2342 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2344 ICONST(REG_ITMP2, iptr->val.i);
2345 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2347 M_BNEZ(REG_ITMP1, 0);
2349 codegen_addreference(cd, (basicblock *) iptr->target);
2353 case ICMD_IFLE: /* ..., value ==> ... */
2354 /* op1 = target JavaVM pc, val.i = constant */
2356 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2357 if (iptr->val.i == 0) {
2361 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2362 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2363 M_BNEZ(REG_ITMP1, 0);
2366 ICONST(REG_ITMP2, iptr->val.i);
2367 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2368 M_BEQZ(REG_ITMP1, 0);
2371 codegen_addreference(cd, (basicblock *) iptr->target);
2375 case ICMD_IFNE: /* ..., value ==> ... */
2376 /* op1 = target JavaVM pc, val.i = constant */
2378 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2379 if (iptr->val.i == 0) {
2383 ICONST(REG_ITMP2, iptr->val.i);
2384 M_BNE(s1, REG_ITMP2, 0);
2386 codegen_addreference(cd, (basicblock *) iptr->target);
2390 case ICMD_IFGT: /* ..., value ==> ... */
2391 /* op1 = target JavaVM pc, val.i = constant */
2393 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2394 if (iptr->val.i == 0) {
2398 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2399 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2400 M_BEQZ(REG_ITMP1, 0);
2403 ICONST(REG_ITMP2, iptr->val.i);
2404 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2405 M_BNEZ(REG_ITMP1, 0);
2408 codegen_addreference(cd, (basicblock *) iptr->target);
2412 case ICMD_IFGE: /* ..., value ==> ... */
2413 /* op1 = target JavaVM pc, val.i = constant */
2415 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2416 if (iptr->val.i == 0) {
2420 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2421 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2424 ICONST(REG_ITMP2, iptr->val.i);
2425 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2427 M_BEQZ(REG_ITMP1, 0);
2429 codegen_addreference(cd, (basicblock *) iptr->target);
2433 case ICMD_IF_LEQ: /* ..., value ==> ... */
2434 /* op1 = target JavaVM pc, val.l = constant */
2436 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2437 if (iptr->val.l == 0) {
2441 LCONST(REG_ITMP2, iptr->val.l);
2442 M_BEQ(s1, REG_ITMP2, 0);
2444 codegen_addreference(cd, (basicblock *) iptr->target);
2448 case ICMD_IF_LLT: /* ..., value ==> ... */
2449 /* op1 = target JavaVM pc, val.l = constant */
2451 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2452 if (iptr->val.l == 0) {
2456 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2457 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2460 LCONST(REG_ITMP2, iptr->val.l);
2461 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2463 M_BNEZ(REG_ITMP1, 0);
2465 codegen_addreference(cd, (basicblock *) iptr->target);
2469 case ICMD_IF_LLE: /* ..., value ==> ... */
2470 /* op1 = target JavaVM pc, val.l = constant */
2472 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2473 if (iptr->val.l == 0) {
2477 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2478 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2479 M_BNEZ(REG_ITMP1, 0);
2482 LCONST(REG_ITMP2, iptr->val.l);
2483 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2484 M_BEQZ(REG_ITMP1, 0);
2487 codegen_addreference(cd, (basicblock *) iptr->target);
2491 case ICMD_IF_LNE: /* ..., value ==> ... */
2492 /* op1 = target JavaVM pc, val.l = constant */
2494 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2495 if (iptr->val.l == 0) {
2499 LCONST(REG_ITMP2, iptr->val.l);
2500 M_BNE(s1, REG_ITMP2, 0);
2502 codegen_addreference(cd, (basicblock *) iptr->target);
2506 case ICMD_IF_LGT: /* ..., value ==> ... */
2507 /* op1 = target JavaVM pc, val.l = constant */
2509 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2510 if (iptr->val.l == 0) {
2514 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2515 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2516 M_BEQZ(REG_ITMP1, 0);
2519 LCONST(REG_ITMP2, iptr->val.l);
2520 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2521 M_BNEZ(REG_ITMP1, 0);
2524 codegen_addreference(cd, (basicblock *) iptr->target);
2528 case ICMD_IF_LGE: /* ..., value ==> ... */
2529 /* op1 = target JavaVM pc, val.l = constant */
2531 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2532 if (iptr->val.l == 0) {
2536 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2537 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2540 LCONST(REG_ITMP2, iptr->val.l);
2541 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2543 M_BEQZ(REG_ITMP1, 0);
2545 codegen_addreference(cd, (basicblock *) iptr->target);
2549 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2550 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2551 case ICMD_IF_ACMPEQ:
2553 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2554 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2556 codegen_addreference(cd, (basicblock *) iptr->target);
2560 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2561 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2562 case ICMD_IF_ACMPNE:
2564 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2565 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2567 codegen_addreference(cd, (basicblock *) iptr->target);
2571 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2572 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2574 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2575 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2576 M_CMPLT(s1, s2, REG_ITMP1);
2577 M_BNEZ(REG_ITMP1, 0);
2578 codegen_addreference(cd, (basicblock *) iptr->target);
2582 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2583 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2585 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2586 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2587 M_CMPGT(s1, s2, REG_ITMP1);
2588 M_BNEZ(REG_ITMP1, 0);
2589 codegen_addreference(cd, (basicblock *) iptr->target);
2593 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2594 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2596 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2597 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2598 M_CMPGT(s1, s2, REG_ITMP1);
2599 M_BEQZ(REG_ITMP1, 0);
2600 codegen_addreference(cd, (basicblock *) iptr->target);
2604 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2605 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2607 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2608 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2609 M_CMPLT(s1, s2, REG_ITMP1);
2610 M_BEQZ(REG_ITMP1, 0);
2611 codegen_addreference(cd, (basicblock *) iptr->target);
2615 #ifdef CONDITIONAL_LOADCONST
2616 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2618 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2621 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2622 /* val.i = constant */
2624 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2625 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2627 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2628 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2629 M_CMPEQ(s1, REG_ZERO, d);
2630 emit_store(jd, iptr, iptr->dst, d);
2633 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2634 M_CMPEQ(s1, REG_ZERO, d);
2636 emit_store(jd, iptr, iptr->dst, d);
2640 M_MOV(s1, REG_ITMP1);
2643 ICONST(d, iptr[1].val.i);
2645 if ((s3 >= 0) && (s3 <= 255)) {
2646 M_CMOVEQ_IMM(s1, s3, d);
2648 ICONST(REG_ITMP3, s3);
2649 M_CMOVEQ(s1, REG_ITMP3, d);
2651 emit_store(jd, iptr, iptr->dst, d);
2654 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2655 /* val.i = constant */
2657 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2658 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2660 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2661 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2662 M_CMPEQ(s1, REG_ZERO, d);
2663 emit_store(jd, iptr, iptr->dst, d);
2666 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2667 M_CMPEQ(s1, REG_ZERO, d);
2669 emit_store(jd, iptr, iptr->dst, d);
2673 M_MOV(s1, REG_ITMP1);
2676 ICONST(d, iptr[1].val.i);
2678 if ((s3 >= 0) && (s3 <= 255)) {
2679 M_CMOVNE_IMM(s1, s3, d);
2681 ICONST(REG_ITMP3, s3);
2682 M_CMOVNE(s1, REG_ITMP3, d);
2684 emit_store(jd, iptr, iptr->dst, d);
2687 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2688 /* val.i = constant */
2690 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2691 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2693 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2694 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2695 M_CMPLT(s1, REG_ZERO, d);
2696 emit_store(jd, iptr, iptr->dst, d);
2699 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2700 M_CMPLE(REG_ZERO, s1, d);
2701 emit_store(jd, iptr, iptr->dst, d);
2705 M_MOV(s1, REG_ITMP1);
2708 ICONST(d, iptr[1].val.i);
2710 if ((s3 >= 0) && (s3 <= 255)) {
2711 M_CMOVLT_IMM(s1, s3, d);
2713 ICONST(REG_ITMP3, s3);
2714 M_CMOVLT(s1, REG_ITMP3, d);
2716 emit_store(jd, iptr, iptr->dst, d);
2719 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2720 /* val.i = constant */
2722 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2723 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2725 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2726 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2727 M_CMPLE(REG_ZERO, s1, d);
2728 emit_store(jd, iptr, iptr->dst, d);
2731 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2732 M_CMPLT(s1, REG_ZERO, d);
2733 emit_store(jd, iptr, iptr->dst, d);
2737 M_MOV(s1, REG_ITMP1);
2740 ICONST(d, iptr[1].val.i);
2742 if ((s3 >= 0) && (s3 <= 255)) {
2743 M_CMOVGE_IMM(s1, s3, d);
2745 ICONST(REG_ITMP3, s3);
2746 M_CMOVGE(s1, REG_ITMP3, d);
2748 emit_store(jd, iptr, iptr->dst, d);
2751 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2752 /* val.i = constant */
2754 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2755 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2757 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2758 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2759 M_CMPLT(REG_ZERO, s1, d);
2760 emit_store(jd, iptr, iptr->dst, d);
2763 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2764 M_CMPLE(s1, REG_ZERO, d);
2765 emit_store(jd, iptr, iptr->dst, d);
2769 M_MOV(s1, REG_ITMP1);
2772 ICONST(d, iptr[1].val.i);
2774 if ((s3 >= 0) && (s3 <= 255)) {
2775 M_CMOVGT_IMM(s1, s3, d);
2777 ICONST(REG_ITMP3, s3);
2778 M_CMOVGT(s1, REG_ITMP3, d);
2780 emit_store(jd, iptr, iptr->dst, d);
2783 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2784 /* val.i = constant */
2786 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2787 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2789 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2790 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2791 M_CMPLE(s1, REG_ZERO, d);
2792 emit_store(jd, iptr, iptr->dst, d);
2795 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2796 M_CMPLT(REG_ZERO, s1, d);
2797 emit_store(jd, iptr, iptr->dst, d);
2801 M_MOV(s1, REG_ITMP1);
2804 ICONST(d, iptr[1].val.i);
2806 if ((s3 >= 0) && (s3 <= 255)) {
2807 M_CMOVLE_IMM(s1, s3, d);
2809 ICONST(REG_ITMP3, s3);
2810 M_CMOVLE(s1, REG_ITMP3, d);
2812 emit_store(jd, iptr, iptr->dst, d);
2817 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2820 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2821 M_INTMOVE(s1, REG_RESULT);
2822 goto nowperformreturn;
2824 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2826 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2827 M_INTMOVE(s1, REG_RESULT);
2829 #ifdef ENABLE_VERIFIER
2831 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2832 (unresolved_class *) iptr->val.a, 0);
2834 if (opt_showdisassemble) {
2838 #endif /* ENABLE_VERIFIER */
2839 goto nowperformreturn;
2841 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2843 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2844 M_FLTMOVE(s1, REG_FRESULT);
2845 goto nowperformreturn;
2847 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2849 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2850 M_DBLMOVE(s1, REG_FRESULT);
2851 goto nowperformreturn;
2853 case ICMD_RETURN: /* ... ==> ... */
2859 p = parentargs_base;
2861 /* call trace function */
2863 if (opt_verbosecall) {
2864 M_LDA(REG_SP, REG_SP, -3 * 8);
2865 M_LST(REG_RA, REG_SP, 0 * 8);
2866 M_LST(REG_RESULT, REG_SP, 1 * 8);
2867 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2869 disp = dseg_addaddress(cd, m);
2870 M_ALD(rd->argintregs[0], REG_PV, disp);
2871 M_MOV(REG_RESULT, rd->argintregs[1]);
2872 M_DMOV(REG_FRESULT, rd->argfltregs[2]);
2873 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2875 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2876 M_ALD(REG_ITMP3, REG_PV, disp);
2877 M_JSR(REG_RA, REG_ITMP3);
2880 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2881 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2882 M_LLD(REG_RA, REG_SP, 0 * 8);
2883 M_LDA(REG_SP, REG_SP, 3 * 8);
2886 #if defined(ENABLE_THREADS)
2887 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2888 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2889 M_ALD(REG_ITMP3, REG_PV, disp);
2891 /* we need to save the proper return value */
2893 switch (iptr->opc) {
2897 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2898 M_JSR(REG_RA, REG_ITMP3);
2899 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2903 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2904 M_JSR(REG_RA, REG_ITMP3);
2905 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2908 M_JSR(REG_RA, REG_ITMP3);
2909 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2913 /* and now restore the proper return value */
2915 switch (iptr->opc) {
2919 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2923 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2929 /* restore return address */
2931 if (!m->isleafmethod) {
2932 p--; M_ALD(REG_RA, REG_SP, p * 8);
2935 /* restore saved registers */
2937 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2938 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2940 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2941 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2944 /* deallocate stack and return */
2946 if (parentargs_base) {
2949 disp = parentargs_base * 8;
2950 lo = (short) (disp);
2951 hi = (short) (((disp) - lo) >> 16);
2955 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2957 M_LUI(REG_ITMP3,hi);
2958 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2960 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2973 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2978 tptr = (void **) iptr->target;
2980 s4ptr = iptr->val.a;
2981 l = s4ptr[1]; /* low */
2982 i = s4ptr[2]; /* high */
2984 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2986 {M_INTMOVE(s1, REG_ITMP1);}
2987 else if (l <= 32768) {
2988 M_IADD_IMM(s1, -l, REG_ITMP1);
2991 ICONST(REG_ITMP2, l);
2992 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2998 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2999 M_BEQZ(REG_ITMP2, 0);
3000 codegen_addreference(cd, (basicblock *) tptr[0]);
3001 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
3003 /* build jump table top down and use address of lowest entry */
3005 /* s4ptr += 3 + i; */
3009 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3010 dseg_addtarget(cd, (basicblock *) tptr[0]);
3015 /* length of dataseg after last dseg_addtarget is used by load */
3017 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3018 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3025 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3027 s4 i, /*l, */val, *s4ptr;
3030 tptr = (void **) iptr->target;
3032 s4ptr = iptr->val.a;
3033 /*l = s4ptr[0];*/ /* default */
3034 i = s4ptr[1]; /* count */
3036 MCODECHECK((i<<2)+8);
3037 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3043 ICONST(REG_ITMP2, val);
3044 M_BEQ(s1, REG_ITMP2, 0);
3045 codegen_addreference(cd, (basicblock *) tptr[0]);
3050 tptr = (void **) iptr->target;
3051 codegen_addreference(cd, (basicblock *) tptr[0]);
3058 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3059 /* op1 = arg count val.a = builtintable entry */
3065 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3066 /* op1 = arg count, val.a = method pointer */
3068 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3069 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3070 case ICMD_INVOKEINTERFACE:
3072 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3073 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3077 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3078 md = lm->parseddesc;
3082 s3 = md->paramcount;
3084 MCODECHECK((s3 << 1) + 64);
3086 /* copy arguments to registers or stack location */
3088 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3089 if (src->varkind == ARGVAR)
3091 if (IS_INT_LNG_TYPE(src->type)) {
3092 if (!md->params[s3].inmemory) {
3093 s1 = rd->argintregs[md->params[s3].regoff];
3094 d = emit_load_s1(jd, iptr, src, s1);
3097 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3098 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3102 if (!md->params[s3].inmemory) {
3103 s1 = rd->argfltregs[md->params[s3].regoff];
3104 d = emit_load_s1(jd, iptr, src, s1);
3105 if (IS_2_WORD_TYPE(src->type))
3111 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3112 if (IS_2_WORD_TYPE(src->type))
3113 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3115 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3120 switch (iptr->opc) {
3122 disp = dseg_addaddress(cd, bte->fp);
3123 d = md->returntype.type;
3125 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3126 M_JSR(REG_RA, REG_ITMP3);
3128 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3129 M_LDA(REG_PV, REG_RA, -disp);
3131 /* if op1 == true, we need to check for an exception */
3133 if (iptr->op1 == true) {
3134 M_BEQZ(REG_RESULT, 0);
3135 codegen_add_fillinstacktrace_ref(cd);
3140 case ICMD_INVOKESPECIAL:
3141 M_BEQZ(rd->argintregs[0], 0);
3142 codegen_add_nullpointerexception_ref(cd);
3146 case ICMD_INVOKESTATIC:
3148 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3150 disp = dseg_addaddress(cd, NULL);
3152 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3155 if (opt_showdisassemble) {
3159 d = um->methodref->parseddesc.md->returntype.type;
3162 disp = dseg_addaddress(cd, lm->stubroutine);
3163 d = lm->parseddesc->returntype.type;
3166 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3167 M_JSR(REG_RA, REG_PV);
3169 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3170 M_LDA(REG_PV, REG_RA, -disp);
3173 case ICMD_INVOKEVIRTUAL:
3174 gen_nullptr_check(rd->argintregs[0]);
3177 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3179 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3181 if (opt_showdisassemble) {
3186 d = um->methodref->parseddesc.md->returntype.type;
3189 s1 = OFFSET(vftbl_t, table[0]) +
3190 sizeof(methodptr) * lm->vftblindex;
3191 d = lm->parseddesc->returntype.type;
3194 M_ALD(REG_METHODPTR, rd->argintregs[0],
3195 OFFSET(java_objectheader, vftbl));
3196 M_ALD(REG_PV, REG_METHODPTR, s1);
3197 M_JSR(REG_RA, REG_PV);
3199 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3200 M_LDA(REG_PV, REG_RA, -disp);
3203 case ICMD_INVOKEINTERFACE:
3204 gen_nullptr_check(rd->argintregs[0]);
3207 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3209 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3211 if (opt_showdisassemble) {
3217 d = um->methodref->parseddesc.md->returntype.type;
3220 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3221 sizeof(methodptr*) * lm->class->index;
3223 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3225 d = lm->parseddesc->returntype.type;
3228 M_ALD(REG_METHODPTR, rd->argintregs[0],
3229 OFFSET(java_objectheader, vftbl));
3230 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3231 M_ALD(REG_PV, REG_METHODPTR, s2);
3232 M_JSR(REG_RA, REG_PV);
3234 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3235 M_LDA(REG_PV, REG_RA, -disp);
3239 /* d contains return type */
3241 if (d != TYPE_VOID) {
3242 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3243 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3244 M_INTMOVE(REG_RESULT, s1);
3246 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3247 if (IS_2_WORD_TYPE(iptr->dst->type))
3248 M_DMOV(REG_FRESULT, s1);
3250 M_FMOV(REG_FRESULT, s1);
3252 emit_store(jd, iptr, iptr->dst, s1);
3257 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3258 /* op1: 0 == array, 1 == class */
3259 /* val.a: (classinfo*) superclass */
3261 /* superclass is an interface:
3263 * OK if ((sub == NULL) ||
3264 * (sub->vftbl->interfacetablelength > super->index) &&
3265 * (sub->vftbl->interfacetable[-super->index] != NULL));
3267 * superclass is a class:
3269 * OK if ((sub == NULL) || (0
3270 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3271 * super->vftbl->diffvall));
3274 if (iptr->op1 == 1) {
3276 vftbl_t *supervftbl;
3279 super = (classinfo *) iptr->val.a;
3286 superindex = super->index;
3287 supervftbl = super->vftbl;
3290 #if defined(ENABLE_THREADS)
3291 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3294 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3296 /* calculate interface checkcast code size */
3300 s2 += (opt_showdisassemble ? 2 : 0);
3302 /* calculate class checkcast code size */
3304 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3306 s3 += (opt_showdisassemble ? 2 : 0);
3308 /* if class is not resolved, check which code to call */
3311 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3314 disp = dseg_adds4(cd, 0); /* super->flags */
3316 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3317 (constant_classref *) iptr->target,
3320 if (opt_showdisassemble) {
3324 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3325 M_ILD(REG_ITMP2, REG_PV, disp);
3326 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3327 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3331 /* interface checkcast code */
3333 if (!super || super->flags & ACC_INTERFACE) {
3339 codegen_addpatchref(cd,
3340 PATCHER_checkcast_instanceof_interface,
3341 (constant_classref *) iptr->target,
3344 if (opt_showdisassemble) {
3349 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3350 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3351 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3352 M_BLEZ(REG_ITMP3, 0);
3353 codegen_add_classcastexception_ref(cd);
3355 M_ALD(REG_ITMP3, REG_ITMP2,
3356 OFFSET(vftbl_t, interfacetable[0]) -
3357 superindex * sizeof(methodptr*));
3358 M_BEQZ(REG_ITMP3, 0);
3359 codegen_add_classcastexception_ref(cd);
3368 /* class checkcast code */
3370 if (!super || !(super->flags & ACC_INTERFACE)) {
3371 disp = dseg_addaddress(cd, (void *) supervftbl);
3378 codegen_addpatchref(cd,
3379 PATCHER_checkcast_instanceof_class,
3380 (constant_classref *) iptr->target,
3383 if (opt_showdisassemble) {
3388 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3389 M_ALD(REG_ITMP3, REG_PV, disp);
3390 #if defined(ENABLE_THREADS)
3391 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3393 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3394 /* if (s1 != REG_ITMP1) { */
3395 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3396 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3397 /* #if defined(ENABLE_THREADS) */
3398 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3400 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3402 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3403 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3404 M_ALD(REG_ITMP3, REG_PV, disp);
3405 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3406 #if defined(ENABLE_THREADS)
3407 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3410 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3411 M_BNEZ(REG_ITMP3, 0);
3412 codegen_add_classcastexception_ref(cd);
3415 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3418 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3419 M_INTMOVE(s1, rd->argintregs[0]);
3421 disp = dseg_addaddress(cd, iptr->val.a);
3423 if (iptr->val.a == NULL) {
3424 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3425 (constant_classref *) iptr->target,
3428 if (opt_showdisassemble) {
3433 M_ALD(rd->argintregs[1], REG_PV, disp);
3434 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3435 M_ALD(REG_ITMP3, REG_PV, disp);
3436 M_JSR(REG_RA, REG_ITMP3);
3439 M_BEQZ(REG_RESULT, 0);
3440 codegen_add_classcastexception_ref(cd);
3443 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3444 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3447 emit_store(jd, iptr, iptr->dst, d);
3450 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3451 /* op1: 0 == array, 1 == class */
3452 /* val.a: (classinfo*) superclass */
3454 /* superclass is an interface:
3456 * return (sub != NULL) &&
3457 * (sub->vftbl->interfacetablelength > super->index) &&
3458 * (sub->vftbl->interfacetable[-super->index] != NULL);
3460 * superclass is a class:
3462 * return ((sub != NULL) && (0
3463 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3464 * super->vftbl->diffvall));
3469 vftbl_t *supervftbl;
3472 super = (classinfo *) iptr->val.a;
3479 superindex = super->index;
3480 supervftbl = super->vftbl;
3483 #if defined(ENABLE_THREADS)
3484 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3487 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3488 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3490 M_MOV(s1, REG_ITMP1);
3494 /* calculate interface instanceof code size */
3498 s2 += (opt_showdisassemble ? 2 : 0);
3500 /* calculate class instanceof code size */
3504 s3 += (opt_showdisassemble ? 2 : 0);
3508 /* if class is not resolved, check which code to call */
3511 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3514 disp = dseg_adds4(cd, 0); /* super->flags */
3516 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3517 (constant_classref *) iptr->target, disp);
3519 if (opt_showdisassemble) {
3523 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3524 M_ILD(REG_ITMP3, REG_PV, disp);
3525 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3526 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3530 /* interface instanceof code */
3532 if (!super || (super->flags & ACC_INTERFACE)) {
3538 codegen_addpatchref(cd,
3539 PATCHER_checkcast_instanceof_interface,
3540 (constant_classref *) iptr->target, 0);
3542 if (opt_showdisassemble) {
3547 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3548 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3549 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3550 M_BLEZ(REG_ITMP3, 3);
3552 M_ALD(REG_ITMP1, REG_ITMP1,
3553 OFFSET(vftbl_t, interfacetable[0]) -
3554 superindex * sizeof(methodptr*));
3555 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3563 /* class instanceof code */
3565 if (!super || !(super->flags & ACC_INTERFACE)) {
3566 disp = dseg_addaddress(cd, supervftbl);
3573 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3574 (constant_classref *) iptr->target,
3577 if (opt_showdisassemble) {
3582 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3583 M_ALD(REG_ITMP2, REG_PV, disp);
3584 #if defined(ENABLE_THREADS)
3585 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3587 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3588 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3589 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3590 #if defined(ENABLE_THREADS)
3591 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3593 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3594 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3597 emit_store(jd, iptr, iptr->dst, d);
3601 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3602 /* op1 = dimension, val.a = class */
3604 /* check for negative sizes and copy sizes to stack if necessary */
3606 MCODECHECK((iptr->op1 << 1) + 64);
3608 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3609 /* copy SAVEDVAR sizes to stack */
3611 if (src->varkind != ARGVAR) {
3612 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3613 M_LST(s2, REG_SP, s1 * 8);
3617 /* a0 = dimension count */
3619 ICONST(rd->argintregs[0], iptr->op1);
3621 /* is patcher function set? */
3623 if (iptr->val.a == NULL) {
3624 disp = dseg_addaddress(cd, NULL);
3626 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3627 (constant_classref *) iptr->target, disp);
3629 if (opt_showdisassemble) {
3634 disp = dseg_addaddress(cd, iptr->val.a);
3637 /* a1 = arraydescriptor */
3639 M_ALD(rd->argintregs[1], REG_PV, disp);
3641 /* a2 = pointer to dimensions = stack pointer */
3643 M_INTMOVE(REG_SP, rd->argintregs[2]);
3645 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3646 M_ALD(REG_ITMP3, REG_PV, disp);
3647 M_JSR(REG_RA, REG_ITMP3);
3650 /* check for exception before result assignment */
3652 M_BEQZ(REG_RESULT, 0);
3653 codegen_add_fillinstacktrace_ref(cd);
3656 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3657 M_INTMOVE(REG_RESULT, d);
3658 emit_store(jd, iptr, iptr->dst, d);
3662 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3666 } /* for instruction */
3668 /* copy values to interface registers */
3670 src = bptr->outstack;
3671 len = bptr->outdepth;
3673 #if defined(ENABLE_LSRA)
3678 if ((src->varkind != STACKVAR)) {
3680 if (IS_FLT_DBL_TYPE(s2)) {
3681 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3682 if (rd->interfaces[len][s2].flags & INMEMORY) {
3683 if (IS_2_WORD_TYPE(s2))
3684 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3686 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3689 if (IS_2_WORD_TYPE(s2))
3690 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3692 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3696 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3697 if (rd->interfaces[len][s2].flags & INMEMORY)
3698 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3700 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3706 /* At the end of a basic block we may have to append some nops,
3707 because the patcher stub calling code might be longer than the
3708 actual instruction. So codepatching does not change the
3709 following block unintentionally. */
3711 if (cd->mcodeptr < cd->lastmcodeptr) {
3712 while (cd->mcodeptr < cd->lastmcodeptr)
3716 } /* if (bptr -> flags >= BBREACHED) */
3717 } /* for basic block */
3719 dseg_createlinenumbertable(cd);
3722 /* generate exception and patcher stubs */
3731 savedmcodeptr = NULL;
3733 /* generate exception stubs */
3735 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3736 gen_resolvebranch(cd->mcodebase + eref->branchpos,
3737 eref->branchpos, cd->mcodeptr - cd->mcodebase);
3741 /* Check if the exception is an
3742 ArrayIndexOutOfBoundsException. If so, move index register
3745 if (eref->reg != -1)
3746 M_MOV(eref->reg, REG_ITMP1);
3748 /* calcuate exception address */
3750 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3752 /* move function to call into REG_ITMP3 */
3754 disp = dseg_addaddress(cd, eref->function);
3755 M_ALD(REG_ITMP3, REG_PV, disp);
3757 if (savedmcodeptr != NULL) {
3758 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3763 savedmcodeptr = cd->mcodeptr;
3765 M_MOV(REG_PV, rd->argintregs[0]);
3766 M_MOV(REG_SP, rd->argintregs[1]);
3768 if (m->isleafmethod)
3769 M_MOV(REG_RA, rd->argintregs[2]);
3771 M_ALD(rd->argintregs[2],
3772 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3774 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3775 M_MOV(REG_ITMP1, rd->argintregs[4]);
3777 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3778 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3780 if (m->isleafmethod)
3781 M_AST(REG_RA, REG_SP, 1 * 8);
3783 M_JSR(REG_RA, REG_ITMP3);
3785 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3787 if (m->isleafmethod)
3788 M_ALD(REG_RA, REG_SP, 1 * 8);
3790 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3791 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3793 a = dseg_addaddress(cd, asm_handle_exception);
3794 M_ALD(REG_ITMP3, REG_PV, a);
3801 /* generate code patching stub call code */
3803 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3804 /* check code segment size */
3808 /* Get machine code which is patched back in later. The
3809 call is 2 instruction words long. */
3811 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3813 /* We need to split this, because an unaligned 8 byte read
3814 causes a SIGSEGV. */
3816 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
3817 ((u4 *) tmpmcodeptr)[0];
3819 /* Patch in the call to call the following code (done at
3822 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3823 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3825 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3827 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3829 new_internalerror("Jump offset is out of range: %d > +/-%d",
3837 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3839 /* create stack frame */
3841 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3843 /* calculate return address and move it onto the stack */
3845 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3846 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3848 /* move pointer to java_objectheader onto stack */
3850 #if defined(ENABLE_THREADS)
3851 /* create a virtual java_objectheader */
3853 (void) dseg_addaddress(cd, NULL); /* flcword */
3854 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3855 disp = dseg_addaddress(cd, NULL); /* vftbl */
3857 M_LDA(REG_ITMP3, REG_PV, disp);
3858 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3863 /* move machine code onto stack */
3865 disp = dseg_adds8(cd, mcode);
3866 M_LLD(REG_ITMP3, REG_PV, disp);
3867 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3869 /* move class/method/field reference onto stack */
3871 disp = dseg_addaddress(cd, pref->ref);
3872 M_ALD(REG_ITMP3, REG_PV, disp);
3873 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3875 /* move data segment displacement onto stack */
3877 disp = dseg_adds4(cd, pref->disp);
3878 M_ILD(REG_ITMP3, REG_PV, disp);
3879 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3881 /* move patcher function pointer onto stack */
3883 disp = dseg_addaddress(cd, pref->patcher);
3884 M_ALD(REG_ITMP3, REG_PV, disp);
3885 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3887 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3888 M_ALD(REG_ITMP3, REG_PV, disp);
3893 /* generate replacement-out stubs */
3898 replacementpoint = jd->code->rplpoints;
3900 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3901 /* check code segment size */
3905 /* note start of stub code */
3907 replacementpoint->outcode = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
3909 /* make machine code for patching */
3911 savedmcodeptr = cd->mcodeptr;
3912 cd->mcodeptr = (u1 *) &(replacementpoint->mcode);
3914 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3915 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3917 new_internalerror("Jump offset is out of range: %d > +/-%d",
3922 M_NOP; /* delay slot */
3924 cd->mcodeptr = savedmcodeptr;
3926 /* create stack frame - 16-byte aligned */
3928 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3930 /* push address of `rplpoint` struct */
3932 disp = dseg_addaddress(cd, replacementpoint);
3933 M_ALD(REG_ITMP3, REG_PV, disp);
3934 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3936 /* jump to replacement function */
3938 disp = dseg_addaddress(cd, asm_replacement_out);
3939 M_ALD(REG_ITMP3, REG_PV, disp);
3941 M_NOP; /* delay slot */
3948 /* everything's ok */
3954 /* createcompilerstub **********************************************************
3956 Creates a stub routine which calls the compiler.
3958 *******************************************************************************/
3960 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3961 #define COMPILERSTUB_CODESIZE 4 * 4
3963 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3966 u1 *createcompilerstub(methodinfo *m)
3968 u1 *s; /* memory to hold the stub */
3973 s = CNEW(u1, COMPILERSTUB_SIZE);
3975 /* set data pointer and code pointer */
3978 s = s + COMPILERSTUB_DATASIZE;
3980 /* mark start of dump memory area */
3982 dumpsize = dump_size();
3984 cd = DNEW(codegendata);
3987 /* Store the methodinfo* in the same place as in the methodheader
3988 for compiled methods. */
3990 d[0] = (ptrint) asm_call_jit_compiler;
3993 M_ALD_INTERN(REG_ITMP1, REG_PV, -1 * SIZEOF_VOID_P); /* method pointer */
3994 M_ALD_INTERN(REG_PV, REG_PV, -2 * SIZEOF_VOID_P); /* pointer to compiler */
3998 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
4000 #if defined(ENABLE_STATISTICS)
4002 count_cstub_len += COMPILERSTUB_SIZE;
4005 /* release dump area */
4007 dump_release(dumpsize);
4013 /* createnativestub ************************************************************
4015 Creates a stub routine which calls a native method.
4017 *******************************************************************************/
4019 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4024 s4 stackframesize; /* size of stackframe if needed */
4027 s4 i, j; /* count variables */
4030 s4 funcdisp; /* displacement of the function */
4032 /* get required compiler data */
4038 /* initialize variables */
4041 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4043 /* calculate stack frame size */
4046 1 + /* return address */
4047 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4048 sizeof(localref_table) / SIZEOF_VOID_P +
4049 md->paramcount + /* for saving arguments over calls */
4050 1 + /* for saving return address */
4053 /* create method header */
4055 #if SIZEOF_VOID_P == 4
4056 (void) dseg_addaddress(cd, m); /* MethodPointer */
4058 (void) dseg_addaddress(cd, m); /* MethodPointer */
4059 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4060 (void) dseg_adds4(cd, 0); /* IsSync */
4061 (void) dseg_adds4(cd, 0); /* IsLeaf */
4062 (void) dseg_adds4(cd, 0); /* IntSave */
4063 (void) dseg_adds4(cd, 0); /* FltSave */
4064 (void) dseg_addlinenumbertablesize(cd);
4065 (void) dseg_adds4(cd, 0); /* ExTableSize */
4067 /* generate stub code */
4069 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
4070 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
4072 /* call trace function */
4074 if (opt_verbosecall) {
4075 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4077 /* save integer argument registers */
4079 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4080 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4081 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4083 /* save and copy float arguments into integer registers */
4085 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4086 t = md->paramtypes[i].type;
4088 if (IS_FLT_DBL_TYPE(t)) {
4089 if (IS_2_WORD_TYPE(t)) {
4090 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4091 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4093 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4094 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4099 disp = dseg_addaddress(cd, m);
4100 M_ALD(REG_ITMP1, REG_PV, disp);
4101 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4102 disp = dseg_addaddress(cd, builtin_trace_args);
4103 M_ALD(REG_ITMP3, REG_PV, disp);
4104 M_JSR(REG_RA, REG_ITMP3);
4107 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4108 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4109 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4111 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4112 t = md->paramtypes[i].type;
4114 if (IS_FLT_DBL_TYPE(t)) {
4115 if (IS_2_WORD_TYPE(t))
4116 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4118 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4122 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4125 /* get function address (this must happen before the stackframeinfo) */
4127 funcdisp = dseg_addaddress(cd, f);
4129 #if !defined(WITH_STATIC_CLASSPATH)
4131 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4133 if (opt_showdisassemble) {
4139 /* save integer and float argument registers */
4141 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4142 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4143 M_LST(rd->argintregs[i], REG_SP, j * 8);
4148 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4149 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4150 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4155 /* prepare data structures for native function call */
4157 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4158 M_MOV(REG_PV, rd->argintregs[1]);
4159 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4160 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4161 disp = dseg_addaddress(cd, codegen_start_native_call);
4162 M_ALD(REG_ITMP3, REG_PV, disp);
4163 M_JSR(REG_RA, REG_ITMP3);
4164 M_NOP; /* XXX fill me! */
4166 /* restore integer and float argument registers */
4168 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4169 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4170 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4175 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4176 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4177 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4182 /* copy or spill arguments to new locations */
4184 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4185 t = md->paramtypes[i].type;
4187 if (IS_INT_LNG_TYPE(t)) {
4188 if (!md->params[i].inmemory) {
4189 s1 = rd->argintregs[md->params[i].regoff];
4191 if (!nmd->params[j].inmemory) {
4192 s2 = rd->argintregs[nmd->params[j].regoff];
4195 s2 = nmd->params[j].regoff;
4196 M_AST(s1, REG_SP, s2 * 8);
4200 s1 = md->params[i].regoff + stackframesize;
4201 s2 = nmd->params[j].regoff;
4202 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4203 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4207 if (!md->params[i].inmemory) {
4208 s1 = rd->argfltregs[md->params[i].regoff];
4210 if (!nmd->params[j].inmemory) {
4211 s2 = rd->argfltregs[nmd->params[j].regoff];
4212 if (IS_2_WORD_TYPE(t))
4218 s2 = nmd->params[j].regoff;
4219 if (IS_2_WORD_TYPE(t))
4220 M_DST(s1, REG_SP, s2 * 8);
4222 M_FST(s1, REG_SP, s2 * 8);
4226 s1 = md->params[i].regoff + stackframesize;
4227 s2 = nmd->params[j].regoff;
4228 if (IS_2_WORD_TYPE(t)) {
4229 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4230 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4232 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4233 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4239 /* put class into second argument register */
4241 if (m->flags & ACC_STATIC) {
4242 disp = dseg_addaddress(cd, m->class);
4243 M_ALD(rd->argintregs[1], REG_PV, disp);
4246 /* put env into first argument register */
4248 disp = dseg_addaddress(cd, _Jv_env);
4249 M_ALD(rd->argintregs[0], REG_PV, disp);
4251 /* do the native function call */
4253 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4254 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4255 M_NOP; /* delay slot */
4257 /* save return value */
4259 if (IS_INT_LNG_TYPE(md->returntype.type))
4260 M_LST(REG_RESULT, REG_SP, 0 * 8);
4262 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4264 /* remove native stackframe info */
4266 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4267 disp = dseg_addaddress(cd, codegen_finish_native_call);
4268 M_ALD(REG_ITMP3, REG_PV, disp);
4269 M_JSR(REG_RA, REG_ITMP3);
4270 M_NOP; /* XXX fill me! */
4272 /* call finished trace function */
4274 if (opt_verbosecall) {
4275 if (IS_INT_LNG_TYPE(md->returntype.type))
4276 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4278 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4280 disp = dseg_addaddress(cd, m);
4281 M_ALD(rd->argintregs[0], REG_PV, disp);
4283 M_MOV(REG_RESULT, rd->argintregs[1]);
4284 M_DMFC1(REG_ITMP1, REG_FRESULT);
4285 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4286 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4288 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4289 M_ALD(REG_ITMP3, REG_PV, disp);
4290 M_JSR(REG_RA, REG_ITMP3);
4294 /* check for exception */
4296 #if defined(ENABLE_THREADS)
4297 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4298 M_ALD(REG_ITMP3, REG_PV, disp);
4299 M_JSR(REG_RA, REG_ITMP3);
4301 M_MOV(REG_RESULT, REG_ITMP3);
4303 disp = dseg_addaddress(cd, &_exceptionptr);
4304 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4306 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4308 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4310 /* restore return value */
4312 if (IS_INT_LNG_TYPE(md->returntype.type))
4313 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4315 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4317 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4318 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4320 M_RET(REG_RA); /* return to caller */
4321 M_NOP; /* DELAY SLOT */
4323 /* handle exception */
4325 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4327 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4328 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4329 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4330 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4333 /* generate static stub call code */
4341 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4342 /* Get machine code which is patched back in later. The
4343 call is 2 instruction words long. */
4345 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
4347 /* We need to split this, because an unaligned 8 byte read
4348 causes a SIGSEGV. */
4350 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
4351 ((u4 *) tmpmcodeptr)[0];
4353 /* Patch in the call to call the following code (done at
4356 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4357 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4359 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
4361 M_NOP; /* branch delay slot */
4363 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4365 /* create stack frame */
4367 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4369 /* move return address onto stack */
4371 M_AST(REG_RA, REG_SP, 5 * 8);
4373 /* move pointer to java_objectheader onto stack */
4375 #if defined(ENABLE_THREADS)
4376 /* order reversed because of data segment layout */
4378 (void) dseg_addaddress(cd, NULL); /* flcword */
4379 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4380 disp = dseg_addaddress(cd, NULL); /* vftbl */
4382 M_LDA(REG_ITMP3, REG_PV, disp);
4383 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4385 M_AST(REG_ZERO, REG_SP, 4 * 8);
4388 /* move machine code onto stack */
4390 disp = dseg_adds8(cd, mcode);
4391 M_LLD(REG_ITMP3, REG_PV, disp);
4392 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4394 /* move class/method/field reference onto stack */
4396 disp = dseg_addaddress(cd, pref->ref);
4397 M_ALD(REG_ITMP3, REG_PV, disp);
4398 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4400 /* move data segment displacement onto stack */
4402 disp = dseg_adds4(cd, pref->disp);
4403 M_ILD(REG_ITMP3, REG_PV, disp);
4404 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4406 /* move patcher function pointer onto stack */
4408 disp = dseg_addaddress(cd, pref->patcher);
4409 M_ALD(REG_ITMP3, REG_PV, disp);
4410 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4412 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4413 M_ALD(REG_ITMP3, REG_PV, disp);
4421 return jd->code->entrypoint;
4426 * These are local overrides for various environment variables in Emacs.
4427 * Please do not remove this and leave it at the end of the file, where
4428 * Emacs will automagically detect them.
4429 * ---------------------------------------------------------------------
4432 * indent-tabs-mode: t
4436 * vim:noexpandtab:sw=4:ts=4: