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 5127 2006-07-13 10:26:38Z twisti $
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
56 #include "native/native.h"
58 #if defined(ENABLE_THREADS)
59 # include "threads/native/lock.h"
62 #include "vm/builtin.h"
64 #include "vm/exceptions.h"
65 #include "vm/options.h"
66 #include "vm/stringlocal.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
82 /* codegen *********************************************************************
84 Generates machine code.
86 *******************************************************************************/
88 bool codegen(jitdata *jd)
94 s4 len, s1, s2, s3, d, disp;
103 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
104 builtintable_entry *bte;
106 rplpoint *replacementpoint;
108 /* get required compiler data */
119 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
121 /* space to save used callee saved registers */
123 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
124 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
126 parentargs_base = rd->memuse + savedregs_num;
128 #if defined(ENABLE_THREADS)
129 /* space to save argument of monitor_enter */
131 if (checksync && (m->flags & ACC_SYNCHRONIZED))
135 /* adjust frame size for 16 byte alignment */
137 if (parentargs_base & 1)
140 /* create method header */
142 #if SIZEOF_VOID_P == 4
143 (void) dseg_addaddress(cd, code); /* Filler */
145 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
146 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
148 #if defined(ENABLE_THREADS)
149 /* IsSync contains the offset relative to the stack pointer for the
150 argument of monitor_exit used in the exception handler. Since the
151 offset could be zero and give a wrong meaning of the flag it is
155 if (checksync && (m->flags & ACC_SYNCHRONIZED))
156 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
159 (void) dseg_adds4(cd, 0); /* IsSync */
161 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
162 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
163 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
164 dseg_addlinenumbertablesize(cd);
165 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
167 /* create exception table */
169 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
170 dseg_addtarget(cd, ex->start);
171 dseg_addtarget(cd, ex->end);
172 dseg_addtarget(cd, ex->handler);
173 (void) dseg_addaddress(cd, ex->catchtype.cls);
176 /* create stack frame (if necessary) */
179 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
181 /* save return address and used callee saved registers */
184 if (!jd->isleafmethod) {
185 p--; M_AST(REG_RA, REG_SP, p * 8);
187 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
188 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
190 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
191 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
194 /* take arguments out of register or stack frame */
198 for (p = 0, l = 0; p < md->paramcount; p++) {
199 t = md->paramtypes[p].type;
200 var = &(rd->locals[l][t]);
202 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
206 s1 = md->params[p].regoff;
207 if (IS_INT_LNG_TYPE(t)) { /* integer args */
208 if (!md->params[p].inmemory) { /* register arguments */
209 s2 = rd->argintregs[s1];
210 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
211 M_INTMOVE(s2, var->regoff);
212 } else { /* reg arg -> spilled */
213 M_LST(s2, REG_SP, var->regoff * 8);
216 } else { /* stack arguments */
217 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
218 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
219 } else { /* stack arg -> spilled */
220 var->regoff = parentargs_base + s1;
224 } else { /* floating args */
225 if (!md->params[p].inmemory) { /* register arguments */
226 s2 = rd->argfltregs[s1];
227 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
228 if (IS_2_WORD_TYPE(t))
229 M_DMOV(s2, var->regoff);
231 M_FMOV(s2, var->regoff);
232 } else { /* reg arg -> spilled */
233 if (IS_2_WORD_TYPE(t))
234 M_DST(s2, REG_SP, var->regoff * 8);
236 M_FST(s2, REG_SP, var->regoff * 8);
239 } else { /* stack arguments */
240 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
241 if (IS_2_WORD_TYPE(t))
242 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
244 M_FLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
245 } else /* stack-arg -> spilled */
246 var->regoff = parentargs_base + s1;
251 /* call monitorenter function */
253 #if defined(ENABLE_THREADS)
254 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
255 /* stack offset for monitor argument */
259 # if !defined(NDEBUG)
260 if (opt_verbosecall) {
261 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
263 for (p = 0; p < INT_ARG_CNT; p++)
264 M_LST(rd->argintregs[p], REG_SP, p * 8);
266 for (p = 0; p < FLT_ARG_CNT; p++)
267 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
269 s1 += INT_ARG_CNT + FLT_ARG_CNT;
273 /* get correct lock object */
275 if (m->flags & ACC_STATIC) {
276 p = dseg_addaddress(cd, &m->class->object.header);
277 M_ALD(rd->argintregs[0], REG_PV, p);
280 M_BEQZ(rd->argintregs[0], 0);
281 codegen_add_nullpointerexception_ref(cd);
284 p = dseg_addaddress(cd, LOCK_monitor_enter);
285 M_ALD(REG_ITMP3, REG_PV, p);
286 M_JSR(REG_RA, REG_ITMP3);
287 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
289 # if !defined(NDEBUG)
290 if (opt_verbosecall) {
291 for (p = 0; p < INT_ARG_CNT; p++)
292 M_LLD(rd->argintregs[p], REG_SP, p * 8);
294 for (p = 0; p < FLT_ARG_CNT; p++)
295 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
298 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
304 /* copy argument registers to stack and call trace function */
306 if (opt_verbosecall) {
307 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
308 M_AST(REG_RA, REG_SP, 1 * 8);
310 /* save integer argument registers */
312 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
313 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
315 /* save and copy float arguments into integer registers */
317 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
318 t = md->paramtypes[p].type;
320 if (IS_FLT_DBL_TYPE(t)) {
321 if (IS_2_WORD_TYPE(t)) {
322 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
323 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
326 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
327 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
331 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
335 /* save temporary registers for leaf methods */
337 if (jd->isleafmethod) {
338 for (p = 0; p < INT_TMP_CNT; p++)
339 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
341 for (p = 0; p < FLT_TMP_CNT; p++)
342 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
345 p = dseg_addaddress(cd, m);
346 M_ALD(REG_ITMP1, REG_PV, p);
347 M_AST(REG_ITMP1, REG_SP, 0 * 8);
348 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
349 M_ALD(REG_ITMP3, REG_PV, disp);
350 M_JSR(REG_RA, REG_ITMP3);
353 M_ALD(REG_RA, REG_SP, 1 * 8);
355 /* restore integer argument registers */
357 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
358 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
360 /* restore float argument registers */
362 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
363 t = md->paramtypes[p].type;
365 if (IS_FLT_DBL_TYPE(t)) {
366 if (IS_2_WORD_TYPE(t)) {
367 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
370 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
374 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
378 /* restore temporary registers for leaf methods */
380 if (jd->isleafmethod) {
381 for (p = 0; p < INT_TMP_CNT; p++)
382 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
384 for (p = 0; p < FLT_TMP_CNT; p++)
385 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
388 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
393 /* end of header generation */
395 replacementpoint = jd->code->rplpoints;
397 /* walk through all basic blocks */
399 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
401 /* handle replacement points */
403 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
405 /* 8-byte align pc */
406 if ((ptrint) cd->mcodeptr & 4) {
410 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
413 assert(cd->lastmcodeptr <= cd->mcodeptr);
414 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
417 /* store relative start of block */
419 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
421 if (bptr->flags >= BBREACHED) {
423 /* branch resolving */
426 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
427 gen_resolvebranch(cd->mcodebase + bref->branchpos,
433 /* copy interface registers to their destination */
438 #if defined(ENABLE_LSRA)
440 while (src != NULL) {
442 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
443 /* d = reg_of_var(m, src, REG_ITMP1); */
444 if (!(src->flags & INMEMORY))
448 M_INTMOVE(REG_ITMP1, d);
449 emit_store(jd, NULL, src, d);
455 while (src != NULL) {
457 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
458 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
459 M_INTMOVE(REG_ITMP1, d);
460 emit_store(jd, NULL, src, d);
463 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
464 if ((src->varkind != STACKVAR)) {
466 s1 = rd->interfaces[len][s2].regoff;
467 if (IS_FLT_DBL_TYPE(s2)) {
468 if (rd->interfaces[len][s2].flags & INMEMORY) {
469 if (IS_2_WORD_TYPE(s2))
470 M_DLD(d, REG_SP, s1 * 8);
472 M_FLD(d, REG_SP, s1 * 8);
475 if (IS_2_WORD_TYPE(s2))
482 if (rd->interfaces[len][s2].flags & INMEMORY)
483 M_LLD(d, REG_SP, s1 * 8);
488 emit_store(jd, NULL, src, d);
493 #if defined(ENABLE_LSRA)
496 /* walk through all instructions */
502 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
503 if (iptr->line != currentline) {
504 dseg_addlinenumber(cd, iptr->line);
505 currentline = iptr->line;
508 MCODECHECK(64); /* an instruction usually needs < 64 words */
512 case ICMD_NOP: /* ... ==> ... */
515 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
517 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
519 codegen_add_nullpointerexception_ref(cd);
523 /* constant operations ************************************************/
525 case ICMD_ICONST: /* ... ==> ..., constant */
526 /* op1 = 0, val.i = constant */
528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
529 ICONST(d, iptr->val.i);
530 emit_store(jd, iptr, iptr->dst, d);
533 case ICMD_LCONST: /* ... ==> ..., constant */
534 /* op1 = 0, val.l = constant */
536 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
537 LCONST(d, iptr->val.l);
538 emit_store(jd, iptr, iptr->dst, d);
541 case ICMD_FCONST: /* ... ==> ..., constant */
542 /* op1 = 0, val.f = constant */
544 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
545 disp = dseg_addfloat(cd, iptr->val.f);
546 M_FLD(d, REG_PV, disp);
547 emit_store(jd, iptr, iptr->dst, d);
550 case ICMD_DCONST: /* ... ==> ..., constant */
551 /* op1 = 0, val.d = constant */
553 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
554 disp = dseg_adddouble(cd, iptr->val.d);
555 M_DLD(d, REG_PV, disp);
556 emit_store(jd, iptr, iptr->dst, d);
559 case ICMD_ACONST: /* ... ==> ..., constant */
560 /* op1 = 0, val.a = constant */
562 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
564 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
565 disp = dseg_addaddress(cd, NULL);
567 codegen_addpatchref(cd, PATCHER_aconst,
568 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
571 if (opt_showdisassemble) {
575 M_ALD(d, REG_PV, disp);
578 if (iptr->val.a == NULL) {
579 M_INTMOVE(REG_ZERO, d);
581 disp = dseg_addaddress(cd, iptr->val.a);
582 M_ALD(d, REG_PV, disp);
585 emit_store(jd, iptr, iptr->dst, d);
589 /* load/store operations **********************************************/
591 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
592 /* op1 = local variable */
594 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
595 if ((iptr->dst->varkind == LOCALVAR) &&
596 (iptr->dst->varnum == iptr->op1))
598 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
599 if (var->flags & INMEMORY)
600 #if SIZEOF_VOID_P == 8
601 M_LLD(d, REG_SP, var->regoff * 8);
603 M_ILD(d, REG_SP, var->regoff * 8);
606 M_INTMOVE(var->regoff,d);
607 emit_store(jd, iptr, iptr->dst, d);
610 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
611 /* op1 = local variable */
613 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
614 if ((iptr->dst->varkind == LOCALVAR) &&
615 (iptr->dst->varnum == iptr->op1))
617 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
618 if (var->flags & INMEMORY)
619 M_LLD(d, REG_SP, var->regoff * 8);
621 M_INTMOVE(var->regoff,d);
622 emit_store(jd, iptr, iptr->dst, d);
625 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
626 /* op1 = local variable */
628 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
629 if ((iptr->dst->varkind == LOCALVAR) &&
630 (iptr->dst->varnum == iptr->op1))
632 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
633 if (var->flags & INMEMORY)
634 M_ALD(d, REG_SP, var->regoff * 8);
636 M_INTMOVE(var->regoff,d);
637 emit_store(jd, iptr, iptr->dst, d);
640 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
641 /* op1 = local variable */
643 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
644 if ((iptr->dst->varkind == LOCALVAR) &&
645 (iptr->dst->varnum == iptr->op1))
647 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
648 if (var->flags & INMEMORY)
649 M_FLD(d, REG_SP, var->regoff * 8);
651 M_FMOV(var->regoff, d);
652 emit_store(jd, iptr, iptr->dst, d);
655 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
656 /* op1 = local variable */
658 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
659 if ((iptr->dst->varkind == LOCALVAR) &&
660 (iptr->dst->varnum == iptr->op1))
662 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
663 if (var->flags & INMEMORY)
664 M_DLD(d, REG_SP, var->regoff * 8);
666 M_DMOV(var->regoff, d);
667 emit_store(jd, iptr, iptr->dst, d);
671 case ICMD_ISTORE: /* ..., value ==> ... */
672 /* op1 = local variable */
674 if ((src->varkind == LOCALVAR) &&
675 (src->varnum == iptr->op1))
677 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
678 if (var->flags & INMEMORY) {
679 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
680 #if SIZEOF_VOID_P == 8
681 M_LST(s1, REG_SP, var->regoff * 8);
683 M_IST(s1, REG_SP, var->regoff * 8);
686 s1 = emit_load_s1(jd, iptr, src, var->regoff);
687 M_INTMOVE(s1, var->regoff);
691 case ICMD_LSTORE: /* ..., value ==> ... */
692 /* op1 = local variable */
694 if ((src->varkind == LOCALVAR) &&
695 (src->varnum == iptr->op1))
697 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
698 if (var->flags & INMEMORY) {
699 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
700 M_LST(s1, REG_SP, var->regoff * 8);
702 s1 = emit_load_s1(jd, iptr, src, var->regoff);
703 M_INTMOVE(s1, var->regoff);
707 case ICMD_ASTORE: /* ..., value ==> ... */
708 /* op1 = local variable */
710 if ((src->varkind == LOCALVAR) &&
711 (src->varnum == iptr->op1))
713 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
714 if (var->flags & INMEMORY) {
715 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
716 M_AST(s1, REG_SP, var->regoff * 8);
718 s1 = emit_load_s1(jd, iptr, src, var->regoff);
719 M_INTMOVE(s1, var->regoff);
723 case ICMD_FSTORE: /* ..., value ==> ... */
724 /* op1 = local variable */
726 if ((src->varkind == LOCALVAR) &&
727 (src->varnum == iptr->op1))
729 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
730 if (var->flags & INMEMORY) {
731 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
732 M_FST(s1, REG_SP, var->regoff * 8);
734 s1 = emit_load_s1(jd, iptr, src, var->regoff);
735 M_FMOV(s1, var->regoff);
739 case ICMD_DSTORE: /* ..., value ==> ... */
740 /* op1 = local variable */
742 if ((src->varkind == LOCALVAR) &&
743 (src->varnum == iptr->op1))
745 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
746 if (var->flags & INMEMORY) {
747 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
748 M_DST(s1, REG_SP, var->regoff * 8);
750 s1 = emit_load_s1(jd, iptr, src, var->regoff);
751 M_DMOV(s1, var->regoff);
756 /* pop/dup/swap operations ********************************************/
758 /* attention: double and longs are only one entry in CACAO ICMDs */
760 case ICMD_POP: /* ..., value ==> ... */
761 case ICMD_POP2: /* ..., value, value ==> ... */
764 case ICMD_DUP: /* ..., a ==> ..., a, a */
765 M_COPY(src, iptr->dst);
768 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
770 M_COPY(src, iptr->dst);
771 M_COPY(src->prev, iptr->dst->prev);
772 M_COPY(iptr->dst, iptr->dst->prev->prev);
775 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
777 M_COPY(src, iptr->dst);
778 M_COPY(src->prev, iptr->dst->prev);
779 M_COPY(src->prev->prev, iptr->dst->prev->prev);
780 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
783 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
785 M_COPY(src, iptr->dst);
786 M_COPY(src->prev, iptr->dst->prev);
789 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
791 M_COPY(src, iptr->dst);
792 M_COPY(src->prev, iptr->dst->prev);
793 M_COPY(src->prev->prev, iptr->dst->prev->prev);
794 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
795 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
798 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
800 M_COPY(src, iptr->dst);
801 M_COPY(src->prev, iptr->dst->prev);
802 M_COPY(src->prev->prev, iptr->dst->prev->prev);
803 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
804 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
805 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
808 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
810 M_COPY(src, iptr->dst->prev);
811 M_COPY(src->prev, iptr->dst);
815 /* integer operations *************************************************/
817 case ICMD_INEG: /* ..., 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_ISUB(REG_ZERO, s1, d);
822 emit_store(jd, iptr, iptr->dst, d);
825 case ICMD_LNEG: /* ..., 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);
829 M_LSUB(REG_ZERO, s1, d);
830 emit_store(jd, iptr, iptr->dst, d);
833 case ICMD_I2L: /* ..., 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);
838 emit_store(jd, iptr, iptr->dst, d);
841 case ICMD_L2I: /* ..., 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_ISLL_IMM(s1, 0, d );
846 emit_store(jd, iptr, iptr->dst, d);
849 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
851 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
852 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
853 M_LSLL_IMM(s1, 56, d);
854 M_LSRA_IMM( d, 56, d);
855 emit_store(jd, iptr, iptr->dst, d);
858 case ICMD_INT2CHAR: /* ..., 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);
863 emit_store(jd, iptr, iptr->dst, d);
866 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
868 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
869 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
870 M_LSLL_IMM(s1, 48, d);
871 M_LSRA_IMM( d, 48, d);
872 emit_store(jd, iptr, iptr->dst, d);
876 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
878 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
879 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
880 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
882 emit_store(jd, iptr, iptr->dst, d);
885 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
886 /* val.i = constant */
888 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
889 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
890 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
891 M_IADD_IMM(s1, iptr->val.i, d);
893 ICONST(REG_ITMP2, iptr->val.i);
894 M_IADD(s1, REG_ITMP2, d);
896 emit_store(jd, iptr, iptr->dst, d);
899 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
901 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
902 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
903 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
905 emit_store(jd, iptr, iptr->dst, d);
908 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
909 /* val.l = constant */
911 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
912 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
913 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
914 M_LADD_IMM(s1, iptr->val.l, d);
916 LCONST(REG_ITMP2, iptr->val.l);
917 M_LADD(s1, REG_ITMP2, d);
919 emit_store(jd, iptr, iptr->dst, d);
922 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
924 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
925 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
926 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
928 emit_store(jd, iptr, iptr->dst, d);
931 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
932 /* val.i = constant */
934 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
935 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
936 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
937 M_IADD_IMM(s1, -iptr->val.i, d);
939 ICONST(REG_ITMP2, iptr->val.i);
940 M_ISUB(s1, REG_ITMP2, d);
942 emit_store(jd, iptr, iptr->dst, d);
945 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
947 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
948 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
949 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
951 emit_store(jd, iptr, iptr->dst, d);
954 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
955 /* val.l = constant */
957 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
958 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
959 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
960 M_LADD_IMM(s1, -iptr->val.l, d);
962 LCONST(REG_ITMP2, iptr->val.l);
963 M_LSUB(s1, REG_ITMP2, d);
965 emit_store(jd, iptr, iptr->dst, d);
968 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
970 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
971 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
972 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
977 emit_store(jd, iptr, iptr->dst, d);
980 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
981 /* val.i = constant */
983 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
984 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
985 ICONST(REG_ITMP2, iptr->val.i);
986 M_IMUL(s1, REG_ITMP2);
990 emit_store(jd, iptr, iptr->dst, d);
993 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
995 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
996 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
997 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1002 emit_store(jd, iptr, iptr->dst, d);
1005 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1006 /* val.l = constant */
1008 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1009 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1010 LCONST(REG_ITMP2, iptr->val.l);
1011 M_LMUL(s1, REG_ITMP2);
1015 emit_store(jd, iptr, iptr->dst, d);
1018 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1020 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1021 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1022 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1028 emit_store(jd, iptr, iptr->dst, d);
1031 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1033 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1034 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1035 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1041 emit_store(jd, iptr, iptr->dst, d);
1044 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1046 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1047 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1048 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1054 emit_store(jd, iptr, iptr->dst, d);
1057 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1059 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1060 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1061 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1067 emit_store(jd, iptr, iptr->dst, d);
1070 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1071 case ICMD_LDIVPOW2: /* val.i = constant */
1073 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1074 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1075 M_LSRA_IMM(s1, 63, REG_ITMP2);
1076 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1077 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1078 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1079 emit_store(jd, iptr, iptr->dst, d);
1082 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1084 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1085 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1086 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1088 emit_store(jd, iptr, iptr->dst, d);
1091 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1092 /* val.i = constant */
1094 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1095 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1096 M_ISLL_IMM(s1, iptr->val.i, d);
1097 emit_store(jd, iptr, iptr->dst, d);
1100 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1102 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1103 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1104 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1106 emit_store(jd, iptr, iptr->dst, d);
1109 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1110 /* val.i = constant */
1112 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1113 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1114 M_ISRA_IMM(s1, iptr->val.i, d);
1115 emit_store(jd, iptr, iptr->dst, d);
1118 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1120 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1121 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1122 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1124 emit_store(jd, iptr, iptr->dst, d);
1127 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1128 /* val.i = constant */
1130 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1131 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1132 M_ISRL_IMM(s1, iptr->val.i, d);
1133 emit_store(jd, iptr, iptr->dst, d);
1136 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1138 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1139 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1140 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1142 emit_store(jd, iptr, iptr->dst, d);
1145 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1146 /* val.i = constant */
1148 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1149 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1150 M_LSLL_IMM(s1, iptr->val.i, d);
1151 emit_store(jd, iptr, iptr->dst, d);
1154 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1156 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1157 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1158 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1160 emit_store(jd, iptr, iptr->dst, d);
1163 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1164 /* val.i = constant */
1166 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1167 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1168 M_LSRA_IMM(s1, iptr->val.i, d);
1169 emit_store(jd, iptr, iptr->dst, d);
1172 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1174 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1175 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1176 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1178 emit_store(jd, iptr, iptr->dst, d);
1181 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1182 /* val.i = constant */
1184 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1185 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1186 M_LSRL_IMM(s1, iptr->val.i, d);
1187 emit_store(jd, iptr, iptr->dst, d);
1190 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1193 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1194 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1195 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1197 emit_store(jd, iptr, iptr->dst, d);
1200 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1201 /* val.i = constant */
1203 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1204 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1205 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1206 M_AND_IMM(s1, iptr->val.i, d);
1208 ICONST(REG_ITMP2, iptr->val.i);
1209 M_AND(s1, REG_ITMP2, d);
1211 emit_store(jd, iptr, iptr->dst, d);
1214 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1215 /* val.i = constant */
1217 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1218 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1220 M_MOV(s1, REG_ITMP1);
1223 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1224 M_AND_IMM(s1, iptr->val.i, d);
1227 M_ISUB(REG_ZERO, s1, d);
1228 M_AND_IMM(d, iptr->val.i, d);
1230 ICONST(REG_ITMP2, iptr->val.i);
1231 M_AND(s1, REG_ITMP2, d);
1234 M_ISUB(REG_ZERO, s1, d);
1235 M_AND(d, REG_ITMP2, d);
1237 M_ISUB(REG_ZERO, d, d);
1238 emit_store(jd, iptr, iptr->dst, d);
1241 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1242 /* val.l = constant */
1244 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1245 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1246 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1247 M_AND_IMM(s1, iptr->val.l, d);
1249 LCONST(REG_ITMP2, iptr->val.l);
1250 M_AND(s1, REG_ITMP2, d);
1252 emit_store(jd, iptr, iptr->dst, d);
1255 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1256 /* val.l = constant */
1258 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1259 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1261 M_MOV(s1, REG_ITMP1);
1264 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1265 M_AND_IMM(s1, iptr->val.l, d);
1268 M_LSUB(REG_ZERO, s1, d);
1269 M_AND_IMM(d, iptr->val.l, d);
1271 LCONST(REG_ITMP2, iptr->val.l);
1272 M_AND(s1, REG_ITMP2, d);
1275 M_LSUB(REG_ZERO, s1, d);
1276 M_AND(d, REG_ITMP2, d);
1278 M_LSUB(REG_ZERO, d, d);
1279 emit_store(jd, iptr, iptr->dst, d);
1282 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1285 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1286 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1287 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1289 emit_store(jd, iptr, iptr->dst, d);
1292 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1293 /* val.i = constant */
1295 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1296 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1297 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1298 M_OR_IMM(s1, iptr->val.i, d);
1300 ICONST(REG_ITMP2, iptr->val.i);
1301 M_OR(s1, REG_ITMP2, d);
1303 emit_store(jd, iptr, iptr->dst, d);
1306 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1307 /* val.l = constant */
1309 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1310 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1311 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1312 M_OR_IMM(s1, iptr->val.l, d);
1314 LCONST(REG_ITMP2, iptr->val.l);
1315 M_OR(s1, REG_ITMP2, d);
1317 emit_store(jd, iptr, iptr->dst, d);
1320 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1323 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1325 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1327 emit_store(jd, iptr, iptr->dst, d);
1330 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1331 /* val.i = constant */
1333 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1334 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1335 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1336 M_XOR_IMM(s1, iptr->val.i, d);
1338 ICONST(REG_ITMP2, iptr->val.i);
1339 M_XOR(s1, REG_ITMP2, d);
1341 emit_store(jd, iptr, iptr->dst, d);
1344 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1345 /* val.l = constant */
1347 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1348 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1349 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1350 M_XOR_IMM(s1, iptr->val.l, d);
1352 LCONST(REG_ITMP2, iptr->val.l);
1353 M_XOR(s1, REG_ITMP2, d);
1355 emit_store(jd, iptr, iptr->dst, d);
1359 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1361 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1362 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1363 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1364 M_CMPLT(s1, s2, REG_ITMP3);
1365 M_CMPLT(s2, s1, REG_ITMP1);
1366 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1367 emit_store(jd, iptr, iptr->dst, d);
1371 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1372 /* op1 = variable, val.i = constant */
1374 var = &(rd->locals[iptr->op1][TYPE_INT]);
1375 if (var->flags & INMEMORY) {
1377 M_LLD(s1, REG_SP, var->regoff * 8);
1380 M_IADD_IMM(s1, iptr->val.i, s1);
1381 if (var->flags & INMEMORY)
1382 M_LST(s1, REG_SP, var->regoff * 8);
1386 /* floating operations ************************************************/
1388 case ICMD_FNEG: /* ..., 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_DNEG: /* ..., value ==> ..., - value */
1398 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1399 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1401 emit_store(jd, iptr, iptr->dst, d);
1404 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1406 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1407 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1408 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1410 emit_store(jd, iptr, iptr->dst, d);
1413 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1415 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1416 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1417 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1419 emit_store(jd, iptr, iptr->dst, d);
1422 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1424 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1425 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1426 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1428 emit_store(jd, iptr, iptr->dst, d);
1431 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1433 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1434 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1435 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1437 emit_store(jd, iptr, iptr->dst, d);
1440 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1442 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1443 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1444 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1446 emit_store(jd, iptr, iptr->dst, d);
1449 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1451 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1452 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1453 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1455 emit_store(jd, iptr, iptr->dst, d);
1458 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1460 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1461 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1462 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1464 emit_store(jd, iptr, iptr->dst, d);
1467 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1469 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1470 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1471 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1473 emit_store(jd, iptr, iptr->dst, d);
1477 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1479 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1480 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1481 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1482 M_FDIV(s1,s2, REG_FTMP3);
1483 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1484 M_CVTLF(REG_FTMP3, REG_FTMP3);
1485 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1486 M_FSUB(s1, REG_FTMP3, d);
1487 emit_store(jd, iptr, iptr->dst, d);
1490 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1492 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1493 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1494 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1495 M_DDIV(s1,s2, REG_FTMP3);
1496 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1497 M_CVTLD(REG_FTMP3, REG_FTMP3);
1498 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1499 M_DSUB(s1, REG_FTMP3, d);
1500 emit_store(jd, iptr, iptr->dst, d);
1504 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1506 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1507 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1510 emit_store(jd, iptr, iptr->dst, d);
1513 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1515 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1516 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1519 emit_store(jd, iptr, iptr->dst, d);
1523 /* XXX these do not work correctly */
1525 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1527 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1529 M_TRUNCFI(s1, REG_FTMP1);
1530 M_MOVDI(REG_FTMP1, d);
1532 emit_store(jd, iptr, iptr->dst, d);
1535 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1537 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1538 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1539 M_TRUNCDI(s1, REG_FTMP1);
1540 M_MOVDI(REG_FTMP1, d);
1542 emit_store(jd, iptr, iptr->dst, d);
1545 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1547 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1548 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1549 M_TRUNCFL(s1, REG_FTMP1);
1550 M_MOVDL(REG_FTMP1, d);
1552 emit_store(jd, iptr, iptr->dst, d);
1555 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1557 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1558 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1559 M_TRUNCDL(s1, REG_FTMP1);
1560 M_MOVDL(REG_FTMP1, d);
1562 emit_store(jd, iptr, iptr->dst, d);
1566 case ICMD_F2D: /* ..., 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_D2F: /* ..., value ==> ..., (double) value */
1576 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1577 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1579 emit_store(jd, iptr, iptr->dst, d);
1582 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1584 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1585 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1586 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1589 M_LADD_IMM(REG_ZERO, 1, d);
1593 M_LSUB_IMM(REG_ZERO, 1, d);
1594 M_CMOVT(REG_ZERO, d);
1595 emit_store(jd, iptr, iptr->dst, d);
1598 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1600 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1601 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1602 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1605 M_LADD_IMM(REG_ZERO, 1, d);
1609 M_LSUB_IMM(REG_ZERO, 1, d);
1610 M_CMOVT(REG_ZERO, d);
1611 emit_store(jd, iptr, iptr->dst, d);
1614 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1616 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1617 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1618 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1621 M_LSUB_IMM(REG_ZERO, 1, d);
1625 M_LADD_IMM(REG_ZERO, 1, d);
1626 M_CMOVT(REG_ZERO, d);
1627 emit_store(jd, iptr, iptr->dst, d);
1630 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1632 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1633 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1634 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1637 M_LSUB_IMM(REG_ZERO, 1, d);
1641 M_LADD_IMM(REG_ZERO, 1, d);
1642 M_CMOVT(REG_ZERO, d);
1643 emit_store(jd, iptr, iptr->dst, d);
1647 /* memory operations **************************************************/
1649 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1651 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1652 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1653 gen_nullptr_check(s1);
1654 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1655 emit_store(jd, iptr, iptr->dst, d);
1658 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1660 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1661 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1662 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1663 if (iptr->op1 == 0) {
1664 gen_nullptr_check(s1);
1667 M_AADD(s2, s1, REG_ITMP3);
1668 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1669 emit_store(jd, iptr, iptr->dst, d);
1672 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1674 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1675 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1676 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1677 if (iptr->op1 == 0) {
1678 gen_nullptr_check(s1);
1681 M_AADD(s2, s1, REG_ITMP3);
1682 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1683 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1684 emit_store(jd, iptr, iptr->dst, d);
1687 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1689 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1691 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1692 if (iptr->op1 == 0) {
1693 gen_nullptr_check(s1);
1696 M_AADD(s2, s1, REG_ITMP3);
1697 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1698 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1699 emit_store(jd, iptr, iptr->dst, d);
1702 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1704 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1705 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1706 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1707 if (iptr->op1 == 0) {
1708 gen_nullptr_check(s1);
1711 M_ASLL_IMM(s2, 2, REG_ITMP3);
1712 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1713 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1714 emit_store(jd, iptr, iptr->dst, d);
1717 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1719 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1720 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1721 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1722 if (iptr->op1 == 0) {
1723 gen_nullptr_check(s1);
1726 M_ASLL_IMM(s2, 3, REG_ITMP3);
1727 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1728 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1729 emit_store(jd, iptr, iptr->dst, d);
1732 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1734 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1736 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1737 if (iptr->op1 == 0) {
1738 gen_nullptr_check(s1);
1741 M_ASLL_IMM(s2, 2, REG_ITMP3);
1742 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1743 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1744 emit_store(jd, iptr, iptr->dst, d);
1747 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1749 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1750 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1751 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1752 if (iptr->op1 == 0) {
1753 gen_nullptr_check(s1);
1756 M_ASLL_IMM(s2, 3, REG_ITMP3);
1757 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1758 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1759 emit_store(jd, iptr, iptr->dst, d);
1762 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1764 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1765 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1766 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1767 if (iptr->op1 == 0) {
1768 gen_nullptr_check(s1);
1771 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1772 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1773 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1774 emit_store(jd, iptr, iptr->dst, d);
1778 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1780 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1781 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1782 if (iptr->op1 == 0) {
1783 gen_nullptr_check(s1);
1786 M_AADD(s2, s1, REG_ITMP1);
1787 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1788 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1791 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1792 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1794 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1795 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1796 if (iptr->op1 == 0) {
1797 gen_nullptr_check(s1);
1800 M_AADD(s2, s1, REG_ITMP1);
1801 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1802 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1803 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1806 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1808 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1809 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1810 if (iptr->op1 == 0) {
1811 gen_nullptr_check(s1);
1814 M_ASLL_IMM(s2, 2, REG_ITMP2);
1815 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1816 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1817 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1820 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1822 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1823 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1824 if (iptr->op1 == 0) {
1825 gen_nullptr_check(s1);
1828 M_ASLL_IMM(s2, 3, REG_ITMP2);
1829 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1830 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1831 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1834 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1836 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1837 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1838 if (iptr->op1 == 0) {
1839 gen_nullptr_check(s1);
1842 M_ASLL_IMM(s2, 2, REG_ITMP2);
1843 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1844 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1845 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1848 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1850 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1851 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1852 if (iptr->op1 == 0) {
1853 gen_nullptr_check(s1);
1856 M_ASLL_IMM(s2, 3, REG_ITMP2);
1857 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1858 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1859 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1863 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1865 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1866 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1867 if (iptr->op1 == 0) {
1868 gen_nullptr_check(s1);
1871 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1873 M_MOV(s1, rd->argintregs[0]);
1874 M_MOV(s3, rd->argintregs[1]);
1875 disp = dseg_addaddress(cd, BUILTIN_canstore);
1876 M_ALD(REG_ITMP3, REG_PV, disp);
1877 M_JSR(REG_RA, REG_ITMP3);
1880 M_BEQZ(REG_RESULT, 0);
1881 codegen_add_arraystoreexception_ref(cd);
1884 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1886 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1887 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1888 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1889 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1893 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1895 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1896 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1897 if (iptr->op1 == 0) {
1898 gen_nullptr_check(s1);
1901 M_AADD(s2, s1, REG_ITMP1);
1902 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1905 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1906 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1908 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1909 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1910 if (iptr->op1 == 0) {
1911 gen_nullptr_check(s1);
1914 M_AADD(s2, s1, REG_ITMP1);
1915 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1916 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1919 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1921 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1922 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1923 if (iptr->op1 == 0) {
1924 gen_nullptr_check(s1);
1927 M_ASLL_IMM(s2, 2, REG_ITMP2);
1928 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1929 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1932 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1934 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1935 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1936 if (iptr->op1 == 0) {
1937 gen_nullptr_check(s1);
1940 M_ASLL_IMM(s2, 3, REG_ITMP2);
1941 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1942 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1945 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1947 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1948 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1949 if (iptr->op1 == 0) {
1950 gen_nullptr_check(s1);
1953 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1954 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1955 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1959 case ICMD_GETSTATIC: /* ... ==> ..., value */
1960 /* op1 = type, val.a = field address */
1962 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1963 disp = dseg_addaddress(cd, NULL);
1965 codegen_addpatchref(cd, PATCHER_get_putstatic,
1966 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1968 if (opt_showdisassemble) {
1973 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1975 disp = dseg_addaddress(cd, &(fi->value));
1977 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1978 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1980 if (opt_showdisassemble) {
1986 M_ALD(REG_ITMP1, REG_PV, disp);
1987 switch (iptr->op1) {
1989 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1990 M_ILD_INTERN(d, REG_ITMP1, 0);
1991 emit_store(jd, iptr, iptr->dst, d);
1994 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1995 M_LLD_INTERN(d, REG_ITMP1, 0);
1996 emit_store(jd, iptr, iptr->dst, d);
1999 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2000 M_ALD_INTERN(d, REG_ITMP1, 0);
2001 emit_store(jd, iptr, iptr->dst, d);
2004 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2005 M_FLD_INTERN(d, REG_ITMP1, 0);
2006 emit_store(jd, iptr, iptr->dst, d);
2009 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2010 M_DLD_INTERN(d, REG_ITMP1, 0);
2011 emit_store(jd, iptr, iptr->dst, d);
2016 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2017 /* op1 = type, val.a = field address */
2019 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2020 disp = dseg_addaddress(cd, NULL);
2022 codegen_addpatchref(cd, PATCHER_get_putstatic,
2023 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2025 if (opt_showdisassemble) {
2030 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2032 disp = dseg_addaddress(cd, &(fi->value));
2034 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2035 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2037 if (opt_showdisassemble) {
2043 M_ALD(REG_ITMP1, REG_PV, disp);
2044 switch (iptr->op1) {
2046 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2047 M_IST_INTERN(s2, REG_ITMP1, 0);
2050 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2051 M_LST_INTERN(s2, REG_ITMP1, 0);
2054 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2055 M_AST_INTERN(s2, REG_ITMP1, 0);
2058 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2059 M_FST_INTERN(s2, REG_ITMP1, 0);
2062 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2063 M_DST_INTERN(s2, REG_ITMP1, 0);
2068 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2069 /* val = value (in current instruction) */
2070 /* op1 = type, val.a = field address (in */
2071 /* following NOP) */
2073 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2074 disp = dseg_addaddress(cd, NULL);
2076 codegen_addpatchref(cd, PATCHER_get_putstatic,
2077 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2079 if (opt_showdisassemble) {
2084 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2086 disp = dseg_addaddress(cd, &(fi->value));
2088 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2089 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2091 if (opt_showdisassemble) {
2097 M_ALD(REG_ITMP1, REG_PV, disp);
2098 switch (iptr->op1) {
2100 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2103 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2106 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2109 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2112 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2118 case ICMD_GETFIELD: /* ... ==> ..., value */
2119 /* op1 = type, val.i = field offset */
2121 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2122 gen_nullptr_check(s1);
2124 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2125 codegen_addpatchref(cd, PATCHER_get_putfield,
2126 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2128 if (opt_showdisassemble) {
2135 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2138 switch (iptr->op1) {
2140 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2142 emit_store(jd, iptr, iptr->dst, d);
2145 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2147 emit_store(jd, iptr, iptr->dst, d);
2150 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2152 emit_store(jd, iptr, iptr->dst, d);
2155 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2157 emit_store(jd, iptr, iptr->dst, d);
2160 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2162 emit_store(jd, iptr, iptr->dst, d);
2167 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2168 /* op1 = type, val.a = field address */
2170 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2171 gen_nullptr_check(s1);
2173 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2174 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2176 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2179 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2180 codegen_addpatchref(cd, PATCHER_get_putfield,
2181 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2183 if (opt_showdisassemble) {
2190 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2193 switch (iptr->op1) {
2212 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2213 /* val = value (in current instruction) */
2214 /* op1 = type, val.a = field address (in */
2215 /* following NOP) */
2217 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2218 gen_nullptr_check(s1);
2220 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2221 codegen_addpatchref(cd, PATCHER_get_putfield,
2222 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2224 if (opt_showdisassemble) {
2231 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2234 switch (iptr[1].op1) {
2236 M_IST(REG_ZERO, s1, a);
2239 M_LST(REG_ZERO, s1, a);
2242 M_AST(REG_ZERO, s1, a);
2245 M_FST(REG_ZERO, s1, a);
2248 M_DST(REG_ZERO, s1, a);
2254 /* branch operations **************************************************/
2256 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2258 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2259 M_INTMOVE(s1, REG_ITMP1_XPTR);
2261 #ifdef ENABLE_VERIFIER
2263 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2264 (unresolved_class *) iptr->val.a, 0);
2266 if (opt_showdisassemble) {
2270 #endif /* ENABLE_VERIFIER */
2272 disp = dseg_addaddress(cd, asm_handle_exception);
2273 M_ALD(REG_ITMP2, REG_PV, disp);
2274 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2276 M_NOP; /* nop ensures that XPC is less than the end */
2277 /* of basic block */
2281 case ICMD_GOTO: /* ... ==> ... */
2282 /* op1 = target JavaVM pc */
2284 codegen_addreference(cd, (basicblock *) iptr->target);
2289 case ICMD_JSR: /* ... ==> ... */
2290 /* op1 = target JavaVM pc */
2292 dseg_addtarget(cd, (basicblock *) iptr->target);
2293 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2294 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2298 case ICMD_RET: /* ... ==> ... */
2299 /* op1 = local variable */
2300 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2301 if (var->flags & INMEMORY) {
2302 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2310 case ICMD_IFNULL: /* ..., value ==> ... */
2311 /* op1 = target JavaVM pc */
2313 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2315 codegen_addreference(cd, (basicblock *) iptr->target);
2319 case ICMD_IFNONNULL: /* ..., value ==> ... */
2320 /* op1 = target JavaVM pc */
2322 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2324 codegen_addreference(cd, (basicblock *) iptr->target);
2328 case ICMD_IFEQ: /* ..., value ==> ... */
2329 /* op1 = target JavaVM pc, val.i = constant */
2331 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2332 if (iptr->val.i == 0) {
2335 ICONST(REG_ITMP2, iptr->val.i);
2336 M_BEQ(s1, REG_ITMP2, 0);
2338 codegen_addreference(cd, (basicblock *) iptr->target);
2342 case ICMD_IFLT: /* ..., value ==> ... */
2343 /* op1 = target JavaVM pc, val.i = constant */
2345 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2346 if (iptr->val.i == 0) {
2349 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2350 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2352 ICONST(REG_ITMP2, iptr->val.i);
2353 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2355 M_BNEZ(REG_ITMP1, 0);
2357 codegen_addreference(cd, (basicblock *) iptr->target);
2361 case ICMD_IFLE: /* ..., value ==> ... */
2362 /* op1 = target JavaVM pc, val.i = constant */
2364 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2365 if (iptr->val.i == 0) {
2369 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2370 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2371 M_BNEZ(REG_ITMP1, 0);
2374 ICONST(REG_ITMP2, iptr->val.i);
2375 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2376 M_BEQZ(REG_ITMP1, 0);
2379 codegen_addreference(cd, (basicblock *) iptr->target);
2383 case ICMD_IFNE: /* ..., value ==> ... */
2384 /* op1 = target JavaVM pc, val.i = constant */
2386 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2387 if (iptr->val.i == 0) {
2391 ICONST(REG_ITMP2, iptr->val.i);
2392 M_BNE(s1, REG_ITMP2, 0);
2394 codegen_addreference(cd, (basicblock *) iptr->target);
2398 case ICMD_IFGT: /* ..., value ==> ... */
2399 /* op1 = target JavaVM pc, val.i = constant */
2401 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2402 if (iptr->val.i == 0) {
2406 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2407 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2408 M_BEQZ(REG_ITMP1, 0);
2411 ICONST(REG_ITMP2, iptr->val.i);
2412 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2413 M_BNEZ(REG_ITMP1, 0);
2416 codegen_addreference(cd, (basicblock *) iptr->target);
2420 case ICMD_IFGE: /* ..., value ==> ... */
2421 /* op1 = target JavaVM pc, val.i = constant */
2423 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2424 if (iptr->val.i == 0) {
2428 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2429 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2432 ICONST(REG_ITMP2, iptr->val.i);
2433 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2435 M_BEQZ(REG_ITMP1, 0);
2437 codegen_addreference(cd, (basicblock *) iptr->target);
2441 case ICMD_IF_LEQ: /* ..., value ==> ... */
2442 /* op1 = target JavaVM pc, val.l = constant */
2444 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2445 if (iptr->val.l == 0) {
2449 LCONST(REG_ITMP2, iptr->val.l);
2450 M_BEQ(s1, REG_ITMP2, 0);
2452 codegen_addreference(cd, (basicblock *) iptr->target);
2456 case ICMD_IF_LLT: /* ..., value ==> ... */
2457 /* op1 = target JavaVM pc, val.l = constant */
2459 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2460 if (iptr->val.l == 0) {
2464 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2465 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2468 LCONST(REG_ITMP2, iptr->val.l);
2469 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2471 M_BNEZ(REG_ITMP1, 0);
2473 codegen_addreference(cd, (basicblock *) iptr->target);
2477 case ICMD_IF_LLE: /* ..., value ==> ... */
2478 /* op1 = target JavaVM pc, val.l = constant */
2480 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2481 if (iptr->val.l == 0) {
2485 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2486 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2487 M_BNEZ(REG_ITMP1, 0);
2490 LCONST(REG_ITMP2, iptr->val.l);
2491 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2492 M_BEQZ(REG_ITMP1, 0);
2495 codegen_addreference(cd, (basicblock *) iptr->target);
2499 case ICMD_IF_LNE: /* ..., value ==> ... */
2500 /* op1 = target JavaVM pc, val.l = constant */
2502 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2503 if (iptr->val.l == 0) {
2507 LCONST(REG_ITMP2, iptr->val.l);
2508 M_BNE(s1, REG_ITMP2, 0);
2510 codegen_addreference(cd, (basicblock *) iptr->target);
2514 case ICMD_IF_LGT: /* ..., value ==> ... */
2515 /* op1 = target JavaVM pc, val.l = constant */
2517 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2518 if (iptr->val.l == 0) {
2522 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2523 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2524 M_BEQZ(REG_ITMP1, 0);
2527 LCONST(REG_ITMP2, iptr->val.l);
2528 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2529 M_BNEZ(REG_ITMP1, 0);
2532 codegen_addreference(cd, (basicblock *) iptr->target);
2536 case ICMD_IF_LGE: /* ..., value ==> ... */
2537 /* op1 = target JavaVM pc, val.l = constant */
2539 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2540 if (iptr->val.l == 0) {
2544 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2545 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2548 LCONST(REG_ITMP2, iptr->val.l);
2549 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2551 M_BEQZ(REG_ITMP1, 0);
2553 codegen_addreference(cd, (basicblock *) iptr->target);
2557 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2558 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2559 case ICMD_IF_ACMPEQ:
2561 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2562 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2564 codegen_addreference(cd, (basicblock *) iptr->target);
2568 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2569 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2570 case ICMD_IF_ACMPNE:
2572 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2573 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2575 codegen_addreference(cd, (basicblock *) iptr->target);
2579 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2580 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2582 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2583 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2584 M_CMPLT(s1, s2, REG_ITMP1);
2585 M_BNEZ(REG_ITMP1, 0);
2586 codegen_addreference(cd, (basicblock *) iptr->target);
2590 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2591 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2593 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2594 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2595 M_CMPGT(s1, s2, REG_ITMP1);
2596 M_BNEZ(REG_ITMP1, 0);
2597 codegen_addreference(cd, (basicblock *) iptr->target);
2601 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2602 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2604 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2605 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2606 M_CMPGT(s1, s2, REG_ITMP1);
2607 M_BEQZ(REG_ITMP1, 0);
2608 codegen_addreference(cd, (basicblock *) iptr->target);
2612 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2613 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2615 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2616 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2617 M_CMPLT(s1, s2, REG_ITMP1);
2618 M_BEQZ(REG_ITMP1, 0);
2619 codegen_addreference(cd, (basicblock *) iptr->target);
2623 #ifdef CONDITIONAL_LOADCONST
2624 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2626 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2629 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2630 /* val.i = constant */
2632 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2633 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2635 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2636 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2637 M_CMPEQ(s1, REG_ZERO, d);
2638 emit_store(jd, iptr, iptr->dst, d);
2641 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2642 M_CMPEQ(s1, REG_ZERO, d);
2644 emit_store(jd, iptr, iptr->dst, d);
2648 M_MOV(s1, REG_ITMP1);
2651 ICONST(d, iptr[1].val.i);
2653 if ((s3 >= 0) && (s3 <= 255)) {
2654 M_CMOVEQ_IMM(s1, s3, d);
2656 ICONST(REG_ITMP3, s3);
2657 M_CMOVEQ(s1, REG_ITMP3, d);
2659 emit_store(jd, iptr, iptr->dst, d);
2662 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2663 /* val.i = constant */
2665 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2666 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2668 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2669 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2670 M_CMPEQ(s1, REG_ZERO, d);
2671 emit_store(jd, iptr, iptr->dst, d);
2674 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2675 M_CMPEQ(s1, REG_ZERO, d);
2677 emit_store(jd, iptr, iptr->dst, d);
2681 M_MOV(s1, REG_ITMP1);
2684 ICONST(d, iptr[1].val.i);
2686 if ((s3 >= 0) && (s3 <= 255)) {
2687 M_CMOVNE_IMM(s1, s3, d);
2689 ICONST(REG_ITMP3, s3);
2690 M_CMOVNE(s1, REG_ITMP3, d);
2692 emit_store(jd, iptr, iptr->dst, d);
2695 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2696 /* val.i = constant */
2698 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2699 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2701 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2702 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2703 M_CMPLT(s1, REG_ZERO, d);
2704 emit_store(jd, iptr, iptr->dst, d);
2707 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2708 M_CMPLE(REG_ZERO, s1, d);
2709 emit_store(jd, iptr, iptr->dst, d);
2713 M_MOV(s1, REG_ITMP1);
2716 ICONST(d, iptr[1].val.i);
2718 if ((s3 >= 0) && (s3 <= 255)) {
2719 M_CMOVLT_IMM(s1, s3, d);
2721 ICONST(REG_ITMP3, s3);
2722 M_CMOVLT(s1, REG_ITMP3, d);
2724 emit_store(jd, iptr, iptr->dst, d);
2727 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2728 /* val.i = constant */
2730 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2731 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2733 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2734 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2735 M_CMPLE(REG_ZERO, s1, d);
2736 emit_store(jd, iptr, iptr->dst, d);
2739 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2740 M_CMPLT(s1, REG_ZERO, d);
2741 emit_store(jd, iptr, iptr->dst, d);
2745 M_MOV(s1, REG_ITMP1);
2748 ICONST(d, iptr[1].val.i);
2750 if ((s3 >= 0) && (s3 <= 255)) {
2751 M_CMOVGE_IMM(s1, s3, d);
2753 ICONST(REG_ITMP3, s3);
2754 M_CMOVGE(s1, REG_ITMP3, d);
2756 emit_store(jd, iptr, iptr->dst, d);
2759 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2760 /* val.i = constant */
2762 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2763 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2765 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2766 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2767 M_CMPLT(REG_ZERO, s1, d);
2768 emit_store(jd, iptr, iptr->dst, d);
2771 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2772 M_CMPLE(s1, REG_ZERO, d);
2773 emit_store(jd, iptr, iptr->dst, d);
2777 M_MOV(s1, REG_ITMP1);
2780 ICONST(d, iptr[1].val.i);
2782 if ((s3 >= 0) && (s3 <= 255)) {
2783 M_CMOVGT_IMM(s1, s3, d);
2785 ICONST(REG_ITMP3, s3);
2786 M_CMOVGT(s1, REG_ITMP3, d);
2788 emit_store(jd, iptr, iptr->dst, d);
2791 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2792 /* val.i = constant */
2794 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2795 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2797 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2798 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2799 M_CMPLE(s1, REG_ZERO, d);
2800 emit_store(jd, iptr, iptr->dst, d);
2803 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2804 M_CMPLT(REG_ZERO, s1, d);
2805 emit_store(jd, iptr, iptr->dst, d);
2809 M_MOV(s1, REG_ITMP1);
2812 ICONST(d, iptr[1].val.i);
2814 if ((s3 >= 0) && (s3 <= 255)) {
2815 M_CMOVLE_IMM(s1, s3, d);
2817 ICONST(REG_ITMP3, s3);
2818 M_CMOVLE(s1, REG_ITMP3, d);
2820 emit_store(jd, iptr, iptr->dst, d);
2825 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2828 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2829 M_INTMOVE(s1, REG_RESULT);
2830 goto nowperformreturn;
2832 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2834 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2835 M_INTMOVE(s1, REG_RESULT);
2837 #ifdef ENABLE_VERIFIER
2839 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2840 (unresolved_class *) iptr->val.a, 0);
2842 if (opt_showdisassemble) {
2846 #endif /* ENABLE_VERIFIER */
2847 goto nowperformreturn;
2849 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2851 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2852 M_FLTMOVE(s1, REG_FRESULT);
2853 goto nowperformreturn;
2855 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2857 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2858 M_DBLMOVE(s1, REG_FRESULT);
2859 goto nowperformreturn;
2861 case ICMD_RETURN: /* ... ==> ... */
2867 p = parentargs_base;
2869 /* call trace function */
2871 if (opt_verbosecall) {
2872 M_LDA(REG_SP, REG_SP, -3 * 8);
2873 M_LST(REG_RA, REG_SP, 0 * 8);
2874 M_LST(REG_RESULT, REG_SP, 1 * 8);
2875 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2877 disp = dseg_addaddress(cd, m);
2878 M_ALD(rd->argintregs[0], REG_PV, disp);
2879 M_MOV(REG_RESULT, rd->argintregs[1]);
2880 M_DMOV(REG_FRESULT, rd->argfltregs[2]);
2881 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2883 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2884 M_ALD(REG_ITMP3, REG_PV, disp);
2885 M_JSR(REG_RA, REG_ITMP3);
2888 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2889 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2890 M_LLD(REG_RA, REG_SP, 0 * 8);
2891 M_LDA(REG_SP, REG_SP, 3 * 8);
2894 #if defined(ENABLE_THREADS)
2895 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2896 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2897 M_ALD(REG_ITMP3, REG_PV, disp);
2899 /* we need to save the proper return value */
2901 switch (iptr->opc) {
2905 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2906 M_JSR(REG_RA, REG_ITMP3);
2907 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2911 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2912 M_JSR(REG_RA, REG_ITMP3);
2913 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2916 M_JSR(REG_RA, REG_ITMP3);
2917 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2921 /* and now restore the proper return value */
2923 switch (iptr->opc) {
2927 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2931 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2937 /* restore return address */
2939 if (!jd->isleafmethod) {
2940 p--; M_ALD(REG_RA, REG_SP, p * 8);
2943 /* restore saved registers */
2945 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2946 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2948 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2949 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2952 /* deallocate stack and return */
2954 if (parentargs_base) {
2957 disp = parentargs_base * 8;
2958 lo = (short) (disp);
2959 hi = (short) (((disp) - lo) >> 16);
2963 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2965 M_LUI(REG_ITMP3,hi);
2966 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2968 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2981 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2986 tptr = (void **) iptr->target;
2988 s4ptr = iptr->val.a;
2989 l = s4ptr[1]; /* low */
2990 i = s4ptr[2]; /* high */
2992 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2994 {M_INTMOVE(s1, REG_ITMP1);}
2995 else if (l <= 32768) {
2996 M_IADD_IMM(s1, -l, REG_ITMP1);
2999 ICONST(REG_ITMP2, l);
3000 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3006 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3007 M_BEQZ(REG_ITMP2, 0);
3008 codegen_addreference(cd, (basicblock *) tptr[0]);
3009 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
3011 /* build jump table top down and use address of lowest entry */
3013 /* s4ptr += 3 + i; */
3017 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3018 dseg_addtarget(cd, (basicblock *) tptr[0]);
3023 /* length of dataseg after last dseg_addtarget is used by load */
3025 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3026 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3033 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3035 s4 i, /*l, */val, *s4ptr;
3038 tptr = (void **) iptr->target;
3040 s4ptr = iptr->val.a;
3041 /*l = s4ptr[0];*/ /* default */
3042 i = s4ptr[1]; /* count */
3044 MCODECHECK((i<<2)+8);
3045 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3051 ICONST(REG_ITMP2, val);
3052 M_BEQ(s1, REG_ITMP2, 0);
3053 codegen_addreference(cd, (basicblock *) tptr[0]);
3058 tptr = (void **) iptr->target;
3059 codegen_addreference(cd, (basicblock *) tptr[0]);
3066 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3067 /* op1 = arg count val.a = builtintable entry */
3073 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3074 /* op1 = arg count, val.a = method pointer */
3076 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3077 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3078 case ICMD_INVOKEINTERFACE:
3080 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3081 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3085 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3086 md = lm->parseddesc;
3090 s3 = md->paramcount;
3092 MCODECHECK((s3 << 1) + 64);
3094 /* copy arguments to registers or stack location */
3096 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3097 if (src->varkind == ARGVAR)
3099 if (IS_INT_LNG_TYPE(src->type)) {
3100 if (!md->params[s3].inmemory) {
3101 s1 = rd->argintregs[md->params[s3].regoff];
3102 d = emit_load_s1(jd, iptr, src, s1);
3105 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3106 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3110 if (!md->params[s3].inmemory) {
3111 s1 = rd->argfltregs[md->params[s3].regoff];
3112 d = emit_load_s1(jd, iptr, src, s1);
3113 if (IS_2_WORD_TYPE(src->type))
3119 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3120 if (IS_2_WORD_TYPE(src->type))
3121 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3123 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3128 switch (iptr->opc) {
3130 disp = dseg_addaddress(cd, bte->fp);
3131 d = md->returntype.type;
3133 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3134 M_JSR(REG_RA, REG_ITMP3);
3136 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3137 M_LDA(REG_PV, REG_RA, -disp);
3139 /* if op1 == true, we need to check for an exception */
3141 if (iptr->op1 == true) {
3142 M_BEQZ(REG_RESULT, 0);
3143 codegen_add_fillinstacktrace_ref(cd);
3148 case ICMD_INVOKESPECIAL:
3149 M_BEQZ(rd->argintregs[0], 0);
3150 codegen_add_nullpointerexception_ref(cd);
3154 case ICMD_INVOKESTATIC:
3156 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3158 disp = dseg_addaddress(cd, NULL);
3160 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3163 if (opt_showdisassemble) {
3167 d = um->methodref->parseddesc.md->returntype.type;
3170 disp = dseg_addaddress(cd, lm->stubroutine);
3171 d = lm->parseddesc->returntype.type;
3174 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3175 M_JSR(REG_RA, REG_PV);
3177 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3178 M_LDA(REG_PV, REG_RA, -disp);
3181 case ICMD_INVOKEVIRTUAL:
3182 gen_nullptr_check(rd->argintregs[0]);
3185 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3187 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3189 if (opt_showdisassemble) {
3194 d = um->methodref->parseddesc.md->returntype.type;
3197 s1 = OFFSET(vftbl_t, table[0]) +
3198 sizeof(methodptr) * lm->vftblindex;
3199 d = lm->parseddesc->returntype.type;
3202 M_ALD(REG_METHODPTR, rd->argintregs[0],
3203 OFFSET(java_objectheader, vftbl));
3204 M_ALD(REG_PV, REG_METHODPTR, s1);
3205 M_JSR(REG_RA, REG_PV);
3207 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3208 M_LDA(REG_PV, REG_RA, -disp);
3211 case ICMD_INVOKEINTERFACE:
3212 gen_nullptr_check(rd->argintregs[0]);
3215 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3217 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3219 if (opt_showdisassemble) {
3225 d = um->methodref->parseddesc.md->returntype.type;
3228 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3229 sizeof(methodptr*) * lm->class->index;
3231 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3233 d = lm->parseddesc->returntype.type;
3236 M_ALD(REG_METHODPTR, rd->argintregs[0],
3237 OFFSET(java_objectheader, vftbl));
3238 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3239 M_ALD(REG_PV, REG_METHODPTR, s2);
3240 M_JSR(REG_RA, REG_PV);
3242 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3243 M_LDA(REG_PV, REG_RA, -disp);
3247 /* d contains return type */
3249 if (d != TYPE_VOID) {
3250 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3251 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3252 M_INTMOVE(REG_RESULT, s1);
3254 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3255 if (IS_2_WORD_TYPE(iptr->dst->type))
3256 M_DMOV(REG_FRESULT, s1);
3258 M_FMOV(REG_FRESULT, s1);
3260 emit_store(jd, iptr, iptr->dst, s1);
3265 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3266 /* op1: 0 == array, 1 == class */
3267 /* val.a: (classinfo*) superclass */
3269 /* superclass is an interface:
3271 * OK if ((sub == NULL) ||
3272 * (sub->vftbl->interfacetablelength > super->index) &&
3273 * (sub->vftbl->interfacetable[-super->index] != NULL));
3275 * superclass is a class:
3277 * OK if ((sub == NULL) || (0
3278 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3279 * super->vftbl->diffvall));
3282 if (iptr->op1 == 1) {
3284 vftbl_t *supervftbl;
3287 super = (classinfo *) iptr->val.a;
3289 if (super == NULL) {
3294 superindex = super->index;
3295 supervftbl = super->vftbl;
3298 #if defined(ENABLE_THREADS)
3299 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3302 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3304 /* calculate interface checkcast code size */
3308 s2 += (opt_showdisassemble ? 2 : 0);
3310 /* calculate class checkcast code size */
3312 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3314 s3 += (opt_showdisassemble ? 2 : 0);
3316 /* if class is not resolved, check which code to call */
3318 if (super == NULL) {
3319 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3322 disp = dseg_adds4(cd, 0); /* super->flags */
3324 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3325 (constant_classref *) iptr->target,
3328 if (opt_showdisassemble) {
3332 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3333 M_ILD(REG_ITMP2, REG_PV, disp);
3334 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3335 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3339 /* interface checkcast code */
3341 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3342 if (super != NULL) {
3347 codegen_addpatchref(cd,
3348 PATCHER_checkcast_instanceof_interface,
3349 (constant_classref *) iptr->target,
3352 if (opt_showdisassemble) {
3357 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3358 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3359 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3360 M_BLEZ(REG_ITMP3, 0);
3361 codegen_add_classcastexception_ref(cd, s1);
3363 M_ALD(REG_ITMP3, REG_ITMP2,
3364 OFFSET(vftbl_t, interfacetable[0]) -
3365 superindex * sizeof(methodptr*));
3366 M_BEQZ(REG_ITMP3, 0);
3367 codegen_add_classcastexception_ref(cd, s1);
3370 if (super == NULL) {
3376 /* class checkcast code */
3378 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3379 disp = dseg_addaddress(cd, (void *) supervftbl);
3381 if (super != NULL) {
3386 codegen_addpatchref(cd,
3387 PATCHER_checkcast_instanceof_class,
3388 (constant_classref *) iptr->target,
3391 if (opt_showdisassemble) {
3396 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3397 M_ALD(REG_ITMP3, REG_PV, disp);
3398 #if defined(ENABLE_THREADS)
3399 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3401 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3402 /* if (s1 != REG_ITMP1) { */
3403 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3404 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3405 /* #if defined(ENABLE_THREADS) */
3406 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3408 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3410 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3411 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3412 M_ALD(REG_ITMP3, REG_PV, disp);
3413 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3414 #if defined(ENABLE_THREADS)
3415 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3418 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3419 M_BNEZ(REG_ITMP3, 0);
3420 codegen_add_classcastexception_ref(cd, s1);
3424 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3427 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3428 M_INTMOVE(s1, rd->argintregs[0]);
3430 disp = dseg_addaddress(cd, iptr->val.a);
3432 if (iptr->val.a == NULL) {
3433 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3434 (constant_classref *) iptr->target,
3437 if (opt_showdisassemble) {
3442 M_ALD(rd->argintregs[1], REG_PV, disp);
3443 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3444 M_ALD(REG_ITMP3, REG_PV, disp);
3445 M_JSR(REG_RA, REG_ITMP3);
3448 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3449 M_BEQZ(REG_RESULT, 0);
3450 codegen_add_classcastexception_ref(cd, s1);
3453 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3457 emit_store(jd, iptr, iptr->dst, d);
3460 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3461 /* op1: 0 == array, 1 == class */
3462 /* val.a: (classinfo*) superclass */
3464 /* superclass is an interface:
3466 * return (sub != NULL) &&
3467 * (sub->vftbl->interfacetablelength > super->index) &&
3468 * (sub->vftbl->interfacetable[-super->index] != NULL);
3470 * superclass is a class:
3472 * return ((sub != NULL) && (0
3473 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3474 * super->vftbl->diffvall));
3479 vftbl_t *supervftbl;
3482 super = (classinfo *) iptr->val.a;
3484 if (super == NULL) {
3489 superindex = super->index;
3490 supervftbl = super->vftbl;
3493 #if defined(ENABLE_THREADS)
3494 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3497 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3498 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3500 M_MOV(s1, REG_ITMP1);
3504 /* calculate interface instanceof code size */
3508 s2 += (opt_showdisassemble ? 2 : 0);
3510 /* calculate class instanceof code size */
3514 s3 += (opt_showdisassemble ? 2 : 0);
3518 /* if class is not resolved, check which code to call */
3520 if (super == NULL) {
3521 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3524 disp = dseg_adds4(cd, 0); /* super->flags */
3526 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3527 (constant_classref *) iptr->target, disp);
3529 if (opt_showdisassemble) {
3533 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3534 M_ILD(REG_ITMP3, REG_PV, disp);
3535 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3536 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3540 /* interface instanceof code */
3542 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3543 if (super != NULL) {
3548 codegen_addpatchref(cd,
3549 PATCHER_checkcast_instanceof_interface,
3550 (constant_classref *) iptr->target, 0);
3552 if (opt_showdisassemble) {
3557 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3558 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3559 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3560 M_BLEZ(REG_ITMP3, 3);
3562 M_ALD(REG_ITMP1, REG_ITMP1,
3563 OFFSET(vftbl_t, interfacetable[0]) -
3564 superindex * sizeof(methodptr*));
3565 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3567 if (super == NULL) {
3573 /* class instanceof code */
3575 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3576 disp = dseg_addaddress(cd, supervftbl);
3578 if (super != NULL) {
3583 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3584 (constant_classref *) iptr->target,
3587 if (opt_showdisassemble) {
3592 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3593 M_ALD(REG_ITMP2, REG_PV, disp);
3594 #if defined(ENABLE_THREADS)
3595 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3597 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3598 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3599 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3600 #if defined(ENABLE_THREADS)
3601 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3603 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3604 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3607 emit_store(jd, iptr, iptr->dst, d);
3611 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3612 /* op1 = dimension, val.a = class */
3614 /* check for negative sizes and copy sizes to stack if necessary */
3616 MCODECHECK((iptr->op1 << 1) + 64);
3618 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3619 /* copy SAVEDVAR sizes to stack */
3621 if (src->varkind != ARGVAR) {
3622 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3623 M_LST(s2, REG_SP, s1 * 8);
3627 /* a0 = dimension count */
3629 ICONST(rd->argintregs[0], iptr->op1);
3631 /* is patcher function set? */
3633 if (iptr->val.a == NULL) {
3634 disp = dseg_addaddress(cd, NULL);
3636 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3637 (constant_classref *) iptr->target, disp);
3639 if (opt_showdisassemble) {
3644 disp = dseg_addaddress(cd, iptr->val.a);
3647 /* a1 = arraydescriptor */
3649 M_ALD(rd->argintregs[1], REG_PV, disp);
3651 /* a2 = pointer to dimensions = stack pointer */
3653 M_INTMOVE(REG_SP, rd->argintregs[2]);
3655 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3656 M_ALD(REG_ITMP3, REG_PV, disp);
3657 M_JSR(REG_RA, REG_ITMP3);
3660 /* check for exception before result assignment */
3662 M_BEQZ(REG_RESULT, 0);
3663 codegen_add_fillinstacktrace_ref(cd);
3666 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3667 M_INTMOVE(REG_RESULT, d);
3668 emit_store(jd, iptr, iptr->dst, d);
3672 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3676 } /* for instruction */
3678 /* copy values to interface registers */
3680 src = bptr->outstack;
3681 len = bptr->outdepth;
3683 #if defined(ENABLE_LSRA)
3688 if ((src->varkind != STACKVAR)) {
3690 if (IS_FLT_DBL_TYPE(s2)) {
3691 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3692 if (rd->interfaces[len][s2].flags & INMEMORY) {
3693 if (IS_2_WORD_TYPE(s2))
3694 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3696 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3699 if (IS_2_WORD_TYPE(s2))
3700 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3702 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3706 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3707 if (rd->interfaces[len][s2].flags & INMEMORY)
3708 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3710 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3716 /* At the end of a basic block we may have to append some nops,
3717 because the patcher stub calling code might be longer than the
3718 actual instruction. So codepatching does not change the
3719 following block unintentionally. */
3721 if (cd->mcodeptr < cd->lastmcodeptr) {
3722 while (cd->mcodeptr < cd->lastmcodeptr)
3726 } /* if (bptr -> flags >= BBREACHED) */
3727 } /* for basic block */
3729 dseg_createlinenumbertable(cd);
3732 /* generate exception and patcher stubs */
3741 savedmcodeptr = NULL;
3743 /* generate exception stubs */
3745 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3746 gen_resolvebranch(cd->mcodebase + eref->branchpos,
3747 eref->branchpos, cd->mcodeptr - cd->mcodebase);
3751 /* Check if the exception is an
3752 ArrayIndexOutOfBoundsException. If so, move index register
3755 if (eref->reg != -1)
3756 M_MOV(eref->reg, REG_ITMP1);
3758 /* calcuate exception address */
3760 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3762 /* move function to call into REG_ITMP3 */
3764 disp = dseg_addaddress(cd, eref->function);
3765 M_ALD(REG_ITMP3, REG_PV, disp);
3767 if (savedmcodeptr != NULL) {
3768 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3773 savedmcodeptr = cd->mcodeptr;
3775 M_MOV(REG_PV, rd->argintregs[0]);
3776 M_MOV(REG_SP, rd->argintregs[1]);
3778 if (jd->isleafmethod)
3779 M_MOV(REG_RA, rd->argintregs[2]);
3781 M_ALD(rd->argintregs[2],
3782 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3784 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3785 M_MOV(REG_ITMP1, rd->argintregs[4]);
3787 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3788 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3790 if (jd->isleafmethod)
3791 M_AST(REG_RA, REG_SP, 1 * 8);
3793 M_JSR(REG_RA, REG_ITMP3);
3795 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3797 if (jd->isleafmethod)
3798 M_ALD(REG_RA, REG_SP, 1 * 8);
3800 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3801 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3803 a = dseg_addaddress(cd, asm_handle_exception);
3804 M_ALD(REG_ITMP3, REG_PV, a);
3811 /* generate code patching stub call code */
3813 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3814 /* check code segment size */
3818 /* Get machine code which is patched back in later. The
3819 call is 2 instruction words long. */
3821 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3823 /* We need to split this, because an unaligned 8 byte read
3824 causes a SIGSEGV. */
3826 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
3827 ((u4 *) tmpmcodeptr)[0];
3829 /* Patch in the call to call the following code (done at
3832 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3833 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3835 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3837 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3839 new_internalerror("Jump offset is out of range: %d > +/-%d",
3847 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3849 /* create stack frame */
3851 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3853 /* calculate return address and move it onto the stack */
3855 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3856 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3858 /* move pointer to java_objectheader onto stack */
3860 #if defined(ENABLE_THREADS)
3861 /* create a virtual java_objectheader */
3863 (void) dseg_addaddress(cd, NULL); /* flcword */
3864 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3865 disp = dseg_addaddress(cd, NULL); /* vftbl */
3867 M_LDA(REG_ITMP3, REG_PV, disp);
3868 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3873 /* move machine code onto stack */
3875 disp = dseg_adds8(cd, mcode);
3876 M_LLD(REG_ITMP3, REG_PV, disp);
3877 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3879 /* move class/method/field reference onto stack */
3881 disp = dseg_addaddress(cd, pref->ref);
3882 M_ALD(REG_ITMP3, REG_PV, disp);
3883 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3885 /* move data segment displacement onto stack */
3887 disp = dseg_adds4(cd, pref->disp);
3888 M_ILD(REG_ITMP3, REG_PV, disp);
3889 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3891 /* move patcher function pointer onto stack */
3893 disp = dseg_addaddress(cd, pref->patcher);
3894 M_ALD(REG_ITMP3, REG_PV, disp);
3895 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3897 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3898 M_ALD(REG_ITMP3, REG_PV, disp);
3903 /* generate replacement-out stubs */
3908 replacementpoint = jd->code->rplpoints;
3910 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3911 /* check code segment size */
3915 /* note start of stub code */
3917 replacementpoint->outcode = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
3919 /* make machine code for patching */
3921 savedmcodeptr = cd->mcodeptr;
3922 cd->mcodeptr = (u1 *) &(replacementpoint->mcode);
3924 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3925 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3927 new_internalerror("Jump offset is out of range: %d > +/-%d",
3932 M_NOP; /* delay slot */
3934 cd->mcodeptr = savedmcodeptr;
3936 /* create stack frame - 16-byte aligned */
3938 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3940 /* push address of `rplpoint` struct */
3942 disp = dseg_addaddress(cd, replacementpoint);
3943 M_ALD(REG_ITMP3, REG_PV, disp);
3944 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3946 /* jump to replacement function */
3948 disp = dseg_addaddress(cd, asm_replacement_out);
3949 M_ALD(REG_ITMP3, REG_PV, disp);
3951 M_NOP; /* delay slot */
3958 /* everything's ok */
3964 /* createcompilerstub **********************************************************
3966 Creates a stub routine which calls the compiler.
3968 *******************************************************************************/
3970 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3971 #define COMPILERSTUB_CODESIZE 4 * 4
3973 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3976 u1 *createcompilerstub(methodinfo *m)
3978 u1 *s; /* memory to hold the stub */
3984 s = CNEW(u1, COMPILERSTUB_SIZE);
3986 /* set data pointer and code pointer */
3989 s = s + COMPILERSTUB_DATASIZE;
3991 /* mark start of dump memory area */
3993 dumpsize = dump_size();
3995 cd = DNEW(codegendata);
3998 /* Store the codeinfo pointer in the same place as in the
3999 methodheader for compiled methods. */
4001 code = code_codeinfo_new(m);
4003 d[0] = (ptrint) asm_call_jit_compiler;
4005 d[2] = (ptrint) code;
4007 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
4008 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
4012 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
4014 #if defined(ENABLE_STATISTICS)
4016 count_cstub_len += COMPILERSTUB_SIZE;
4019 /* release dump area */
4021 dump_release(dumpsize);
4027 /* createnativestub ************************************************************
4029 Creates a stub routine which calls a native method.
4031 *******************************************************************************/
4033 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4039 s4 stackframesize; /* size of stackframe if needed */
4042 s4 i, j; /* count variables */
4045 s4 funcdisp; /* displacement of the function */
4047 /* get required compiler data */
4054 /* initialize variables */
4057 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4059 /* calculate stack frame size */
4062 1 + /* return address */
4063 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4064 sizeof(localref_table) / SIZEOF_VOID_P +
4065 md->paramcount + /* for saving arguments over calls */
4066 1 + /* for saving return address */
4069 /* create method header */
4071 #if SIZEOF_VOID_P == 4
4072 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
4074 (void) dseg_addaddress(cd, code); /* MethodPointer */
4075 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4076 (void) dseg_adds4(cd, 0); /* IsSync */
4077 (void) dseg_adds4(cd, 0); /* IsLeaf */
4078 (void) dseg_adds4(cd, 0); /* IntSave */
4079 (void) dseg_adds4(cd, 0); /* FltSave */
4080 (void) dseg_addlinenumbertablesize(cd);
4081 (void) dseg_adds4(cd, 0); /* ExTableSize */
4083 /* generate stub code */
4085 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
4086 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
4088 #if !defined(NDEBUG)
4089 /* call trace function */
4091 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
4092 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4094 /* save integer argument registers */
4096 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4097 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4098 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4100 /* save and copy float arguments into integer registers */
4102 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4103 t = md->paramtypes[i].type;
4105 if (IS_FLT_DBL_TYPE(t)) {
4106 if (IS_2_WORD_TYPE(t)) {
4107 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4108 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4110 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4111 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4116 disp = dseg_addaddress(cd, m);
4117 M_ALD(REG_ITMP1, REG_PV, disp);
4118 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4119 disp = dseg_addaddress(cd, builtin_trace_args);
4120 M_ALD(REG_ITMP3, REG_PV, disp);
4121 M_JSR(REG_RA, REG_ITMP3);
4124 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4125 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4126 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4128 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4129 t = md->paramtypes[i].type;
4131 if (IS_FLT_DBL_TYPE(t)) {
4132 if (IS_2_WORD_TYPE(t))
4133 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4135 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4139 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4141 #endif /* !defined(NDEBUG) */
4143 /* get function address (this must happen before the stackframeinfo) */
4145 funcdisp = dseg_addaddress(cd, f);
4147 #if !defined(WITH_STATIC_CLASSPATH)
4149 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4151 if (opt_showdisassemble) {
4157 /* save integer and float argument registers */
4159 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4160 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4161 M_LST(rd->argintregs[i], REG_SP, j * 8);
4166 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4167 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4168 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4173 /* prepare data structures for native function call */
4175 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4176 M_MOV(REG_PV, rd->argintregs[1]);
4177 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4178 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4179 disp = dseg_addaddress(cd, codegen_start_native_call);
4180 M_ALD(REG_ITMP3, REG_PV, disp);
4181 M_JSR(REG_RA, REG_ITMP3);
4182 M_NOP; /* XXX fill me! */
4184 /* restore integer and float argument registers */
4186 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4187 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4188 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4193 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4194 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4195 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4200 /* copy or spill arguments to new locations */
4202 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4203 t = md->paramtypes[i].type;
4205 if (IS_INT_LNG_TYPE(t)) {
4206 if (!md->params[i].inmemory) {
4207 s1 = rd->argintregs[md->params[i].regoff];
4209 if (!nmd->params[j].inmemory) {
4210 s2 = rd->argintregs[nmd->params[j].regoff];
4213 s2 = nmd->params[j].regoff;
4214 M_AST(s1, REG_SP, s2 * 8);
4218 s1 = md->params[i].regoff + stackframesize;
4219 s2 = nmd->params[j].regoff;
4220 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4221 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4225 if (!md->params[i].inmemory) {
4226 s1 = rd->argfltregs[md->params[i].regoff];
4228 if (!nmd->params[j].inmemory) {
4229 s2 = rd->argfltregs[nmd->params[j].regoff];
4230 if (IS_2_WORD_TYPE(t))
4236 s2 = nmd->params[j].regoff;
4237 if (IS_2_WORD_TYPE(t))
4238 M_DST(s1, REG_SP, s2 * 8);
4240 M_FST(s1, REG_SP, s2 * 8);
4244 s1 = md->params[i].regoff + stackframesize;
4245 s2 = nmd->params[j].regoff;
4246 if (IS_2_WORD_TYPE(t)) {
4247 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4248 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4250 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4251 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4257 /* put class into second argument register */
4259 if (m->flags & ACC_STATIC) {
4260 disp = dseg_addaddress(cd, m->class);
4261 M_ALD(rd->argintregs[1], REG_PV, disp);
4264 /* put env into first argument register */
4266 disp = dseg_addaddress(cd, _Jv_env);
4267 M_ALD(rd->argintregs[0], REG_PV, disp);
4269 /* do the native function call */
4271 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4272 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4273 M_NOP; /* delay slot */
4275 /* save return value */
4277 if (md->returntype.type != TYPE_VOID) {
4278 if (IS_INT_LNG_TYPE(md->returntype.type))
4279 M_LST(REG_RESULT, REG_SP, 0 * 8);
4281 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4284 #if !defined(NDEBUG)
4285 /* call finished trace function */
4287 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
4288 if (md->returntype.type != TYPE_VOID) {
4289 if (IS_INT_LNG_TYPE(md->returntype.type))
4290 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4292 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4295 disp = dseg_addaddress(cd, m);
4296 M_ALD(rd->argintregs[0], REG_PV, disp);
4298 M_MOV(REG_RESULT, rd->argintregs[1]);
4299 M_DMFC1(REG_ITMP1, REG_FRESULT);
4300 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4301 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4303 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4304 M_ALD(REG_ITMP3, REG_PV, disp);
4305 M_JSR(REG_RA, REG_ITMP3);
4310 /* remove native stackframe info */
4312 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4313 disp = dseg_addaddress(cd, codegen_finish_native_call);
4314 M_ALD(REG_ITMP3, REG_PV, disp);
4315 M_JSR(REG_RA, REG_ITMP3);
4316 M_NOP; /* XXX fill me! */
4317 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4319 /* restore return value */
4321 if (md->returntype.type != TYPE_VOID) {
4322 if (IS_INT_LNG_TYPE(md->returntype.type))
4323 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4325 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4328 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4330 /* check for exception */
4332 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4333 M_LDA(REG_SP, REG_SP, stackframesize * 8); /* remove stackframe (DELAY) */
4335 M_RET(REG_RA); /* return to caller */
4336 M_NOP; /* DELAY SLOT */
4338 /* handle exception */
4340 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4341 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4342 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4343 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4345 /* generate static stub call code */
4353 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4354 /* Get machine code which is patched back in later. The
4355 call is 2 instruction words long. */
4357 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
4359 /* We need to split this, because an unaligned 8 byte read
4360 causes a SIGSEGV. */
4362 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
4363 ((u4 *) tmpmcodeptr)[0];
4365 /* Patch in the call to call the following code (done at
4368 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4369 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4371 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
4373 M_NOP; /* branch delay slot */
4375 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4377 /* create stack frame */
4379 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4381 /* move return address onto stack */
4383 M_AST(REG_RA, REG_SP, 5 * 8);
4385 /* move pointer to java_objectheader onto stack */
4387 #if defined(ENABLE_THREADS)
4388 /* order reversed because of data segment layout */
4390 (void) dseg_addaddress(cd, NULL); /* flcword */
4391 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4392 disp = dseg_addaddress(cd, NULL); /* vftbl */
4394 M_LDA(REG_ITMP3, REG_PV, disp);
4395 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4397 M_AST(REG_ZERO, REG_SP, 4 * 8);
4400 /* move machine code onto stack */
4402 disp = dseg_adds8(cd, mcode);
4403 M_LLD(REG_ITMP3, REG_PV, disp);
4404 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4406 /* move class/method/field reference onto stack */
4408 disp = dseg_addaddress(cd, pref->ref);
4409 M_ALD(REG_ITMP3, REG_PV, disp);
4410 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4412 /* move data segment displacement onto stack */
4414 disp = dseg_adds4(cd, pref->disp);
4415 M_ILD(REG_ITMP3, REG_PV, disp);
4416 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4418 /* move patcher function pointer onto stack */
4420 disp = dseg_addaddress(cd, pref->patcher);
4421 M_ALD(REG_ITMP3, REG_PV, disp);
4422 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4424 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4425 M_ALD(REG_ITMP3, REG_PV, disp);
4433 return jd->code->entrypoint;
4438 * These are local overrides for various environment variables in Emacs.
4439 * Please do not remove this and leave it at the end of the file, where
4440 * Emacs will automagically detect them.
4441 * ---------------------------------------------------------------------
4444 * indent-tabs-mode: t
4448 * vim:noexpandtab:sw=4:ts=4: