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 5324 2006-09-05 17:11:32Z 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;
102 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
103 builtintable_entry *bte;
105 rplpoint *replacementpoint;
107 /* get required compiler data */
118 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
120 /* space to save used callee saved registers */
122 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
123 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
125 cd->stackframesize = rd->memuse + savedregs_num;
127 #if defined(ENABLE_THREADS)
128 /* space to save argument of monitor_enter */
130 if (checksync && (m->flags & ACC_SYNCHRONIZED))
131 cd->stackframesize++;
134 /* keep stack 16-byte aligned */
136 if (cd->stackframesize & 1)
137 cd->stackframesize++;
139 /* create method header */
141 #if SIZEOF_VOID_P == 4
142 (void) dseg_addaddress(cd, code); /* Filler */
144 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
145 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
147 #if defined(ENABLE_THREADS)
148 /* IsSync contains the offset relative to the stack pointer for the
149 argument of monitor_exit used in the exception handler. Since the
150 offset could be zero and give a wrong meaning of the flag it is
154 if (checksync && (m->flags & ACC_SYNCHRONIZED))
155 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
158 (void) dseg_adds4(cd, 0); /* IsSync */
160 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
161 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
162 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
163 dseg_addlinenumbertablesize(cd);
164 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
166 /* create exception table */
168 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
169 dseg_addtarget(cd, ex->start);
170 dseg_addtarget(cd, ex->end);
171 dseg_addtarget(cd, ex->handler);
172 (void) dseg_addaddress(cd, ex->catchtype.cls);
175 /* create stack frame (if necessary) */
177 if (cd->stackframesize)
178 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
180 /* save return address and used callee saved registers */
182 p = cd->stackframesize;
183 if (!jd->isleafmethod) {
184 p--; M_AST(REG_RA, REG_SP, p * 8);
186 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
187 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
189 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
193 /* take arguments out of register or stack frame */
197 for (p = 0, l = 0; p < md->paramcount; p++) {
198 t = md->paramtypes[p].type;
199 var = &(rd->locals[l][t]);
201 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
205 s1 = md->params[p].regoff;
206 if (IS_INT_LNG_TYPE(t)) { /* integer args */
207 if (!md->params[p].inmemory) { /* register arguments */
208 s2 = rd->argintregs[s1];
209 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
210 M_INTMOVE(s2, var->regoff);
211 } else { /* reg arg -> spilled */
212 M_LST(s2, REG_SP, var->regoff * 8);
215 } else { /* stack arguments */
216 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
217 M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
218 } else { /* stack arg -> spilled */
219 var->regoff = cd->stackframesize + s1;
223 } else { /* floating args */
224 if (!md->params[p].inmemory) { /* register arguments */
225 s2 = rd->argfltregs[s1];
226 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
227 if (IS_2_WORD_TYPE(t))
228 M_DMOV(s2, var->regoff);
230 M_FMOV(s2, var->regoff);
231 } else { /* reg arg -> spilled */
232 if (IS_2_WORD_TYPE(t))
233 M_DST(s2, REG_SP, var->regoff * 8);
235 M_FST(s2, REG_SP, var->regoff * 8);
238 } else { /* stack arguments */
239 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
240 if (IS_2_WORD_TYPE(t))
241 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
243 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
244 } else /* stack-arg -> spilled */
245 var->regoff = cd->stackframesize + s1;
250 /* call monitorenter function */
252 #if defined(ENABLE_THREADS)
253 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
254 /* stack offset for monitor argument */
258 # if !defined(NDEBUG)
259 if (opt_verbosecall) {
260 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
262 for (p = 0; p < INT_ARG_CNT; p++)
263 M_LST(rd->argintregs[p], REG_SP, p * 8);
265 for (p = 0; p < FLT_ARG_CNT; p++)
266 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
268 s1 += INT_ARG_CNT + FLT_ARG_CNT;
272 /* get correct lock object */
274 if (m->flags & ACC_STATIC) {
275 p = dseg_addaddress(cd, &m->class->object.header);
276 M_ALD(rd->argintregs[0], REG_PV, p);
279 M_BEQZ(rd->argintregs[0], 0);
280 codegen_add_nullpointerexception_ref(cd);
283 p = dseg_addaddress(cd, LOCK_monitor_enter);
284 M_ALD(REG_ITMP3, REG_PV, p);
285 M_JSR(REG_RA, REG_ITMP3);
286 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
288 # if !defined(NDEBUG)
289 if (opt_verbosecall) {
290 for (p = 0; p < INT_ARG_CNT; p++)
291 M_LLD(rd->argintregs[p], REG_SP, p * 8);
293 for (p = 0; p < FLT_ARG_CNT; p++)
294 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
297 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
304 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
305 emit_verbosecall_enter(jd);
310 /* end of header generation */
312 replacementpoint = jd->code->rplpoints;
314 /* walk through all basic blocks */
316 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
318 /* handle replacement points */
320 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
322 /* 8-byte align pc */
323 if ((ptrint) cd->mcodeptr & 4) {
327 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
330 assert(cd->lastmcodeptr <= cd->mcodeptr);
331 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
334 /* store relative start of block */
336 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
338 if (bptr->flags >= BBREACHED) {
340 /* branch resolving */
343 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
344 gen_resolvebranch(cd->mcodebase + bref->branchpos,
350 /* copy interface registers to their destination */
355 #if defined(ENABLE_LSRA)
357 while (src != NULL) {
359 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
360 /* d = reg_of_var(m, src, REG_ITMP1); */
361 if (!(src->flags & INMEMORY))
365 M_INTMOVE(REG_ITMP1, d);
366 emit_store(jd, NULL, src, d);
372 while (src != NULL) {
374 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
375 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
376 M_INTMOVE(REG_ITMP1, d);
377 emit_store(jd, NULL, src, d);
380 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
381 if ((src->varkind != STACKVAR)) {
383 s1 = rd->interfaces[len][s2].regoff;
384 if (IS_FLT_DBL_TYPE(s2)) {
385 if (rd->interfaces[len][s2].flags & INMEMORY) {
386 if (IS_2_WORD_TYPE(s2))
387 M_DLD(d, REG_SP, s1 * 8);
389 M_FLD(d, REG_SP, s1 * 8);
392 if (IS_2_WORD_TYPE(s2))
399 if (rd->interfaces[len][s2].flags & INMEMORY)
400 M_LLD(d, REG_SP, s1 * 8);
405 emit_store(jd, NULL, src, d);
410 #if defined(ENABLE_LSRA)
413 /* walk through all instructions */
419 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
420 if (iptr->line != currentline) {
421 dseg_addlinenumber(cd, iptr->line);
422 currentline = iptr->line;
425 MCODECHECK(64); /* an instruction usually needs < 64 words */
429 case ICMD_NOP: /* ... ==> ... */
432 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
434 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
436 codegen_add_nullpointerexception_ref(cd);
440 /* constant operations ************************************************/
442 case ICMD_ICONST: /* ... ==> ..., constant */
443 /* op1 = 0, val.i = constant */
445 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
446 ICONST(d, iptr->val.i);
447 emit_store(jd, iptr, iptr->dst, d);
450 case ICMD_LCONST: /* ... ==> ..., constant */
451 /* op1 = 0, val.l = constant */
453 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
454 LCONST(d, iptr->val.l);
455 emit_store(jd, iptr, iptr->dst, d);
458 case ICMD_FCONST: /* ... ==> ..., constant */
459 /* op1 = 0, val.f = constant */
461 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
462 disp = dseg_addfloat(cd, iptr->val.f);
463 M_FLD(d, REG_PV, disp);
464 emit_store(jd, iptr, iptr->dst, d);
467 case ICMD_DCONST: /* ... ==> ..., constant */
468 /* op1 = 0, val.d = constant */
470 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
471 disp = dseg_adddouble(cd, iptr->val.d);
472 M_DLD(d, REG_PV, disp);
473 emit_store(jd, iptr, iptr->dst, d);
476 case ICMD_ACONST: /* ... ==> ..., constant */
477 /* op1 = 0, val.a = constant */
479 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
481 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
482 disp = dseg_addaddress(cd, NULL);
484 codegen_addpatchref(cd, PATCHER_aconst,
485 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
488 if (opt_showdisassemble) {
492 M_ALD(d, REG_PV, disp);
495 if (iptr->val.a == NULL) {
496 M_INTMOVE(REG_ZERO, d);
498 disp = dseg_addaddress(cd, iptr->val.a);
499 M_ALD(d, REG_PV, disp);
502 emit_store(jd, iptr, iptr->dst, d);
506 /* load/store operations **********************************************/
508 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
509 /* op1 = local variable */
511 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
512 if ((iptr->dst->varkind == LOCALVAR) &&
513 (iptr->dst->varnum == iptr->op1))
515 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
516 if (var->flags & INMEMORY)
517 #if SIZEOF_VOID_P == 8
518 M_LLD(d, REG_SP, var->regoff * 8);
520 M_ILD(d, REG_SP, var->regoff * 8);
523 M_INTMOVE(var->regoff,d);
524 emit_store(jd, iptr, iptr->dst, d);
527 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
528 /* op1 = local variable */
530 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
531 if ((iptr->dst->varkind == LOCALVAR) &&
532 (iptr->dst->varnum == iptr->op1))
534 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
535 if (var->flags & INMEMORY)
536 M_LLD(d, REG_SP, var->regoff * 8);
538 M_INTMOVE(var->regoff,d);
539 emit_store(jd, iptr, iptr->dst, d);
542 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
543 /* op1 = local variable */
545 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
546 if ((iptr->dst->varkind == LOCALVAR) &&
547 (iptr->dst->varnum == iptr->op1))
549 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
550 if (var->flags & INMEMORY)
551 M_ALD(d, REG_SP, var->regoff * 8);
553 M_INTMOVE(var->regoff,d);
554 emit_store(jd, iptr, iptr->dst, d);
557 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
558 /* op1 = local variable */
560 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
561 if ((iptr->dst->varkind == LOCALVAR) &&
562 (iptr->dst->varnum == iptr->op1))
564 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
565 if (var->flags & INMEMORY)
566 M_FLD(d, REG_SP, var->regoff * 8);
568 M_FMOV(var->regoff, d);
569 emit_store(jd, iptr, iptr->dst, d);
572 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
573 /* op1 = local variable */
575 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
576 if ((iptr->dst->varkind == LOCALVAR) &&
577 (iptr->dst->varnum == iptr->op1))
579 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
580 if (var->flags & INMEMORY)
581 M_DLD(d, REG_SP, var->regoff * 8);
583 M_DMOV(var->regoff, d);
584 emit_store(jd, iptr, iptr->dst, d);
588 case ICMD_ISTORE: /* ..., value ==> ... */
589 /* op1 = local variable */
591 if ((src->varkind == LOCALVAR) &&
592 (src->varnum == iptr->op1))
594 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
595 if (var->flags & INMEMORY) {
596 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
597 #if SIZEOF_VOID_P == 8
598 M_LST(s1, REG_SP, var->regoff * 8);
600 M_IST(s1, REG_SP, var->regoff * 8);
603 s1 = emit_load_s1(jd, iptr, src, var->regoff);
604 M_INTMOVE(s1, var->regoff);
608 case ICMD_LSTORE: /* ..., value ==> ... */
609 /* op1 = local variable */
611 if ((src->varkind == LOCALVAR) &&
612 (src->varnum == iptr->op1))
614 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
615 if (var->flags & INMEMORY) {
616 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
617 M_LST(s1, REG_SP, var->regoff * 8);
619 s1 = emit_load_s1(jd, iptr, src, var->regoff);
620 M_INTMOVE(s1, var->regoff);
624 case ICMD_ASTORE: /* ..., value ==> ... */
625 /* op1 = local variable */
627 if ((src->varkind == LOCALVAR) &&
628 (src->varnum == iptr->op1))
630 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
631 if (var->flags & INMEMORY) {
632 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
633 M_AST(s1, REG_SP, var->regoff * 8);
635 s1 = emit_load_s1(jd, iptr, src, var->regoff);
636 M_INTMOVE(s1, var->regoff);
640 case ICMD_FSTORE: /* ..., value ==> ... */
641 /* op1 = local variable */
643 if ((src->varkind == LOCALVAR) &&
644 (src->varnum == iptr->op1))
646 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
647 if (var->flags & INMEMORY) {
648 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
649 M_FST(s1, REG_SP, var->regoff * 8);
651 s1 = emit_load_s1(jd, iptr, src, var->regoff);
652 M_FMOV(s1, var->regoff);
656 case ICMD_DSTORE: /* ..., value ==> ... */
657 /* op1 = local variable */
659 if ((src->varkind == LOCALVAR) &&
660 (src->varnum == iptr->op1))
662 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
663 if (var->flags & INMEMORY) {
664 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
665 M_DST(s1, REG_SP, var->regoff * 8);
667 s1 = emit_load_s1(jd, iptr, src, var->regoff);
668 M_DMOV(s1, var->regoff);
673 /* pop/dup/swap operations ********************************************/
675 /* attention: double and longs are only one entry in CACAO ICMDs */
677 case ICMD_POP: /* ..., value ==> ... */
678 case ICMD_POP2: /* ..., value, value ==> ... */
681 case ICMD_DUP: /* ..., a ==> ..., a, a */
682 M_COPY(src, iptr->dst);
685 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
687 M_COPY(src, iptr->dst);
688 M_COPY(src->prev, iptr->dst->prev);
689 M_COPY(iptr->dst, iptr->dst->prev->prev);
692 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
694 M_COPY(src, iptr->dst);
695 M_COPY(src->prev, iptr->dst->prev);
696 M_COPY(src->prev->prev, iptr->dst->prev->prev);
697 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
700 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
702 M_COPY(src, iptr->dst);
703 M_COPY(src->prev, iptr->dst->prev);
706 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
708 M_COPY(src, iptr->dst);
709 M_COPY(src->prev, iptr->dst->prev);
710 M_COPY(src->prev->prev, iptr->dst->prev->prev);
711 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
712 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
715 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
717 M_COPY(src, iptr->dst);
718 M_COPY(src->prev, iptr->dst->prev);
719 M_COPY(src->prev->prev, iptr->dst->prev->prev);
720 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
721 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
722 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
725 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
727 M_COPY(src, iptr->dst->prev);
728 M_COPY(src->prev, iptr->dst);
732 /* integer operations *************************************************/
734 case ICMD_INEG: /* ..., value ==> ..., - value */
736 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
737 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
738 M_ISUB(REG_ZERO, s1, d);
739 emit_store(jd, iptr, iptr->dst, d);
742 case ICMD_LNEG: /* ..., value ==> ..., - value */
744 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
745 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
746 M_LSUB(REG_ZERO, s1, d);
747 emit_store(jd, iptr, iptr->dst, d);
750 case ICMD_I2L: /* ..., value ==> ..., value */
752 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
753 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
755 emit_store(jd, iptr, iptr->dst, d);
758 case ICMD_L2I: /* ..., value ==> ..., value */
760 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
761 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
762 M_ISLL_IMM(s1, 0, d );
763 emit_store(jd, iptr, iptr->dst, d);
766 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
768 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
769 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
770 M_LSLL_IMM(s1, 56, d);
771 M_LSRA_IMM( d, 56, d);
772 emit_store(jd, iptr, iptr->dst, d);
775 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
777 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
778 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
780 emit_store(jd, iptr, iptr->dst, d);
783 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
785 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
786 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
787 M_LSLL_IMM(s1, 48, d);
788 M_LSRA_IMM( d, 48, d);
789 emit_store(jd, iptr, iptr->dst, d);
793 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
795 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
796 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
797 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
799 emit_store(jd, iptr, iptr->dst, d);
802 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
803 /* val.i = constant */
805 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
806 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
807 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
808 M_IADD_IMM(s1, iptr->val.i, d);
810 ICONST(REG_ITMP2, iptr->val.i);
811 M_IADD(s1, REG_ITMP2, d);
813 emit_store(jd, iptr, iptr->dst, d);
816 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
818 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
819 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
820 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
822 emit_store(jd, iptr, iptr->dst, d);
825 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
826 /* val.l = constant */
828 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
829 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
830 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
831 M_LADD_IMM(s1, iptr->val.l, d);
833 LCONST(REG_ITMP2, iptr->val.l);
834 M_LADD(s1, REG_ITMP2, d);
836 emit_store(jd, iptr, iptr->dst, d);
839 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
841 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
842 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
843 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
845 emit_store(jd, iptr, iptr->dst, d);
848 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
849 /* val.i = constant */
851 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
852 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
853 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
854 M_IADD_IMM(s1, -iptr->val.i, d);
856 ICONST(REG_ITMP2, iptr->val.i);
857 M_ISUB(s1, REG_ITMP2, d);
859 emit_store(jd, iptr, iptr->dst, d);
862 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
864 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
865 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
866 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
868 emit_store(jd, iptr, iptr->dst, d);
871 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
872 /* val.l = constant */
874 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
875 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
876 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
877 M_LADD_IMM(s1, -iptr->val.l, d);
879 LCONST(REG_ITMP2, iptr->val.l);
880 M_LSUB(s1, REG_ITMP2, d);
882 emit_store(jd, iptr, iptr->dst, d);
885 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
887 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
888 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
889 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
894 emit_store(jd, iptr, iptr->dst, d);
897 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
898 /* val.i = constant */
900 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
901 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
902 ICONST(REG_ITMP2, iptr->val.i);
903 M_IMUL(s1, REG_ITMP2);
907 emit_store(jd, iptr, iptr->dst, d);
910 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
912 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
913 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
914 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
919 emit_store(jd, iptr, iptr->dst, d);
922 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
923 /* val.l = constant */
925 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
926 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
927 LCONST(REG_ITMP2, iptr->val.l);
928 M_LMUL(s1, REG_ITMP2);
932 emit_store(jd, iptr, iptr->dst, d);
935 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
937 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
938 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
939 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
945 emit_store(jd, iptr, iptr->dst, d);
948 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
950 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
951 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
952 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
958 emit_store(jd, iptr, iptr->dst, d);
961 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
963 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
964 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
965 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
971 emit_store(jd, iptr, iptr->dst, d);
974 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
976 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
977 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
978 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
984 emit_store(jd, iptr, iptr->dst, d);
987 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
988 case ICMD_LDIVPOW2: /* val.i = constant */
990 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
991 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
992 M_LSRA_IMM(s1, 63, REG_ITMP2);
993 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
994 M_LADD(s1, REG_ITMP2, REG_ITMP2);
995 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
996 emit_store(jd, iptr, iptr->dst, d);
999 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1001 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1002 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1003 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1005 emit_store(jd, iptr, iptr->dst, d);
1008 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1009 /* val.i = constant */
1011 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1012 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1013 M_ISLL_IMM(s1, iptr->val.i, d);
1014 emit_store(jd, iptr, iptr->dst, d);
1017 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1019 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1020 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1021 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1023 emit_store(jd, iptr, iptr->dst, d);
1026 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1027 /* val.i = constant */
1029 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1030 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1031 M_ISRA_IMM(s1, iptr->val.i, d);
1032 emit_store(jd, iptr, iptr->dst, d);
1035 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1037 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1038 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1039 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1041 emit_store(jd, iptr, iptr->dst, d);
1044 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1045 /* val.i = constant */
1047 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1048 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1049 M_ISRL_IMM(s1, iptr->val.i, d);
1050 emit_store(jd, iptr, iptr->dst, d);
1053 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1055 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1056 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1057 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1059 emit_store(jd, iptr, iptr->dst, d);
1062 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1063 /* val.i = constant */
1065 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1066 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1067 M_LSLL_IMM(s1, iptr->val.i, d);
1068 emit_store(jd, iptr, iptr->dst, d);
1071 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1073 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1074 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1075 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1077 emit_store(jd, iptr, iptr->dst, d);
1080 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1081 /* val.i = constant */
1083 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1084 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1085 M_LSRA_IMM(s1, iptr->val.i, d);
1086 emit_store(jd, iptr, iptr->dst, d);
1089 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1091 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1093 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1095 emit_store(jd, iptr, iptr->dst, d);
1098 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1099 /* val.i = constant */
1101 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1102 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1103 M_LSRL_IMM(s1, iptr->val.i, d);
1104 emit_store(jd, iptr, iptr->dst, d);
1107 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1110 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1111 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1112 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1114 emit_store(jd, iptr, iptr->dst, d);
1117 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1118 /* val.i = constant */
1120 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1121 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1122 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1123 M_AND_IMM(s1, iptr->val.i, d);
1125 ICONST(REG_ITMP2, iptr->val.i);
1126 M_AND(s1, REG_ITMP2, d);
1128 emit_store(jd, iptr, iptr->dst, d);
1131 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1132 /* val.i = constant */
1134 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1135 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1137 M_MOV(s1, REG_ITMP1);
1140 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1141 M_AND_IMM(s1, iptr->val.i, d);
1144 M_ISUB(REG_ZERO, s1, d);
1145 M_AND_IMM(d, iptr->val.i, d);
1147 ICONST(REG_ITMP2, iptr->val.i);
1148 M_AND(s1, REG_ITMP2, d);
1151 M_ISUB(REG_ZERO, s1, d);
1152 M_AND(d, REG_ITMP2, d);
1154 M_ISUB(REG_ZERO, d, d);
1155 emit_store(jd, iptr, iptr->dst, d);
1158 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1159 /* val.l = constant */
1161 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1162 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1163 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1164 M_AND_IMM(s1, iptr->val.l, d);
1166 LCONST(REG_ITMP2, iptr->val.l);
1167 M_AND(s1, REG_ITMP2, d);
1169 emit_store(jd, iptr, iptr->dst, d);
1172 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1173 /* val.l = constant */
1175 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1176 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1178 M_MOV(s1, REG_ITMP1);
1181 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1182 M_AND_IMM(s1, iptr->val.l, d);
1185 M_LSUB(REG_ZERO, s1, d);
1186 M_AND_IMM(d, iptr->val.l, d);
1188 LCONST(REG_ITMP2, iptr->val.l);
1189 M_AND(s1, REG_ITMP2, d);
1192 M_LSUB(REG_ZERO, s1, d);
1193 M_AND(d, REG_ITMP2, d);
1195 M_LSUB(REG_ZERO, d, d);
1196 emit_store(jd, iptr, iptr->dst, d);
1199 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1202 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1203 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1204 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1206 emit_store(jd, iptr, iptr->dst, d);
1209 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1210 /* val.i = constant */
1212 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1213 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1214 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1215 M_OR_IMM(s1, iptr->val.i, d);
1217 ICONST(REG_ITMP2, iptr->val.i);
1218 M_OR(s1, REG_ITMP2, d);
1220 emit_store(jd, iptr, iptr->dst, d);
1223 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1224 /* val.l = constant */
1226 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1227 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1228 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1229 M_OR_IMM(s1, iptr->val.l, d);
1231 LCONST(REG_ITMP2, iptr->val.l);
1232 M_OR(s1, REG_ITMP2, d);
1234 emit_store(jd, iptr, iptr->dst, d);
1237 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1240 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1241 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1242 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1244 emit_store(jd, iptr, iptr->dst, d);
1247 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1248 /* val.i = constant */
1250 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1251 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1252 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1253 M_XOR_IMM(s1, iptr->val.i, d);
1255 ICONST(REG_ITMP2, iptr->val.i);
1256 M_XOR(s1, REG_ITMP2, d);
1258 emit_store(jd, iptr, iptr->dst, d);
1261 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1262 /* val.l = constant */
1264 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1265 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1266 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1267 M_XOR_IMM(s1, iptr->val.l, d);
1269 LCONST(REG_ITMP2, iptr->val.l);
1270 M_XOR(s1, REG_ITMP2, d);
1272 emit_store(jd, iptr, iptr->dst, d);
1276 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1278 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1279 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1280 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1281 M_CMPLT(s1, s2, REG_ITMP3);
1282 M_CMPLT(s2, s1, REG_ITMP1);
1283 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1284 emit_store(jd, iptr, iptr->dst, d);
1288 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1289 /* op1 = variable, val.i = constant */
1291 var = &(rd->locals[iptr->op1][TYPE_INT]);
1292 if (var->flags & INMEMORY) {
1294 M_LLD(s1, REG_SP, var->regoff * 8);
1297 M_IADD_IMM(s1, iptr->val.i, s1);
1298 if (var->flags & INMEMORY)
1299 M_LST(s1, REG_SP, var->regoff * 8);
1303 /* floating operations ************************************************/
1305 case ICMD_FNEG: /* ..., value ==> ..., - value */
1307 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1308 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1310 emit_store(jd, iptr, iptr->dst, d);
1313 case ICMD_DNEG: /* ..., value ==> ..., - value */
1315 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1316 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1318 emit_store(jd, iptr, iptr->dst, d);
1321 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1323 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1324 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1325 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1327 emit_store(jd, iptr, iptr->dst, d);
1330 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1332 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1333 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1334 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1336 emit_store(jd, iptr, iptr->dst, d);
1339 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1341 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1342 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1343 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1345 emit_store(jd, iptr, iptr->dst, d);
1348 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1350 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1351 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1352 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1354 emit_store(jd, iptr, iptr->dst, d);
1357 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1359 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1360 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1361 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1363 emit_store(jd, iptr, iptr->dst, d);
1366 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1368 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1369 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1370 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1372 emit_store(jd, iptr, iptr->dst, d);
1375 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1377 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1378 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1379 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1381 emit_store(jd, iptr, iptr->dst, d);
1384 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1386 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1387 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1388 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1390 emit_store(jd, iptr, iptr->dst, d);
1394 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1396 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1397 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1398 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1399 M_FDIV(s1,s2, REG_FTMP3);
1400 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1401 M_CVTLF(REG_FTMP3, REG_FTMP3);
1402 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1403 M_FSUB(s1, REG_FTMP3, d);
1404 emit_store(jd, iptr, iptr->dst, d);
1407 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1409 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1410 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1411 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1412 M_DDIV(s1,s2, REG_FTMP3);
1413 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1414 M_CVTLD(REG_FTMP3, REG_FTMP3);
1415 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1416 M_DSUB(s1, REG_FTMP3, d);
1417 emit_store(jd, iptr, iptr->dst, d);
1421 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1423 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1424 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1427 emit_store(jd, iptr, iptr->dst, d);
1430 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1432 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1433 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1436 emit_store(jd, iptr, iptr->dst, d);
1440 /* XXX these do not work correctly */
1442 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1444 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1445 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1446 M_TRUNCFI(s1, REG_FTMP1);
1447 M_MOVDI(REG_FTMP1, d);
1449 emit_store(jd, iptr, iptr->dst, d);
1452 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1454 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1455 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1456 M_TRUNCDI(s1, REG_FTMP1);
1457 M_MOVDI(REG_FTMP1, d);
1459 emit_store(jd, iptr, iptr->dst, d);
1462 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1464 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1465 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1466 M_TRUNCFL(s1, REG_FTMP1);
1467 M_MOVDL(REG_FTMP1, d);
1469 emit_store(jd, iptr, iptr->dst, d);
1472 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1474 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1475 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1476 M_TRUNCDL(s1, REG_FTMP1);
1477 M_MOVDL(REG_FTMP1, d);
1479 emit_store(jd, iptr, iptr->dst, d);
1483 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1485 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1486 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1488 emit_store(jd, iptr, iptr->dst, d);
1491 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1493 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1494 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1496 emit_store(jd, iptr, iptr->dst, d);
1499 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1501 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1502 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1503 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1506 M_LADD_IMM(REG_ZERO, 1, d);
1510 M_LSUB_IMM(REG_ZERO, 1, d);
1511 M_CMOVT(REG_ZERO, d);
1512 emit_store(jd, iptr, iptr->dst, d);
1515 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1517 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1518 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1519 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1522 M_LADD_IMM(REG_ZERO, 1, d);
1526 M_LSUB_IMM(REG_ZERO, 1, d);
1527 M_CMOVT(REG_ZERO, d);
1528 emit_store(jd, iptr, iptr->dst, d);
1531 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1533 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1534 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1535 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1538 M_LSUB_IMM(REG_ZERO, 1, d);
1542 M_LADD_IMM(REG_ZERO, 1, d);
1543 M_CMOVT(REG_ZERO, d);
1544 emit_store(jd, iptr, iptr->dst, d);
1547 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1549 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1550 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1551 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1554 M_LSUB_IMM(REG_ZERO, 1, d);
1558 M_LADD_IMM(REG_ZERO, 1, d);
1559 M_CMOVT(REG_ZERO, d);
1560 emit_store(jd, iptr, iptr->dst, d);
1564 /* memory operations **************************************************/
1566 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1568 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1569 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1570 gen_nullptr_check(s1);
1571 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1572 emit_store(jd, iptr, iptr->dst, d);
1575 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1577 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1578 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1579 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1580 if (iptr->op1 == 0) {
1581 gen_nullptr_check(s1);
1584 M_AADD(s2, s1, REG_ITMP3);
1585 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1586 emit_store(jd, iptr, iptr->dst, d);
1589 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1591 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1592 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1593 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1594 if (iptr->op1 == 0) {
1595 gen_nullptr_check(s1);
1598 M_AADD(s2, s1, REG_ITMP3);
1599 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1600 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1601 emit_store(jd, iptr, iptr->dst, d);
1604 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1606 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1607 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1608 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1609 if (iptr->op1 == 0) {
1610 gen_nullptr_check(s1);
1613 M_AADD(s2, s1, REG_ITMP3);
1614 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1615 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1616 emit_store(jd, iptr, iptr->dst, d);
1619 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1621 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1622 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1623 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1624 if (iptr->op1 == 0) {
1625 gen_nullptr_check(s1);
1628 M_ASLL_IMM(s2, 2, REG_ITMP3);
1629 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1630 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1631 emit_store(jd, iptr, iptr->dst, d);
1634 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1636 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1637 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1638 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1639 if (iptr->op1 == 0) {
1640 gen_nullptr_check(s1);
1643 M_ASLL_IMM(s2, 3, REG_ITMP3);
1644 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1645 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1646 emit_store(jd, iptr, iptr->dst, d);
1649 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1651 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1652 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1653 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1654 if (iptr->op1 == 0) {
1655 gen_nullptr_check(s1);
1658 M_ASLL_IMM(s2, 2, REG_ITMP3);
1659 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1660 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1661 emit_store(jd, iptr, iptr->dst, d);
1664 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1666 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1667 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1668 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1669 if (iptr->op1 == 0) {
1670 gen_nullptr_check(s1);
1673 M_ASLL_IMM(s2, 3, REG_ITMP3);
1674 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1675 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1676 emit_store(jd, iptr, iptr->dst, d);
1679 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1681 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1682 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1683 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1684 if (iptr->op1 == 0) {
1685 gen_nullptr_check(s1);
1688 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1689 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1690 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1691 emit_store(jd, iptr, iptr->dst, d);
1695 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1697 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1698 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1699 if (iptr->op1 == 0) {
1700 gen_nullptr_check(s1);
1703 M_AADD(s2, s1, REG_ITMP1);
1704 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1705 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1708 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1709 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1711 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1713 if (iptr->op1 == 0) {
1714 gen_nullptr_check(s1);
1717 M_AADD(s2, s1, REG_ITMP1);
1718 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1719 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1720 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1723 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1725 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1726 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1727 if (iptr->op1 == 0) {
1728 gen_nullptr_check(s1);
1731 M_ASLL_IMM(s2, 2, REG_ITMP2);
1732 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1733 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1734 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1737 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1739 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1740 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1741 if (iptr->op1 == 0) {
1742 gen_nullptr_check(s1);
1745 M_ASLL_IMM(s2, 3, REG_ITMP2);
1746 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1747 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1748 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1751 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1753 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1754 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1755 if (iptr->op1 == 0) {
1756 gen_nullptr_check(s1);
1759 M_ASLL_IMM(s2, 2, REG_ITMP2);
1760 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1761 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1762 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1765 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1767 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1768 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1769 if (iptr->op1 == 0) {
1770 gen_nullptr_check(s1);
1773 M_ASLL_IMM(s2, 3, REG_ITMP2);
1774 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1775 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1776 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1780 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1782 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1783 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1784 if (iptr->op1 == 0) {
1785 gen_nullptr_check(s1);
1788 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1790 M_MOV(s1, rd->argintregs[0]);
1791 M_MOV(s3, rd->argintregs[1]);
1792 disp = dseg_addaddress(cd, BUILTIN_canstore);
1793 M_ALD(REG_ITMP3, REG_PV, disp);
1794 M_JSR(REG_RA, REG_ITMP3);
1797 M_BEQZ(REG_RESULT, 0);
1798 codegen_add_arraystoreexception_ref(cd);
1801 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1802 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1803 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1804 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1805 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1806 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1810 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1812 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1813 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1814 if (iptr->op1 == 0) {
1815 gen_nullptr_check(s1);
1818 M_AADD(s2, s1, REG_ITMP1);
1819 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1822 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1823 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1825 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1826 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1827 if (iptr->op1 == 0) {
1828 gen_nullptr_check(s1);
1831 M_AADD(s2, s1, REG_ITMP1);
1832 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1833 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1836 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1838 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1839 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1840 if (iptr->op1 == 0) {
1841 gen_nullptr_check(s1);
1844 M_ASLL_IMM(s2, 2, REG_ITMP2);
1845 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1846 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1849 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1851 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1852 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1853 if (iptr->op1 == 0) {
1854 gen_nullptr_check(s1);
1857 M_ASLL_IMM(s2, 3, REG_ITMP2);
1858 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1859 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1862 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1864 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1865 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1866 if (iptr->op1 == 0) {
1867 gen_nullptr_check(s1);
1870 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1871 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1872 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1876 case ICMD_GETSTATIC: /* ... ==> ..., value */
1877 /* op1 = type, val.a = field address */
1879 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1880 disp = dseg_addaddress(cd, NULL);
1882 codegen_addpatchref(cd, PATCHER_get_putstatic,
1883 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1885 if (opt_showdisassemble) {
1890 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1892 disp = dseg_addaddress(cd, &(fi->value));
1894 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1895 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1897 if (opt_showdisassemble) {
1903 M_ALD(REG_ITMP1, REG_PV, disp);
1904 switch (iptr->op1) {
1906 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1907 M_ILD_INTERN(d, REG_ITMP1, 0);
1908 emit_store(jd, iptr, iptr->dst, d);
1911 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1912 M_LLD_INTERN(d, REG_ITMP1, 0);
1913 emit_store(jd, iptr, iptr->dst, d);
1916 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1917 M_ALD_INTERN(d, REG_ITMP1, 0);
1918 emit_store(jd, iptr, iptr->dst, d);
1921 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1922 M_FLD_INTERN(d, REG_ITMP1, 0);
1923 emit_store(jd, iptr, iptr->dst, d);
1926 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1927 M_DLD_INTERN(d, REG_ITMP1, 0);
1928 emit_store(jd, iptr, iptr->dst, d);
1933 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1934 /* op1 = type, val.a = field address */
1936 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1937 disp = dseg_addaddress(cd, NULL);
1939 codegen_addpatchref(cd, PATCHER_get_putstatic,
1940 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1942 if (opt_showdisassemble) {
1947 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1949 disp = dseg_addaddress(cd, &(fi->value));
1951 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1952 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1954 if (opt_showdisassemble) {
1960 M_ALD(REG_ITMP1, REG_PV, disp);
1961 switch (iptr->op1) {
1963 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1964 M_IST_INTERN(s1, REG_ITMP1, 0);
1967 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1968 M_LST_INTERN(s1, REG_ITMP1, 0);
1971 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1972 M_AST_INTERN(s1, REG_ITMP1, 0);
1975 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1976 M_FST_INTERN(s1, REG_ITMP1, 0);
1979 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1980 M_DST_INTERN(s1, REG_ITMP1, 0);
1985 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1986 /* val = value (in current instruction) */
1987 /* op1 = type, val.a = field address (in */
1988 /* following NOP) */
1990 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1991 disp = dseg_addaddress(cd, NULL);
1993 codegen_addpatchref(cd, PATCHER_get_putstatic,
1994 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
1996 if (opt_showdisassemble) {
2001 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2003 disp = dseg_addaddress(cd, &(fi->value));
2005 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2006 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2008 if (opt_showdisassemble) {
2014 M_ALD(REG_ITMP1, REG_PV, disp);
2015 switch (iptr->op1) {
2017 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2020 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2023 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2026 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2029 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2035 case ICMD_GETFIELD: /* ... ==> ..., value */
2036 /* op1 = type, val.i = field offset */
2038 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2039 gen_nullptr_check(s1);
2041 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2042 codegen_addpatchref(cd, PATCHER_get_putfield,
2043 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2045 if (opt_showdisassemble) {
2052 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2055 switch (iptr->op1) {
2057 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2059 emit_store(jd, iptr, iptr->dst, d);
2062 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2064 emit_store(jd, iptr, iptr->dst, d);
2067 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2069 emit_store(jd, iptr, iptr->dst, d);
2072 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2074 emit_store(jd, iptr, iptr->dst, d);
2077 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2079 emit_store(jd, iptr, iptr->dst, d);
2084 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2085 /* op1 = type, val.a = field address */
2087 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2088 gen_nullptr_check(s1);
2090 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2091 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2093 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2096 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2097 codegen_addpatchref(cd, PATCHER_get_putfield,
2098 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2100 if (opt_showdisassemble) {
2107 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2110 switch (iptr->op1) {
2129 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2130 /* val = value (in current instruction) */
2131 /* op1 = type, val.a = field address (in */
2132 /* following NOP) */
2134 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2135 gen_nullptr_check(s1);
2137 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2138 codegen_addpatchref(cd, PATCHER_get_putfield,
2139 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2141 if (opt_showdisassemble) {
2148 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2151 switch (iptr[1].op1) {
2153 M_IST(REG_ZERO, s1, a);
2156 M_LST(REG_ZERO, s1, a);
2159 M_AST(REG_ZERO, s1, a);
2162 M_FST(REG_ZERO, s1, a);
2165 M_DST(REG_ZERO, s1, a);
2171 /* branch operations **************************************************/
2173 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2175 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2176 M_INTMOVE(s1, REG_ITMP1_XPTR);
2178 #ifdef ENABLE_VERIFIER
2180 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2181 (unresolved_class *) iptr->val.a, 0);
2183 if (opt_showdisassemble) {
2187 #endif /* ENABLE_VERIFIER */
2189 disp = dseg_addaddress(cd, asm_handle_exception);
2190 M_ALD(REG_ITMP2, REG_PV, disp);
2191 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2193 M_NOP; /* nop ensures that XPC is less than the end */
2194 /* of basic block */
2198 case ICMD_GOTO: /* ... ==> ... */
2199 /* op1 = target JavaVM pc */
2201 codegen_addreference(cd, (basicblock *) iptr->target);
2206 case ICMD_JSR: /* ... ==> ... */
2207 /* op1 = target JavaVM pc */
2209 dseg_addtarget(cd, (basicblock *) iptr->target);
2210 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2211 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2215 case ICMD_RET: /* ... ==> ... */
2216 /* op1 = local variable */
2217 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2218 if (var->flags & INMEMORY) {
2219 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2227 case ICMD_IFNULL: /* ..., value ==> ... */
2228 /* op1 = target JavaVM pc */
2230 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2232 codegen_addreference(cd, (basicblock *) iptr->target);
2236 case ICMD_IFNONNULL: /* ..., value ==> ... */
2237 /* op1 = target JavaVM pc */
2239 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2241 codegen_addreference(cd, (basicblock *) iptr->target);
2245 case ICMD_IFEQ: /* ..., value ==> ... */
2246 /* op1 = target JavaVM pc, val.i = constant */
2248 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2249 if (iptr->val.i == 0) {
2252 ICONST(REG_ITMP2, iptr->val.i);
2253 M_BEQ(s1, REG_ITMP2, 0);
2255 codegen_addreference(cd, (basicblock *) iptr->target);
2259 case ICMD_IFLT: /* ..., value ==> ... */
2260 /* op1 = target JavaVM pc, val.i = constant */
2262 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2263 if (iptr->val.i == 0) {
2266 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2267 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2269 ICONST(REG_ITMP2, iptr->val.i);
2270 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2272 M_BNEZ(REG_ITMP1, 0);
2274 codegen_addreference(cd, (basicblock *) iptr->target);
2278 case ICMD_IFLE: /* ..., value ==> ... */
2279 /* op1 = target JavaVM pc, val.i = constant */
2281 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2282 if (iptr->val.i == 0) {
2286 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2287 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2288 M_BNEZ(REG_ITMP1, 0);
2291 ICONST(REG_ITMP2, iptr->val.i);
2292 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2293 M_BEQZ(REG_ITMP1, 0);
2296 codegen_addreference(cd, (basicblock *) iptr->target);
2300 case ICMD_IFNE: /* ..., value ==> ... */
2301 /* op1 = target JavaVM pc, val.i = constant */
2303 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2304 if (iptr->val.i == 0) {
2308 ICONST(REG_ITMP2, iptr->val.i);
2309 M_BNE(s1, REG_ITMP2, 0);
2311 codegen_addreference(cd, (basicblock *) iptr->target);
2315 case ICMD_IFGT: /* ..., value ==> ... */
2316 /* op1 = target JavaVM pc, val.i = constant */
2318 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2319 if (iptr->val.i == 0) {
2323 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2324 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2325 M_BEQZ(REG_ITMP1, 0);
2328 ICONST(REG_ITMP2, iptr->val.i);
2329 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2330 M_BNEZ(REG_ITMP1, 0);
2333 codegen_addreference(cd, (basicblock *) iptr->target);
2337 case ICMD_IFGE: /* ..., value ==> ... */
2338 /* op1 = target JavaVM pc, val.i = constant */
2340 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2341 if (iptr->val.i == 0) {
2345 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2346 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2349 ICONST(REG_ITMP2, iptr->val.i);
2350 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2352 M_BEQZ(REG_ITMP1, 0);
2354 codegen_addreference(cd, (basicblock *) iptr->target);
2358 case ICMD_IF_LEQ: /* ..., value ==> ... */
2359 /* op1 = target JavaVM pc, val.l = constant */
2361 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2362 if (iptr->val.l == 0) {
2366 LCONST(REG_ITMP2, iptr->val.l);
2367 M_BEQ(s1, REG_ITMP2, 0);
2369 codegen_addreference(cd, (basicblock *) iptr->target);
2373 case ICMD_IF_LLT: /* ..., value ==> ... */
2374 /* op1 = target JavaVM pc, val.l = constant */
2376 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2377 if (iptr->val.l == 0) {
2381 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2382 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2385 LCONST(REG_ITMP2, iptr->val.l);
2386 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2388 M_BNEZ(REG_ITMP1, 0);
2390 codegen_addreference(cd, (basicblock *) iptr->target);
2394 case ICMD_IF_LLE: /* ..., value ==> ... */
2395 /* op1 = target JavaVM pc, val.l = constant */
2397 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2398 if (iptr->val.l == 0) {
2402 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2403 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2404 M_BNEZ(REG_ITMP1, 0);
2407 LCONST(REG_ITMP2, iptr->val.l);
2408 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2409 M_BEQZ(REG_ITMP1, 0);
2412 codegen_addreference(cd, (basicblock *) iptr->target);
2416 case ICMD_IF_LNE: /* ..., value ==> ... */
2417 /* op1 = target JavaVM pc, val.l = constant */
2419 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2420 if (iptr->val.l == 0) {
2424 LCONST(REG_ITMP2, iptr->val.l);
2425 M_BNE(s1, REG_ITMP2, 0);
2427 codegen_addreference(cd, (basicblock *) iptr->target);
2431 case ICMD_IF_LGT: /* ..., value ==> ... */
2432 /* op1 = target JavaVM pc, val.l = constant */
2434 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2435 if (iptr->val.l == 0) {
2439 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2440 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2441 M_BEQZ(REG_ITMP1, 0);
2444 LCONST(REG_ITMP2, iptr->val.l);
2445 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2446 M_BNEZ(REG_ITMP1, 0);
2449 codegen_addreference(cd, (basicblock *) iptr->target);
2453 case ICMD_IF_LGE: /* ..., value ==> ... */
2454 /* op1 = target JavaVM pc, val.l = constant */
2456 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2457 if (iptr->val.l == 0) {
2461 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2462 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2465 LCONST(REG_ITMP2, iptr->val.l);
2466 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2468 M_BEQZ(REG_ITMP1, 0);
2470 codegen_addreference(cd, (basicblock *) iptr->target);
2474 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2475 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2476 case ICMD_IF_ACMPEQ:
2478 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2479 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2481 codegen_addreference(cd, (basicblock *) iptr->target);
2485 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2486 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2487 case ICMD_IF_ACMPNE:
2489 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2490 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2492 codegen_addreference(cd, (basicblock *) iptr->target);
2496 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2497 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2499 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2500 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2501 M_CMPLT(s1, s2, REG_ITMP1);
2502 M_BNEZ(REG_ITMP1, 0);
2503 codegen_addreference(cd, (basicblock *) iptr->target);
2507 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2508 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2510 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2511 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2512 M_CMPGT(s1, s2, REG_ITMP1);
2513 M_BNEZ(REG_ITMP1, 0);
2514 codegen_addreference(cd, (basicblock *) iptr->target);
2518 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2519 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2521 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2522 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2523 M_CMPGT(s1, s2, REG_ITMP1);
2524 M_BEQZ(REG_ITMP1, 0);
2525 codegen_addreference(cd, (basicblock *) iptr->target);
2529 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2530 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2532 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2533 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2534 M_CMPLT(s1, s2, REG_ITMP1);
2535 M_BEQZ(REG_ITMP1, 0);
2536 codegen_addreference(cd, (basicblock *) iptr->target);
2541 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2544 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2545 M_INTMOVE(s1, REG_RESULT);
2546 goto nowperformreturn;
2548 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2550 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2551 M_INTMOVE(s1, REG_RESULT);
2553 #ifdef ENABLE_VERIFIER
2555 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2556 (unresolved_class *) iptr->val.a, 0);
2558 if (opt_showdisassemble) {
2562 #endif /* ENABLE_VERIFIER */
2563 goto nowperformreturn;
2565 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2567 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2568 M_FLTMOVE(s1, REG_FRESULT);
2569 goto nowperformreturn;
2571 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2573 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2574 M_DBLMOVE(s1, REG_FRESULT);
2575 goto nowperformreturn;
2577 case ICMD_RETURN: /* ... ==> ... */
2583 p = cd->stackframesize;
2585 #if !defined(NDEBUG)
2586 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2587 emit_verbosecall_exit(jd);
2590 #if defined(ENABLE_THREADS)
2591 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2592 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2593 M_ALD(REG_ITMP3, REG_PV, disp);
2595 /* we need to save the proper return value */
2597 switch (iptr->opc) {
2601 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2602 M_JSR(REG_RA, REG_ITMP3);
2603 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2607 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2608 M_JSR(REG_RA, REG_ITMP3);
2609 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2612 M_JSR(REG_RA, REG_ITMP3);
2613 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2617 /* and now restore the proper return value */
2619 switch (iptr->opc) {
2623 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2627 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2633 /* restore return address */
2635 if (!jd->isleafmethod) {
2636 p--; M_ALD(REG_RA, REG_SP, p * 8);
2639 /* restore saved registers */
2641 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2642 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2644 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2645 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2648 /* deallocate stack and return */
2650 if (cd->stackframesize) {
2653 disp = cd->stackframesize * 8;
2654 lo = (short) (disp);
2655 hi = (short) (((disp) - lo) >> 16);
2659 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2661 M_LUI(REG_ITMP3,hi);
2662 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2664 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2677 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2682 tptr = (void **) iptr->target;
2684 s4ptr = iptr->val.a;
2685 l = s4ptr[1]; /* low */
2686 i = s4ptr[2]; /* high */
2688 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2690 {M_INTMOVE(s1, REG_ITMP1);}
2691 else if (l <= 32768) {
2692 M_IADD_IMM(s1, -l, REG_ITMP1);
2695 ICONST(REG_ITMP2, l);
2696 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2702 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2703 M_BEQZ(REG_ITMP2, 0);
2704 codegen_addreference(cd, (basicblock *) tptr[0]);
2705 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2707 /* build jump table top down and use address of lowest entry */
2709 /* s4ptr += 3 + i; */
2713 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2714 dseg_addtarget(cd, (basicblock *) tptr[0]);
2719 /* length of dataseg after last dseg_addtarget is used by load */
2721 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2722 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2729 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2731 s4 i, /*l, */val, *s4ptr;
2734 tptr = (void **) iptr->target;
2736 s4ptr = iptr->val.a;
2737 /*l = s4ptr[0];*/ /* default */
2738 i = s4ptr[1]; /* count */
2740 MCODECHECK((i<<2)+8);
2741 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2747 ICONST(REG_ITMP2, val);
2748 M_BEQ(s1, REG_ITMP2, 0);
2749 codegen_addreference(cd, (basicblock *) tptr[0]);
2754 tptr = (void **) iptr->target;
2755 codegen_addreference(cd, (basicblock *) tptr[0]);
2762 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2763 /* op1 = arg count val.a = builtintable entry */
2769 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2770 /* op1 = arg count, val.a = method pointer */
2772 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2773 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2774 case ICMD_INVOKEINTERFACE:
2776 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2777 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
2781 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
2782 md = lm->parseddesc;
2786 s3 = md->paramcount;
2788 MCODECHECK((s3 << 1) + 64);
2790 /* copy arguments to registers or stack location */
2792 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2793 if (src->varkind == ARGVAR)
2795 if (IS_INT_LNG_TYPE(src->type)) {
2796 if (!md->params[s3].inmemory) {
2797 s1 = rd->argintregs[md->params[s3].regoff];
2798 d = emit_load_s1(jd, iptr, src, s1);
2801 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
2802 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2806 if (!md->params[s3].inmemory) {
2807 s1 = rd->argfltregs[md->params[s3].regoff];
2808 d = emit_load_s1(jd, iptr, src, s1);
2809 if (IS_2_WORD_TYPE(src->type))
2815 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
2816 if (IS_2_WORD_TYPE(src->type))
2817 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2819 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2824 switch (iptr->opc) {
2826 disp = dseg_addaddress(cd, bte->fp);
2827 d = md->returntype.type;
2829 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2830 M_JSR(REG_RA, REG_ITMP3);
2832 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2833 M_LDA(REG_PV, REG_RA, -disp);
2835 /* if op1 == true, we need to check for an exception */
2837 if (iptr->op1 == true) {
2838 M_BEQZ(REG_RESULT, 0);
2839 codegen_add_fillinstacktrace_ref(cd);
2844 case ICMD_INVOKESPECIAL:
2845 M_BEQZ(rd->argintregs[0], 0);
2846 codegen_add_nullpointerexception_ref(cd);
2850 case ICMD_INVOKESTATIC:
2852 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2854 disp = dseg_addaddress(cd, NULL);
2856 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2859 if (opt_showdisassemble) {
2863 d = um->methodref->parseddesc.md->returntype.type;
2866 disp = dseg_addaddress(cd, lm->stubroutine);
2867 d = lm->parseddesc->returntype.type;
2870 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2871 M_JSR(REG_RA, REG_PV);
2873 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2874 M_LDA(REG_PV, REG_RA, -disp);
2877 case ICMD_INVOKEVIRTUAL:
2878 gen_nullptr_check(rd->argintregs[0]);
2881 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2883 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2885 if (opt_showdisassemble) {
2890 d = um->methodref->parseddesc.md->returntype.type;
2893 s1 = OFFSET(vftbl_t, table[0]) +
2894 sizeof(methodptr) * lm->vftblindex;
2895 d = lm->parseddesc->returntype.type;
2898 M_ALD(REG_METHODPTR, rd->argintregs[0],
2899 OFFSET(java_objectheader, vftbl));
2900 M_ALD(REG_PV, REG_METHODPTR, s1);
2901 M_JSR(REG_RA, REG_PV);
2903 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2904 M_LDA(REG_PV, REG_RA, -disp);
2907 case ICMD_INVOKEINTERFACE:
2908 gen_nullptr_check(rd->argintregs[0]);
2911 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2913 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2915 if (opt_showdisassemble) {
2921 d = um->methodref->parseddesc.md->returntype.type;
2924 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2925 sizeof(methodptr*) * lm->class->index;
2927 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2929 d = lm->parseddesc->returntype.type;
2932 M_ALD(REG_METHODPTR, rd->argintregs[0],
2933 OFFSET(java_objectheader, vftbl));
2934 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2935 M_ALD(REG_PV, REG_METHODPTR, s2);
2936 M_JSR(REG_RA, REG_PV);
2938 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2939 M_LDA(REG_PV, REG_RA, -disp);
2943 /* d contains return type */
2945 if (d != TYPE_VOID) {
2946 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2947 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
2948 M_INTMOVE(REG_RESULT, s1);
2950 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
2951 if (IS_2_WORD_TYPE(iptr->dst->type))
2952 M_DMOV(REG_FRESULT, s1);
2954 M_FMOV(REG_FRESULT, s1);
2956 emit_store(jd, iptr, iptr->dst, s1);
2961 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2962 /* op1: 0 == array, 1 == class */
2963 /* val.a: (classinfo*) superclass */
2965 /* superclass is an interface:
2967 * OK if ((sub == NULL) ||
2968 * (sub->vftbl->interfacetablelength > super->index) &&
2969 * (sub->vftbl->interfacetable[-super->index] != NULL));
2971 * superclass is a class:
2973 * OK if ((sub == NULL) || (0
2974 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2975 * super->vftbl->diffvall));
2978 if (iptr->op1 == 1) {
2980 vftbl_t *supervftbl;
2983 super = (classinfo *) iptr->val.a;
2985 if (super == NULL) {
2990 superindex = super->index;
2991 supervftbl = super->vftbl;
2994 #if defined(ENABLE_THREADS)
2995 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2998 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3000 /* calculate interface checkcast code size */
3004 s2 += (opt_showdisassemble ? 2 : 0);
3006 /* calculate class checkcast code size */
3008 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3010 s3 += (opt_showdisassemble ? 2 : 0);
3012 /* if class is not resolved, check which code to call */
3014 if (super == NULL) {
3015 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3018 disp = dseg_adds4(cd, 0); /* super->flags */
3020 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3021 (constant_classref *) iptr->target,
3024 if (opt_showdisassemble) {
3028 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3029 M_ILD(REG_ITMP2, REG_PV, disp);
3030 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3031 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3035 /* interface checkcast code */
3037 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3038 if (super != NULL) {
3043 codegen_addpatchref(cd,
3044 PATCHER_checkcast_instanceof_interface,
3045 (constant_classref *) iptr->target,
3048 if (opt_showdisassemble) {
3053 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3054 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3055 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3056 M_BLEZ(REG_ITMP3, 0);
3057 codegen_add_classcastexception_ref(cd, s1);
3059 M_ALD(REG_ITMP3, REG_ITMP2,
3060 OFFSET(vftbl_t, interfacetable[0]) -
3061 superindex * sizeof(methodptr*));
3062 M_BEQZ(REG_ITMP3, 0);
3063 codegen_add_classcastexception_ref(cd, s1);
3066 if (super == NULL) {
3072 /* class checkcast code */
3074 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3075 disp = dseg_addaddress(cd, (void *) supervftbl);
3077 if (super != NULL) {
3082 codegen_addpatchref(cd,
3083 PATCHER_checkcast_instanceof_class,
3084 (constant_classref *) iptr->target,
3087 if (opt_showdisassemble) {
3092 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3093 M_ALD(REG_ITMP3, REG_PV, disp);
3094 #if defined(ENABLE_THREADS)
3095 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3097 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3098 /* if (s1 != REG_ITMP1) { */
3099 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3100 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3101 /* #if defined(ENABLE_THREADS) */
3102 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3104 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3106 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3107 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3108 M_ALD(REG_ITMP3, REG_PV, disp);
3109 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3110 #if defined(ENABLE_THREADS)
3111 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3114 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3115 M_BNEZ(REG_ITMP3, 0);
3116 codegen_add_classcastexception_ref(cd, s1);
3120 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3123 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3124 M_INTMOVE(s1, rd->argintregs[0]);
3126 disp = dseg_addaddress(cd, iptr->val.a);
3128 if (iptr->val.a == NULL) {
3129 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3130 (constant_classref *) iptr->target,
3133 if (opt_showdisassemble) {
3138 M_ALD(rd->argintregs[1], REG_PV, disp);
3139 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3140 M_ALD(REG_ITMP3, REG_PV, disp);
3141 M_JSR(REG_RA, REG_ITMP3);
3144 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3145 M_BEQZ(REG_RESULT, 0);
3146 codegen_add_classcastexception_ref(cd, s1);
3149 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3153 emit_store(jd, iptr, iptr->dst, d);
3156 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3157 /* op1: 0 == array, 1 == class */
3158 /* val.a: (classinfo*) superclass */
3160 /* superclass is an interface:
3162 * return (sub != NULL) &&
3163 * (sub->vftbl->interfacetablelength > super->index) &&
3164 * (sub->vftbl->interfacetable[-super->index] != NULL);
3166 * superclass is a class:
3168 * return ((sub != NULL) && (0
3169 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3170 * super->vftbl->diffvall));
3175 vftbl_t *supervftbl;
3178 super = (classinfo *) iptr->val.a;
3180 if (super == NULL) {
3185 superindex = super->index;
3186 supervftbl = super->vftbl;
3189 #if defined(ENABLE_THREADS)
3190 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3193 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3194 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3196 M_MOV(s1, REG_ITMP1);
3200 /* calculate interface instanceof code size */
3204 s2 += (opt_showdisassemble ? 2 : 0);
3206 /* calculate class instanceof code size */
3210 s3 += (opt_showdisassemble ? 2 : 0);
3214 /* if class is not resolved, check which code to call */
3216 if (super == NULL) {
3217 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3220 disp = dseg_adds4(cd, 0); /* super->flags */
3222 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3223 (constant_classref *) iptr->target, disp);
3225 if (opt_showdisassemble) {
3229 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3230 M_ILD(REG_ITMP3, REG_PV, disp);
3231 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3232 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3236 /* interface instanceof code */
3238 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3239 if (super != NULL) {
3244 codegen_addpatchref(cd,
3245 PATCHER_checkcast_instanceof_interface,
3246 (constant_classref *) iptr->target, 0);
3248 if (opt_showdisassemble) {
3253 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3254 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3255 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3256 M_BLEZ(REG_ITMP3, 3);
3258 M_ALD(REG_ITMP1, REG_ITMP1,
3259 OFFSET(vftbl_t, interfacetable[0]) -
3260 superindex * sizeof(methodptr*));
3261 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3263 if (super == NULL) {
3269 /* class instanceof code */
3271 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3272 disp = dseg_addaddress(cd, supervftbl);
3274 if (super != NULL) {
3279 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3280 (constant_classref *) iptr->target,
3283 if (opt_showdisassemble) {
3288 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3289 M_ALD(REG_ITMP2, REG_PV, disp);
3290 #if defined(ENABLE_THREADS)
3291 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3293 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3294 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3295 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3296 #if defined(ENABLE_THREADS)
3297 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3299 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3300 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3303 emit_store(jd, iptr, iptr->dst, d);
3307 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3308 /* op1 = dimension, val.a = class */
3310 /* check for negative sizes and copy sizes to stack if necessary */
3312 MCODECHECK((iptr->op1 << 1) + 64);
3314 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3315 /* copy SAVEDVAR sizes to stack */
3317 if (src->varkind != ARGVAR) {
3318 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3319 M_LST(s2, REG_SP, s1 * 8);
3323 /* a0 = dimension count */
3325 ICONST(rd->argintregs[0], iptr->op1);
3327 /* is patcher function set? */
3329 if (iptr->val.a == NULL) {
3330 disp = dseg_addaddress(cd, NULL);
3332 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3333 (constant_classref *) iptr->target, disp);
3335 if (opt_showdisassemble) {
3340 disp = dseg_addaddress(cd, iptr->val.a);
3343 /* a1 = arraydescriptor */
3345 M_ALD(rd->argintregs[1], REG_PV, disp);
3347 /* a2 = pointer to dimensions = stack pointer */
3349 M_INTMOVE(REG_SP, rd->argintregs[2]);
3351 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3352 M_ALD(REG_ITMP3, REG_PV, disp);
3353 M_JSR(REG_RA, REG_ITMP3);
3356 /* check for exception before result assignment */
3358 M_BEQZ(REG_RESULT, 0);
3359 codegen_add_fillinstacktrace_ref(cd);
3362 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3363 M_INTMOVE(REG_RESULT, d);
3364 emit_store(jd, iptr, iptr->dst, d);
3368 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3372 } /* for instruction */
3374 /* copy values to interface registers */
3376 src = bptr->outstack;
3377 len = bptr->outdepth;
3379 #if defined(ENABLE_LSRA)
3384 if ((src->varkind != STACKVAR)) {
3386 if (IS_FLT_DBL_TYPE(s2)) {
3387 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3388 if (rd->interfaces[len][s2].flags & INMEMORY) {
3389 if (IS_2_WORD_TYPE(s2))
3390 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3392 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3395 if (IS_2_WORD_TYPE(s2))
3396 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3398 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3402 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3403 if (rd->interfaces[len][s2].flags & INMEMORY)
3404 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3406 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3412 /* At the end of a basic block we may have to append some nops,
3413 because the patcher stub calling code might be longer than the
3414 actual instruction. So codepatching does not change the
3415 following block unintentionally. */
3417 if (cd->mcodeptr < cd->lastmcodeptr) {
3418 while (cd->mcodeptr < cd->lastmcodeptr)
3422 } /* if (bptr -> flags >= BBREACHED) */
3423 } /* for basic block */
3425 dseg_createlinenumbertable(cd);
3427 /* generate exception and patcher stubs */
3429 emit_exception_stubs(jd);
3430 emit_patcher_stubs(jd);
3431 emit_replacement_stubs(jd);
3435 /* everything's ok */
3441 /* createcompilerstub **********************************************************
3443 Creates a stub routine which calls the compiler.
3445 *******************************************************************************/
3447 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3448 #define COMPILERSTUB_CODESIZE 4 * 4
3450 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3453 u1 *createcompilerstub(methodinfo *m)
3455 u1 *s; /* memory to hold the stub */
3461 s = CNEW(u1, COMPILERSTUB_SIZE);
3463 /* set data pointer and code pointer */
3466 s = s + COMPILERSTUB_DATASIZE;
3468 /* mark start of dump memory area */
3470 dumpsize = dump_size();
3472 cd = DNEW(codegendata);
3475 /* Store the codeinfo pointer in the same place as in the
3476 methodheader for compiled methods. */
3478 code = code_codeinfo_new(m);
3480 d[0] = (ptrint) asm_call_jit_compiler;
3482 d[2] = (ptrint) code;
3484 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3485 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3489 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3491 #if defined(ENABLE_STATISTICS)
3493 count_cstub_len += COMPILERSTUB_SIZE;
3496 /* release dump area */
3498 dump_release(dumpsize);
3504 /* createnativestub ************************************************************
3506 Creates a stub routine which calls a native method.
3508 *******************************************************************************/
3510 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3518 s4 i, j; /* count variables */
3521 s4 funcdisp; /* displacement of the function */
3523 /* get required compiler data */
3530 /* initialize variables */
3533 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3535 /* calculate stack frame size */
3537 cd->stackframesize =
3538 1 + /* return address */
3539 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3540 sizeof(localref_table) / SIZEOF_VOID_P +
3541 md->paramcount + /* for saving arguments over calls */
3542 1 + /* for saving return address */
3545 /* create method header */
3547 #if SIZEOF_VOID_P == 4
3548 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3550 (void) dseg_addaddress(cd, code); /* MethodPointer */
3551 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3552 (void) dseg_adds4(cd, 0); /* IsSync */
3553 (void) dseg_adds4(cd, 0); /* IsLeaf */
3554 (void) dseg_adds4(cd, 0); /* IntSave */
3555 (void) dseg_adds4(cd, 0); /* FltSave */
3556 (void) dseg_addlinenumbertablesize(cd);
3557 (void) dseg_adds4(cd, 0); /* ExTableSize */
3559 /* generate stub code */
3561 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3562 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* store RA*/
3564 #if !defined(NDEBUG)
3565 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3566 emit_verbosecall_enter(jd);
3569 /* get function address (this must happen before the stackframeinfo) */
3571 funcdisp = dseg_addaddress(cd, f);
3573 #if !defined(WITH_STATIC_CLASSPATH)
3575 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3577 if (opt_showdisassemble) {
3583 /* save integer and float argument registers */
3585 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3586 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3587 M_LST(rd->argintregs[i], REG_SP, j * 8);
3592 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3593 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3594 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3599 /* prepare data structures for native function call */
3601 M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
3602 M_MOV(REG_PV, rd->argintregs[1]);
3603 M_AADD_IMM(REG_SP, cd->stackframesize * 8, rd->argintregs[2]);
3604 M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3605 disp = dseg_addaddress(cd, codegen_start_native_call);
3606 M_ALD(REG_ITMP3, REG_PV, disp);
3607 M_JSR(REG_RA, REG_ITMP3);
3608 M_NOP; /* XXX fill me! */
3610 /* restore integer and float argument registers */
3612 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3613 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3614 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3619 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3620 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3621 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3626 /* copy or spill arguments to new locations */
3628 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3629 t = md->paramtypes[i].type;
3631 if (IS_INT_LNG_TYPE(t)) {
3632 if (!md->params[i].inmemory) {
3633 s1 = rd->argintregs[md->params[i].regoff];
3635 if (!nmd->params[j].inmemory) {
3636 s2 = rd->argintregs[nmd->params[j].regoff];
3639 s2 = nmd->params[j].regoff;
3640 M_AST(s1, REG_SP, s2 * 8);
3644 s1 = md->params[i].regoff + cd->stackframesize;
3645 s2 = nmd->params[j].regoff;
3646 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3647 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3651 if (!md->params[i].inmemory) {
3652 s1 = rd->argfltregs[md->params[i].regoff];
3654 if (!nmd->params[j].inmemory) {
3655 s2 = rd->argfltregs[nmd->params[j].regoff];
3656 if (IS_2_WORD_TYPE(t))
3662 s2 = nmd->params[j].regoff;
3663 if (IS_2_WORD_TYPE(t))
3664 M_DST(s1, REG_SP, s2 * 8);
3666 M_FST(s1, REG_SP, s2 * 8);
3670 s1 = md->params[i].regoff + cd->stackframesize;
3671 s2 = nmd->params[j].regoff;
3672 if (IS_2_WORD_TYPE(t)) {
3673 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3674 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3676 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3677 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3683 /* put class into second argument register */
3685 if (m->flags & ACC_STATIC) {
3686 disp = dseg_addaddress(cd, m->class);
3687 M_ALD(rd->argintregs[1], REG_PV, disp);
3690 /* put env into first argument register */
3692 disp = dseg_addaddress(cd, _Jv_env);
3693 M_ALD(rd->argintregs[0], REG_PV, disp);
3695 /* do the native function call */
3697 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3698 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3699 M_NOP; /* delay slot */
3701 /* save return value */
3703 if (md->returntype.type != TYPE_VOID) {
3704 if (IS_INT_LNG_TYPE(md->returntype.type))
3705 M_LST(REG_RESULT, REG_SP, 0 * 8);
3707 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3710 #if !defined(NDEBUG)
3711 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3712 emit_verbosecall_exit(jd);
3715 /* remove native stackframe info */
3717 M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
3718 disp = dseg_addaddress(cd, codegen_finish_native_call);
3719 M_ALD(REG_ITMP3, REG_PV, disp);
3720 M_JSR(REG_RA, REG_ITMP3);
3721 M_NOP; /* XXX fill me! */
3722 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3724 /* restore return value */
3726 if (md->returntype.type != TYPE_VOID) {
3727 if (IS_INT_LNG_TYPE(md->returntype.type))
3728 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3730 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3733 M_ALD(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* load RA */
3735 /* check for exception */
3737 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3738 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3740 M_RET(REG_RA); /* return to caller */
3741 M_NOP; /* DELAY SLOT */
3743 /* handle exception */
3745 disp = dseg_addaddress(cd, asm_handle_nat_exception);
3746 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3747 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3748 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3750 /* generate patcher stubs */
3752 emit_patcher_stubs(jd);
3756 return code->entrypoint;
3761 * These are local overrides for various environment variables in Emacs.
3762 * Please do not remove this and leave it at the end of the file, where
3763 * Emacs will automagically detect them.
3764 * ---------------------------------------------------------------------
3767 * indent-tabs-mode: t
3771 * vim:noexpandtab:sw=4:ts=4: